Refactor to typescript
This commit is contained in:
		
							parent
							
								
									5f589f89d8
								
							
						
					
					
						commit
						09e8b1f6d7
					
				
							
								
								
									
										2
									
								
								.npmrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.npmrc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | @moduletrace:registry=https://git.tben.me/api/packages/moduletrace/npm/ | ||||||
|  | //git.tben.me/api/packages/moduletrace/npm/:_authToken=${GITBEN_NPM_TOKEN} | ||||||
							
								
								
									
										
											BIN
										
									
								
								bin/nodecid
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								bin/nodecid
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										263
									
								
								deploy/start.js
									
									
									
									
									
								
							
							
						
						
									
										263
									
								
								deploy/start.js
									
									
									
									
									
								
							| @ -1,263 +0,0 @@ | |||||||
| // @ts-check
 |  | ||||||
| 
 |  | ||||||
| const path = require("path"); |  | ||||||
| const fs = require("fs"); |  | ||||||
| const { |  | ||||||
|     execSync, |  | ||||||
|     spawnSync, |  | ||||||
|     spawn, |  | ||||||
|     execFile, |  | ||||||
|     execFileSync, |  | ||||||
|     ChildProcess, |  | ||||||
| } = require("child_process"); |  | ||||||
| const colors = require("../utils/console-colors"); |  | ||||||
| const kill = require("kill-port"); |  | ||||||
| 
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| let redeployments = 0; |  | ||||||
| 
 |  | ||||||
| /** @type {NodeJS.Signals | number} */ |  | ||||||
| const KILL_SIGNAL = "SIGTERM"; |  | ||||||
| // const KILL_SIGNAL = "SIGINT";
 |  | ||||||
| 
 |  | ||||||
| /** @type {ChildProcess | null} */ |  | ||||||
| let childProcess = null; |  | ||||||
| 
 |  | ||||||
| const pTitle = "nodecid"; |  | ||||||
| process.title = pTitle; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * # Start the process |  | ||||||
|  * @param {object} param0 |  | ||||||
|  * @param {string} param0.command |  | ||||||
|  * @param {string[] | string} param0.preflight |  | ||||||
|  * @param {string[] | string} [param0.postflight] |  | ||||||
|  * @param {string} param0.redeploy_file |  | ||||||
|  * @param {string | number | (string | number)[]} [param0.port] - The port to kill on rebuild |  | ||||||
|  * @param {boolean} [param0.first_run] - Whether to run the preflight on first run. Default `false` |  | ||||||
|  */ |  | ||||||
| function startProcess({ |  | ||||||
|     command, |  | ||||||
|     preflight, |  | ||||||
|     postflight, |  | ||||||
|     redeploy_file, |  | ||||||
|     port, |  | ||||||
|     first_run, |  | ||||||
| }) { |  | ||||||
|     try { |  | ||||||
|         if (first_run) { |  | ||||||
|             console.log("First Run ..."); |  | ||||||
|             const runPreflight = preflightFn(preflight); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!preflight) { |  | ||||||
|             console.log( |  | ||||||
|                 `${colors.FgRed}Error:${colors.Reset} No preflight included in config file. If you don't want to run any preflight command simply add an empty array.` |  | ||||||
|             ); |  | ||||||
|             process.exit(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         childProcess = run(command); |  | ||||||
| 
 |  | ||||||
|         if (!childProcess) { |  | ||||||
|             console.log( |  | ||||||
|                 `${colors.FgRed}Error:${colors.Reset} Process couldn't start. Exiting...` |  | ||||||
|             ); |  | ||||||
|             process.exit(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         console.log("Watching", redeploy_file); |  | ||||||
| 
 |  | ||||||
|         fs.watchFile(redeploy_file, { interval: 100 }, (curr, prev) => { |  | ||||||
|             console.log(`${colors.BgBlue}File Changed${colors.Reset}`); |  | ||||||
| 
 |  | ||||||
|             if (redeployments == 0) return; |  | ||||||
| 
 |  | ||||||
|             if (childProcess) { |  | ||||||
|                 console.log("******************************"); |  | ||||||
|                 console.log( |  | ||||||
|                     `******** ${colors.FgBlue}Rebuilding ${colors.FgMagenta}${redeployments}${colors.Reset} ********` |  | ||||||
|                 ); |  | ||||||
|                 console.log("******************************"); |  | ||||||
| 
 |  | ||||||
|                 try { |  | ||||||
|                     const runPreflight = preflightFn(preflight); |  | ||||||
| 
 |  | ||||||
|                     if (!runPreflight) { |  | ||||||
|                         // TODO: Action to take if preflight fails
 |  | ||||||
| 
 |  | ||||||
|                         console.log( |  | ||||||
|                             `${colors.FgRed}Error:${colors.Reset} Preflight Failed.` |  | ||||||
|                         ); |  | ||||||
|                     } else { |  | ||||||
|                         killChild(port).then((kill) => { |  | ||||||
|                             if (kill) { |  | ||||||
|                                 childProcess = run(command); |  | ||||||
| 
 |  | ||||||
|                                 if (postflight) { |  | ||||||
|                                     const runPostflight = preflightFn( |  | ||||||
|                                         postflight, |  | ||||||
|                                         true |  | ||||||
|                                     ); |  | ||||||
| 
 |  | ||||||
|                                     if (!runPostflight) { |  | ||||||
|                                         // TODO: Action to take if postflight fails
 |  | ||||||
| 
 |  | ||||||
|                                         console.log( |  | ||||||
|                                             `${colors.FgRed}Error:${colors.Reset} Postflight Failed.` |  | ||||||
|                                         ); |  | ||||||
|                                     } |  | ||||||
|                                 } |  | ||||||
|                             } else { |  | ||||||
|                                 process.exit(); |  | ||||||
|                             } |  | ||||||
|                         }); |  | ||||||
|                     } |  | ||||||
|                 } catch (/** @type {*} */ error) { |  | ||||||
|                     console.log( |  | ||||||
|                         `${colors.FgRed}Error:${colors.Reset} killing child processes => ${error.message}` |  | ||||||
|                     ); |  | ||||||
|                     process.exit(); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     } catch (/** @type {*} */ error) { |  | ||||||
|         console.log( |  | ||||||
|             `${colors.FgRed}Error:${colors.Reset} First run failed! => ${error.message}` |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * ## Preflight Function |  | ||||||
|  * @param {string} command |  | ||||||
|  * @returns {ChildProcess | null} |  | ||||||
|  */ |  | ||||||
| function run(command) { |  | ||||||
|     console.log("\n******************************"); |  | ||||||
|     console.log( |  | ||||||
|         `****** ${colors.FgGreen}Starting App ...${colors.Reset} ******` |  | ||||||
|     ); |  | ||||||
|     console.log("******************************\n"); |  | ||||||
| 
 |  | ||||||
|     const startCommandArray = command.split(" ").filter((str) => str.trim()); |  | ||||||
| 
 |  | ||||||
|     try { |  | ||||||
|         const firstCommand = startCommandArray.shift(); |  | ||||||
| 
 |  | ||||||
|         if (!firstCommand) { |  | ||||||
|             throw new Error("No Starting Command Found in command string!"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let childProcess = spawn(firstCommand, startCommandArray, { |  | ||||||
|             stdio: "inherit", |  | ||||||
|             killSignal: KILL_SIGNAL, |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         // let childProcess = execSync(command, {
 |  | ||||||
|         //     stdio: "inherit",
 |  | ||||||
|         // });
 |  | ||||||
| 
 |  | ||||||
|         redeployments++; |  | ||||||
| 
 |  | ||||||
|         return childProcess; |  | ||||||
|     } catch (/** @type {*} */ error) { |  | ||||||
|         console.log( |  | ||||||
|             `${colors.FgRed}Error:${colors.Reset} running start command => ${error.message}` |  | ||||||
|         ); |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * ## Preflight Function |  | ||||||
|  * @param {string[] | string} preflight |  | ||||||
|  * @param {boolean} [postflight] |  | ||||||
|  * @returns {boolean} |  | ||||||
|  */ |  | ||||||
| function preflightFn(preflight, postflight) { |  | ||||||
|     const tag = postflight ? "Postflight" : "Preflight"; |  | ||||||
|     console.log(`${tag} Running ...`); |  | ||||||
| 
 |  | ||||||
|     /** @type {import("child_process").ExecSyncOptions} */ |  | ||||||
|     const options = { |  | ||||||
|         cwd: process.cwd(), |  | ||||||
|         stdio: "inherit", |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     try { |  | ||||||
|         if (typeof preflight == "string") { |  | ||||||
|             execFileSync(preflight, options); |  | ||||||
|         } else if (typeof preflight == "object" && preflight?.[0]) { |  | ||||||
|             for (let i = 0; i < preflight.length; i++) { |  | ||||||
|                 const cmd = preflight[i]; |  | ||||||
|                 try { |  | ||||||
|                     const execCmd = execSync(cmd, options); |  | ||||||
|                 } catch (error) { |  | ||||||
|                     console.log( |  | ||||||
|                         `${colors.FgRed}Error:${colors.Reset} ${tag} command ${cmd} Failed! => ${error.message}` |  | ||||||
|                     ); |  | ||||||
|                     return false; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return true; |  | ||||||
|     } catch (error) { |  | ||||||
|         console.log( |  | ||||||
|             `${colors.FgRed}Error:${colors.Reset} ${tag} Failed! => ${error.message}` |  | ||||||
|         ); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * ## Kill Child Process Function |  | ||||||
|  * @param {string | number | (string | number)[]} [port] |  | ||||||
|  * @returns {Promise<boolean>} |  | ||||||
|  */ |  | ||||||
| async function killChild(port) { |  | ||||||
|     if (!childProcess) return false; |  | ||||||
| 
 |  | ||||||
|     try { |  | ||||||
|         const childProcessPID = childProcess.pid; |  | ||||||
|         childProcess.kill(); |  | ||||||
| 
 |  | ||||||
|         if (typeof port == "object" && port?.[0]) { |  | ||||||
|             for (let i = 0; i < port.length; i++) { |  | ||||||
|                 const singlePort = port[i]; |  | ||||||
|                 await kill(Number(singlePort)); |  | ||||||
|             } |  | ||||||
|         } else if (port) { |  | ||||||
|             await kill(Number(port)); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     } catch (error) { |  | ||||||
|         console.log( |  | ||||||
|             `${colors.FgRed}Error:${colors.Reset} Child Process couldn't be killed! ${error.message}` |  | ||||||
|         ); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| module.exports = startProcess; |  | ||||||
							
								
								
									
										1
									
								
								dist/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | export {}; | ||||||
							
								
								
									
										50
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | "use strict"; | ||||||
|  | var __importDefault = (this && this.__importDefault) || function (mod) { | ||||||
|  |     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | const fs_1 = __importDefault(require("fs")); | ||||||
|  | const path_1 = __importDefault(require("path")); | ||||||
|  | const console_colors_1 = __importDefault(require("./utils/console-colors")); | ||||||
|  | const start_1 = __importDefault(require("./utils/start")); | ||||||
|  | const WORK_DIR = process.cwd(); | ||||||
|  | function run() { | ||||||
|  |     try { | ||||||
|  |         const configText = fs_1.default.readFileSync(path_1.default.join(WORK_DIR, "nodecid.config.json"), "utf-8"); | ||||||
|  |         const config = JSON.parse(configText); | ||||||
|  |         const { start, preflight, postflight, build, redeploy_path, first_run, port, } = config; | ||||||
|  |         /** @type {string | undefined} */ | ||||||
|  |         let redeployFile; | ||||||
|  |         if (!redeploy_path) { | ||||||
|  |             const defaultRedeployPath = path_1.default.join(WORK_DIR, "REDEPLOY"); | ||||||
|  |             const checkExistingPath = fs_1.default.existsSync(defaultRedeployPath); | ||||||
|  |             if (!checkExistingPath) { | ||||||
|  |                 fs_1.default.writeFileSync(defaultRedeployPath, Date.now().toString(), "utf-8"); | ||||||
|  |             } | ||||||
|  |             redeployFile = path_1.default.join(WORK_DIR, "REDEPLOY"); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             redeployFile = path_1.default.resolve(WORK_DIR, redeploy_path); | ||||||
|  |         } | ||||||
|  |         if (!redeployFile) | ||||||
|  |             throw new Error("Redeploy file not found!"); | ||||||
|  |         (0, start_1.default)({ | ||||||
|  |             command: start, | ||||||
|  |             preflight, | ||||||
|  |             redeploy_file: redeployFile, | ||||||
|  |             first_run, | ||||||
|  |             port, | ||||||
|  |             postflight, | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |     catch (error) { | ||||||
|  |         console.log(`${console_colors_1.default.FgRed}ERROR:${console_colors_1.default.Reset} CI process failed! => ${error.message}`); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | run(); | ||||||
|  | process.on("exit", () => { | ||||||
|  |     console.log("Process exiting ..."); | ||||||
|  | }); | ||||||
|  | process.on("beforeExit", () => { | ||||||
|  |     console.log("Process Before exit ..."); | ||||||
|  | }); | ||||||
							
								
								
									
										1
									
								
								dist/tsconfig.tsbuildinfo
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/tsconfig.tsbuildinfo
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										13
									
								
								dist/types.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								dist/types.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | export interface NodeCIConfig { | ||||||
|  |     start: string; | ||||||
|  |     preflight: string[] | string; | ||||||
|  |     postflight?: string[] | string; | ||||||
|  |     redeploy_path?: string; | ||||||
|  |     first_run?: boolean; | ||||||
|  |     port?: string | number | (string | number)[]; | ||||||
|  |     build?: NodeCIBuild; | ||||||
|  | } | ||||||
|  | export interface NodeCIBuild { | ||||||
|  |     paradigm: "Next.JS" | "Remix"; | ||||||
|  |     out_dir?: string; | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								dist/types.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								dist/types.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | "use strict"; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
							
								
								
									
										28
									
								
								dist/utils/console-colors.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								dist/utils/console-colors.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | declare const colors: { | ||||||
|  |     Reset: string; | ||||||
|  |     Bright: string; | ||||||
|  |     Dim: string; | ||||||
|  |     Underscore: string; | ||||||
|  |     Blink: string; | ||||||
|  |     Reverse: string; | ||||||
|  |     Hidden: string; | ||||||
|  |     FgBlack: string; | ||||||
|  |     FgRed: string; | ||||||
|  |     FgGreen: string; | ||||||
|  |     FgYellow: string; | ||||||
|  |     FgBlue: string; | ||||||
|  |     FgMagenta: string; | ||||||
|  |     FgCyan: string; | ||||||
|  |     FgWhite: string; | ||||||
|  |     FgGray: string; | ||||||
|  |     BgBlack: string; | ||||||
|  |     BgRed: string; | ||||||
|  |     BgGreen: string; | ||||||
|  |     BgYellow: string; | ||||||
|  |     BgBlue: string; | ||||||
|  |     BgMagenta: string; | ||||||
|  |     BgCyan: string; | ||||||
|  |     BgWhite: string; | ||||||
|  |     BgGray: string; | ||||||
|  | }; | ||||||
|  | export default colors; | ||||||
							
								
								
									
										61
									
								
								utils/console-colors.js → dist/utils/console-colors.js
									
									
									
									
										vendored
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										61
									
								
								utils/console-colors.js → dist/utils/console-colors.js
									
									
									
									
										vendored
									
									
										
										
										Executable file → Normal file
									
								
							| @ -1,31 +1,30 @@ | |||||||
| const colors = { | "use strict"; | ||||||
|     Reset: "\x1b[0m", | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|     Bright: "\x1b[1m", | const colors = { | ||||||
|     Dim: "\x1b[2m", |     Reset: "\x1b[0m", | ||||||
|     Underscore: "\x1b[4m", |     Bright: "\x1b[1m", | ||||||
|     Blink: "\x1b[5m", |     Dim: "\x1b[2m", | ||||||
|     Reverse: "\x1b[7m", |     Underscore: "\x1b[4m", | ||||||
|     Hidden: "\x1b[8m", |     Blink: "\x1b[5m", | ||||||
| 
 |     Reverse: "\x1b[7m", | ||||||
|     FgBlack: "\x1b[30m", |     Hidden: "\x1b[8m", | ||||||
|     FgRed: "\x1b[31m", |     FgBlack: "\x1b[30m", | ||||||
|     FgGreen: "\x1b[32m", |     FgRed: "\x1b[31m", | ||||||
|     FgYellow: "\x1b[33m", |     FgGreen: "\x1b[32m", | ||||||
|     FgBlue: "\x1b[34m", |     FgYellow: "\x1b[33m", | ||||||
|     FgMagenta: "\x1b[35m", |     FgBlue: "\x1b[34m", | ||||||
|     FgCyan: "\x1b[36m", |     FgMagenta: "\x1b[35m", | ||||||
|     FgWhite: "\x1b[37m", |     FgCyan: "\x1b[36m", | ||||||
|     FgGray: "\x1b[90m", |     FgWhite: "\x1b[37m", | ||||||
| 
 |     FgGray: "\x1b[90m", | ||||||
|     BgBlack: "\x1b[40m", |     BgBlack: "\x1b[40m", | ||||||
|     BgRed: "\x1b[41m", |     BgRed: "\x1b[41m", | ||||||
|     BgGreen: "\x1b[42m", |     BgGreen: "\x1b[42m", | ||||||
|     BgYellow: "\x1b[43m", |     BgYellow: "\x1b[43m", | ||||||
|     BgBlue: "\x1b[44m", |     BgBlue: "\x1b[44m", | ||||||
|     BgMagenta: "\x1b[45m", |     BgMagenta: "\x1b[45m", | ||||||
|     BgCyan: "\x1b[46m", |     BgCyan: "\x1b[46m", | ||||||
|     BgWhite: "\x1b[47m", |     BgWhite: "\x1b[47m", | ||||||
|     BgGray: "\x1b[100m", |     BgGray: "\x1b[100m", | ||||||
| }; | }; | ||||||
| 
 | exports.default = colors; | ||||||
| module.exports = colors; |  | ||||||
							
								
								
									
										6
									
								
								dist/utils/kill-child.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								dist/utils/kill-child.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | /** | ||||||
|  |  * ## Kill Child Process Function | ||||||
|  |  * @param {string | number | (string | number)[]} [port] | ||||||
|  |  * @returns {Promise<boolean>} | ||||||
|  |  */ | ||||||
|  | export default function killChild(port?: string | number | (string | number)[]): Promise<boolean>; | ||||||
							
								
								
									
										49
									
								
								dist/utils/kill-child.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								dist/utils/kill-child.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | "use strict"; | ||||||
|  | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||||
|  |     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||||
|  |     return new (P || (P = Promise))(function (resolve, reject) { | ||||||
|  |         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||||
|  |         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||||
|  |         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||||
|  |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | var __importDefault = (this && this.__importDefault) || function (mod) { | ||||||
|  |     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | exports.default = killChild; | ||||||
|  | const console_colors_1 = __importDefault(require("./console-colors")); | ||||||
|  | const kill_port_1 = __importDefault(require("kill-port")); | ||||||
|  | let childProcess = null; | ||||||
|  | const pTitle = "nodecid"; | ||||||
|  | process.title = pTitle; | ||||||
|  | /** | ||||||
|  |  * ## Kill Child Process Function | ||||||
|  |  * @param {string | number | (string | number)[]} [port] | ||||||
|  |  * @returns {Promise<boolean>} | ||||||
|  |  */ | ||||||
|  | function killChild(port) { | ||||||
|  |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|  |         if (!childProcess) | ||||||
|  |             return false; | ||||||
|  |         try { | ||||||
|  |             const childProcessPID = childProcess.pid; | ||||||
|  |             childProcess.kill(); | ||||||
|  |             if (typeof port == "object" && (port === null || port === void 0 ? void 0 : port[0])) { | ||||||
|  |                 for (let i = 0; i < port.length; i++) { | ||||||
|  |                     const singlePort = port[i]; | ||||||
|  |                     yield (0, kill_port_1.default)(Number(singlePort)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else if (port) { | ||||||
|  |                 yield (0, kill_port_1.default)(Number(port)); | ||||||
|  |             } | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         catch (error) { | ||||||
|  |             console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Child Process couldn't be killed! ${error.message}`); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								dist/utils/preflight.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								dist/utils/preflight.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | /** | ||||||
|  |  * ## Preflight Function | ||||||
|  |  * @param {string[] | string} preflight | ||||||
|  |  * @param {boolean} [postflight] | ||||||
|  |  * @returns {boolean} | ||||||
|  |  */ | ||||||
|  | export default function preflightFn(preflight?: string[] | string, postflight?: boolean): boolean; | ||||||
							
								
								
									
										45
									
								
								dist/utils/preflight.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								dist/utils/preflight.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | "use strict"; | ||||||
|  | var __importDefault = (this && this.__importDefault) || function (mod) { | ||||||
|  |     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | exports.default = preflightFn; | ||||||
|  | const child_process_1 = require("child_process"); | ||||||
|  | const console_colors_1 = __importDefault(require("../utils/console-colors")); | ||||||
|  | /** | ||||||
|  |  * ## Preflight Function | ||||||
|  |  * @param {string[] | string} preflight | ||||||
|  |  * @param {boolean} [postflight] | ||||||
|  |  * @returns {boolean} | ||||||
|  |  */ | ||||||
|  | function preflightFn(preflight, postflight) { | ||||||
|  |     const tag = postflight ? "Postflight" : "Preflight"; | ||||||
|  |     console.log(`${tag} Running ...`); | ||||||
|  |     const options = { | ||||||
|  |         cwd: process.cwd(), | ||||||
|  |         stdio: "inherit", | ||||||
|  |     }; | ||||||
|  |     try { | ||||||
|  |         if (typeof preflight == "string") { | ||||||
|  |             (0, child_process_1.execFileSync)(preflight, options); | ||||||
|  |         } | ||||||
|  |         else if (typeof preflight == "object" && (preflight === null || preflight === void 0 ? void 0 : preflight[0])) { | ||||||
|  |             for (let i = 0; i < preflight.length; i++) { | ||||||
|  |                 const cmd = preflight[i]; | ||||||
|  |                 try { | ||||||
|  |                     const execCmd = (0, child_process_1.execSync)(cmd, options); | ||||||
|  |                 } | ||||||
|  |                 catch (error) { | ||||||
|  |                     console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} ${tag} command ${cmd} Failed! => ${error.message}`); | ||||||
|  |                     return false; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     catch (error) { | ||||||
|  |         console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} ${tag} Failed! => ${error.message}`); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								dist/utils/run.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								dist/utils/run.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | import { ChildProcess } from "child_process"; | ||||||
|  | /** | ||||||
|  |  * ## Preflight Function | ||||||
|  |  * @param {string} command | ||||||
|  |  * @returns {ChildProcess | null} | ||||||
|  |  */ | ||||||
|  | export default function run(command: string): ChildProcess | null; | ||||||
							
								
								
									
										39
									
								
								dist/utils/run.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								dist/utils/run.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | "use strict"; | ||||||
|  | var __importDefault = (this && this.__importDefault) || function (mod) { | ||||||
|  |     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | exports.default = run; | ||||||
|  | const child_process_1 = require("child_process"); | ||||||
|  | const console_colors_1 = __importDefault(require("./console-colors")); | ||||||
|  | let redeployments = 0; | ||||||
|  | const KILL_SIGNAL = "SIGTERM"; | ||||||
|  | const pTitle = "nodecid"; | ||||||
|  | process.title = pTitle; | ||||||
|  | /** | ||||||
|  |  * ## Preflight Function | ||||||
|  |  * @param {string} command | ||||||
|  |  * @returns {ChildProcess | null} | ||||||
|  |  */ | ||||||
|  | function run(command) { | ||||||
|  |     console.log("\n******************************"); | ||||||
|  |     console.log(`****** ${console_colors_1.default.FgGreen}Starting App ...${console_colors_1.default.Reset} ******`); | ||||||
|  |     console.log("******************************\n"); | ||||||
|  |     const startCommandArray = command.split(" ").filter((str) => str.trim()); | ||||||
|  |     try { | ||||||
|  |         const firstCommand = startCommandArray.shift(); | ||||||
|  |         if (!firstCommand) { | ||||||
|  |             throw new Error("No Starting Command Found in command string!"); | ||||||
|  |         } | ||||||
|  |         let childProcess = (0, child_process_1.spawn)(firstCommand, startCommandArray, { | ||||||
|  |             stdio: "inherit", | ||||||
|  |             killSignal: KILL_SIGNAL, | ||||||
|  |         }); | ||||||
|  |         redeployments++; | ||||||
|  |         return childProcess; | ||||||
|  |     } | ||||||
|  |     catch (error) { | ||||||
|  |         console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} running start command => ${error.message}`); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								dist/utils/start.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								dist/utils/start.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | /** | ||||||
|  |  * # Start the process | ||||||
|  |  * @param {object} param0 | ||||||
|  |  * @param {string} param0.command | ||||||
|  |  * @param {string[] | string} param0.preflight | ||||||
|  |  * @param {string[] | string} [param0.postflight] | ||||||
|  |  * @param {string} param0.redeploy_file | ||||||
|  |  * @param {string | number | (string | number)[]} [param0.port] - The port to kill on rebuild | ||||||
|  |  * @param {boolean} [param0.first_run] - Whether to run the preflight on first run. Default `false` | ||||||
|  |  */ | ||||||
|  | export default function startProcess({ command, preflight, postflight, redeploy_file, port, first_run, }: { | ||||||
|  |     command: string; | ||||||
|  |     preflight: string[] | string; | ||||||
|  |     postflight?: string[] | string; | ||||||
|  |     redeploy_file: string; | ||||||
|  |     port?: string | number | (string | number)[]; | ||||||
|  |     first_run?: boolean; | ||||||
|  | }): void; | ||||||
							
								
								
									
										84
									
								
								dist/utils/start.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								dist/utils/start.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | "use strict"; | ||||||
|  | var __importDefault = (this && this.__importDefault) || function (mod) { | ||||||
|  |     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||||
|  | }; | ||||||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
|  | exports.default = startProcess; | ||||||
|  | const fs_1 = __importDefault(require("fs")); | ||||||
|  | const console_colors_1 = __importDefault(require("./console-colors")); | ||||||
|  | const preflight_1 = __importDefault(require("./preflight")); | ||||||
|  | const run_1 = __importDefault(require("./run")); | ||||||
|  | const kill_child_1 = __importDefault(require("./kill-child")); | ||||||
|  | let redeployments = 0; | ||||||
|  | let childProcess = null; | ||||||
|  | const pTitle = "nodecid"; | ||||||
|  | process.title = pTitle; | ||||||
|  | /** | ||||||
|  |  * # Start the process | ||||||
|  |  * @param {object} param0 | ||||||
|  |  * @param {string} param0.command | ||||||
|  |  * @param {string[] | string} param0.preflight | ||||||
|  |  * @param {string[] | string} [param0.postflight] | ||||||
|  |  * @param {string} param0.redeploy_file | ||||||
|  |  * @param {string | number | (string | number)[]} [param0.port] - The port to kill on rebuild | ||||||
|  |  * @param {boolean} [param0.first_run] - Whether to run the preflight on first run. Default `false` | ||||||
|  |  */ | ||||||
|  | function startProcess({ command, preflight, postflight, redeploy_file, port, first_run, }) { | ||||||
|  |     try { | ||||||
|  |         if (first_run) { | ||||||
|  |             console.log("First Run ..."); | ||||||
|  |             const runPreflight = (0, preflight_1.default)(preflight); | ||||||
|  |         } | ||||||
|  |         if (!preflight) { | ||||||
|  |             console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} No preflight included in config file. If you don't want to run any preflight command simply add an empty array.`); | ||||||
|  |             process.exit(); | ||||||
|  |         } | ||||||
|  |         childProcess = (0, run_1.default)(command); | ||||||
|  |         if (!childProcess) { | ||||||
|  |             console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Process couldn't start. Exiting...`); | ||||||
|  |             process.exit(); | ||||||
|  |         } | ||||||
|  |         console.log("Watching", redeploy_file); | ||||||
|  |         fs_1.default.watchFile(redeploy_file, { interval: 100 }, (curr, prev) => { | ||||||
|  |             console.log(`${console_colors_1.default.BgBlue}File Changed${console_colors_1.default.Reset}`); | ||||||
|  |             if (redeployments == 0) | ||||||
|  |                 return; | ||||||
|  |             if (childProcess) { | ||||||
|  |                 console.log("******************************"); | ||||||
|  |                 console.log(`******** ${console_colors_1.default.FgBlue}Rebuilding ${console_colors_1.default.FgMagenta}${redeployments}${console_colors_1.default.Reset} ********`); | ||||||
|  |                 console.log("******************************"); | ||||||
|  |                 try { | ||||||
|  |                     const runPreflight = (0, preflight_1.default)(preflight); | ||||||
|  |                     if (!runPreflight) { | ||||||
|  |                         // TODO: Action to take if preflight fails
 | ||||||
|  |                         console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Preflight Failed.`); | ||||||
|  |                     } | ||||||
|  |                     else { | ||||||
|  |                         (0, kill_child_1.default)(port).then((kill) => { | ||||||
|  |                             if (kill) { | ||||||
|  |                                 childProcess = (0, run_1.default)(command); | ||||||
|  |                                 if (postflight) { | ||||||
|  |                                     const runPostflight = (0, preflight_1.default)(postflight, true); | ||||||
|  |                                     if (!runPostflight) { | ||||||
|  |                                         // TODO: Action to take if postflight fails
 | ||||||
|  |                                         console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} Postflight Failed.`); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                             else { | ||||||
|  |                                 process.exit(); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 catch (error) { | ||||||
|  |                     console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} killing child processes => ${error.message}`); | ||||||
|  |                     process.exit(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |     catch (error) { | ||||||
|  |         console.log(`${console_colors_1.default.FgRed}Error:${console_colors_1.default.Reset} First run failed! => ${error.message}`); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								dist/utils/triggers/github.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								dist/utils/triggers/github.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | declare function githubWebhook(): boolean; | ||||||
							
								
								
									
										4
									
								
								dist/utils/triggers/github.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								dist/utils/triggers/github.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | "use strict"; | ||||||
|  | function githubWebhook() { | ||||||
|  |     return true; | ||||||
|  | } | ||||||
| @ -1,21 +1,11 @@ | |||||||
| #! /usr/bin/env node | import fs from "fs"; | ||||||
| // @ts-check
 | import path from "path"; | ||||||
| 
 | import colors from "./utils/console-colors"; | ||||||
| const fs = require("fs"); | import startProcess from "./utils/start"; | ||||||
| const path = require("path"); | import type { NodeCIConfig } from "./types"; | ||||||
| const colors = require("./utils/console-colors"); |  | ||||||
| const startProcess = require("./deploy/start"); |  | ||||||
| 
 |  | ||||||
| ///////////////////////////////////////////////
 |  | ||||||
| ///////////////////////////////////////////////
 |  | ||||||
| ///////////////////////////////////////////////
 |  | ||||||
| 
 | 
 | ||||||
| const WORK_DIR = process.cwd(); | const WORK_DIR = process.cwd(); | ||||||
| 
 | 
 | ||||||
| ///////////////////////////////////////////////
 |  | ||||||
| ///////////////////////////////////////////////
 |  | ||||||
| ///////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| function run() { | function run() { | ||||||
|     try { |     try { | ||||||
|         const configText = fs.readFileSync( |         const configText = fs.readFileSync( | ||||||
| @ -23,8 +13,7 @@ function run() { | |||||||
|             "utf-8" |             "utf-8" | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         /** @type {NodeCIConfig} */ |         const config: NodeCIConfig = JSON.parse(configText); | ||||||
|         const config = JSON.parse(configText); |  | ||||||
| 
 | 
 | ||||||
|         const { |         const { | ||||||
|             start, |             start, | ||||||
| @ -66,7 +55,7 @@ function run() { | |||||||
|             port, |             port, | ||||||
|             postflight, |             postflight, | ||||||
|         }); |         }); | ||||||
|     } catch (error) { |     } catch (error: any) { | ||||||
|         console.log( |         console.log( | ||||||
|             `${colors.FgRed}ERROR:${colors.Reset} CI process failed! => ${error.message}` |             `${colors.FgRed}ERROR:${colors.Reset} CI process failed! => ${error.message}` | ||||||
|         ); |         ); | ||||||
| @ -75,10 +64,6 @@ function run() { | |||||||
| 
 | 
 | ||||||
| run(); | run(); | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| ////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| process.on("exit", () => { | process.on("exit", () => { | ||||||
|     console.log("Process exiting ..."); |     console.log("Process exiting ..."); | ||||||
| }); | }); | ||||||
							
								
								
									
										27
									
								
								jsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								jsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     // Enable latest features | ||||||
|  |     "lib": ["ESNext", "DOM"], | ||||||
|  |     "target": "ESNext", | ||||||
|  |     "module": "ESNext", | ||||||
|  |     "moduleDetection": "force", | ||||||
|  |     "jsx": "react-jsx", | ||||||
|  |     "allowJs": true, | ||||||
|  | 
 | ||||||
|  |     // Bundler mode | ||||||
|  |     "moduleResolution": "bundler", | ||||||
|  |     "allowImportingTsExtensions": true, | ||||||
|  |     "verbatimModuleSyntax": true, | ||||||
|  |     "noEmit": true, | ||||||
|  | 
 | ||||||
|  |     // Best practices | ||||||
|  |     "strict": true, | ||||||
|  |     "skipLibCheck": true, | ||||||
|  |     "noFallthroughCasesInSwitch": true, | ||||||
|  | 
 | ||||||
|  |     // Some stricter flags (disabled by default) | ||||||
|  |     "noUnusedLocals": false, | ||||||
|  |     "noUnusedParameters": false, | ||||||
|  |     "noPropertyAccessFromIndexSignature": false | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										42
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,42 +0,0 @@ | |||||||
| { |  | ||||||
|     "name": "nodecid", |  | ||||||
|     "version": "1.0.5", |  | ||||||
|     "lockfileVersion": 3, |  | ||||||
|     "requires": true, |  | ||||||
|     "packages": { |  | ||||||
|         "": { |  | ||||||
|             "name": "nodecid", |  | ||||||
|             "version": "1.0.5", |  | ||||||
|             "license": "MIT", |  | ||||||
|             "dependencies": { |  | ||||||
|                 "kill-port": "^2.0.1" |  | ||||||
|             }, |  | ||||||
|             "bin": { |  | ||||||
|                 "node-ci-cd": "index.js", |  | ||||||
|                 "nodecid": "index.js" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         "node_modules/get-them-args": { |  | ||||||
|             "version": "1.3.2", |  | ||||||
|             "resolved": "https://registry.npmjs.org/get-them-args/-/get-them-args-1.3.2.tgz", |  | ||||||
|             "integrity": "sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw==" |  | ||||||
|         }, |  | ||||||
|         "node_modules/kill-port": { |  | ||||||
|             "version": "2.0.1", |  | ||||||
|             "resolved": "https://registry.npmjs.org/kill-port/-/kill-port-2.0.1.tgz", |  | ||||||
|             "integrity": "sha512-e0SVOV5jFo0mx8r7bS29maVWp17qGqLBZ5ricNSajON6//kmb7qqqNnml4twNE8Dtj97UQD+gNFOaipS/q1zzQ==", |  | ||||||
|             "dependencies": { |  | ||||||
|                 "get-them-args": "1.3.2", |  | ||||||
|                 "shell-exec": "1.0.2" |  | ||||||
|             }, |  | ||||||
|             "bin": { |  | ||||||
|                 "kill-port": "cli.js" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         "node_modules/shell-exec": { |  | ||||||
|             "version": "1.0.2", |  | ||||||
|             "resolved": "https://registry.npmjs.org/shell-exec/-/shell-exec-1.0.2.tgz", |  | ||||||
|             "integrity": "sha512-jyVd+kU2X+mWKMmGhx4fpWbPsjvD53k9ivqetutVW/BQ+WIZoDoP4d8vUMGezV6saZsiNoW2f9GIhg9Dondohg==" |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										18
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								package.json
									
									
									
									
									
								
							| @ -1,11 +1,14 @@ | |||||||
| { | { | ||||||
|     "name": "nodecid", |     "name": "@moduletrace/nodecid", | ||||||
|     "version": "1.0.7", |     "version": "1.0.7", | ||||||
|     "description": "Simple CI/CD process", |     "description": "Simple CI/CD process", | ||||||
|     "main": "index.js", |     "main": "dist/index.js", | ||||||
|     "bin": { |     "bin": { | ||||||
|         "nodecid": "./index.js", |         "nodecid": "./dist/index.js", | ||||||
|         "node-ci-cd": "./index.js" |         "node-ci-cd": "./dist/index.js" | ||||||
|  |     }, | ||||||
|  |     "scripts": { | ||||||
|  |         "compile": "bun build --compile --minify --sourcemap --bytecode index.ts --outfile bin/nodecid" | ||||||
|     }, |     }, | ||||||
|     "keywords": [ |     "keywords": [ | ||||||
|         "CI/CD", |         "CI/CD", | ||||||
| @ -16,5 +19,12 @@ | |||||||
|     "license": "MIT", |     "license": "MIT", | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "kill-port": "^2.0.1" |         "kill-port": "^2.0.1" | ||||||
|  |     }, | ||||||
|  |     "devDependencies": { | ||||||
|  |         "@types/bun": "latest", | ||||||
|  |         "@types/node": "^22.10.7" | ||||||
|  |     }, | ||||||
|  |     "peerDependencies": { | ||||||
|  |         "typescript": "^5.0.0" | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | { | ||||||
|  |     "compilerOptions": { | ||||||
|  |         "target": "ES2015", | ||||||
|  |         "module": "commonjs", | ||||||
|  |         "maxNodeModuleJsDepth": 10, | ||||||
|  |         "esModuleInterop": true, | ||||||
|  |         "forceConsistentCasingInFileNames": true, | ||||||
|  |         "strict": true, | ||||||
|  |         "skipLibCheck": true, | ||||||
|  |         "lib": ["dom", "dom.iterable", "esnext"], | ||||||
|  |         "allowJs": true, | ||||||
|  |         "incremental": true, | ||||||
|  |         "resolveJsonModule": true, | ||||||
|  |         "jsx": "preserve", | ||||||
|  |         "moduleResolution": "node", | ||||||
|  |         "declaration": true, | ||||||
|  |         "outDir": "dist" | ||||||
|  |     }, | ||||||
|  |     "include": ["**/*.ts"], | ||||||
|  |     "exclude": ["node_modules", "dist"] | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								types.d.js
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								types.d.js
									
									
									
									
									
								
							| @ -1,19 +0,0 @@ | |||||||
| /** |  | ||||||
|  * @typedef {object} NodeCIConfig |  | ||||||
|  * @property {string} start - Start command. Eg `node index.js` |  | ||||||
|  * @property {string[] | string} preflight - And array of commands to run before |  | ||||||
|  * the application starts, or a single `.sh` file path. |  | ||||||
|  * @property {string[] | string} [postflight] - And array of commands to run after |  | ||||||
|  * the application starts. |  | ||||||
|  * @property {string} [redeploy_path] - The path to the file that will trigger a |  | ||||||
|  * redeployment if content is changed. Default file path is `./REDEPLOY` |  | ||||||
|  * @property {boolean} [first_run] - Whether to run the preflight on first run. Default `false` |  | ||||||
|  * @property {string | number | (string | number)[]} [port] - The port to kill on reload |  | ||||||
|  * @property {NodeCIBuild} [build] - Build configurations |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * @typedef {object} NodeCIBuild |  | ||||||
|  * @property {"Next.JS" | "Remix"} paradigm - The paradigm to build on |  | ||||||
|  * @property {string} [out_dir] - The output Directory. Default `.dist`. |  | ||||||
|  */ |  | ||||||
							
								
								
									
										14
									
								
								types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								types.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | export interface NodeCIConfig { | ||||||
|  |     start: string; | ||||||
|  |     preflight: string[] | string; | ||||||
|  |     postflight?: string[] | string; | ||||||
|  |     redeploy_path?: string; | ||||||
|  |     first_run?: boolean; | ||||||
|  |     port?: string | number | (string | number)[]; | ||||||
|  |     build?: NodeCIBuild; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface NodeCIBuild { | ||||||
|  |     paradigm: "Next.JS" | "Remix"; | ||||||
|  |     out_dir?: string; | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								utils/console-colors.ts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								utils/console-colors.ts
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | const colors = { | ||||||
|  |     Reset: "\x1b[0m", | ||||||
|  |     Bright: "\x1b[1m", | ||||||
|  |     Dim: "\x1b[2m", | ||||||
|  |     Underscore: "\x1b[4m", | ||||||
|  |     Blink: "\x1b[5m", | ||||||
|  |     Reverse: "\x1b[7m", | ||||||
|  |     Hidden: "\x1b[8m", | ||||||
|  | 
 | ||||||
|  |     FgBlack: "\x1b[30m", | ||||||
|  |     FgRed: "\x1b[31m", | ||||||
|  |     FgGreen: "\x1b[32m", | ||||||
|  |     FgYellow: "\x1b[33m", | ||||||
|  |     FgBlue: "\x1b[34m", | ||||||
|  |     FgMagenta: "\x1b[35m", | ||||||
|  |     FgCyan: "\x1b[36m", | ||||||
|  |     FgWhite: "\x1b[37m", | ||||||
|  |     FgGray: "\x1b[90m", | ||||||
|  | 
 | ||||||
|  |     BgBlack: "\x1b[40m", | ||||||
|  |     BgRed: "\x1b[41m", | ||||||
|  |     BgGreen: "\x1b[42m", | ||||||
|  |     BgYellow: "\x1b[43m", | ||||||
|  |     BgBlue: "\x1b[44m", | ||||||
|  |     BgMagenta: "\x1b[45m", | ||||||
|  |     BgCyan: "\x1b[46m", | ||||||
|  |     BgWhite: "\x1b[47m", | ||||||
|  |     BgGray: "\x1b[100m", | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default colors; | ||||||
							
								
								
									
										40
									
								
								utils/kill-child.ts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										40
									
								
								utils/kill-child.ts
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | import { ChildProcess } from "child_process"; | ||||||
|  | import colors from "./console-colors"; | ||||||
|  | import kill from "kill-port"; | ||||||
|  | 
 | ||||||
|  | let childProcess: ChildProcess | null = null; | ||||||
|  | 
 | ||||||
|  | const pTitle = "nodecid"; | ||||||
|  | process.title = pTitle; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * ## Kill Child Process Function | ||||||
|  |  * @param {string | number | (string | number)[]} [port] | ||||||
|  |  * @returns {Promise<boolean>} | ||||||
|  |  */ | ||||||
|  | export default async function killChild( | ||||||
|  |     port?: string | number | (string | number)[] | ||||||
|  | ): Promise<boolean> { | ||||||
|  |     if (!childProcess) return false; | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |         const childProcessPID = childProcess.pid; | ||||||
|  |         childProcess.kill(); | ||||||
|  | 
 | ||||||
|  |         if (typeof port == "object" && port?.[0]) { | ||||||
|  |             for (let i = 0; i < port.length; i++) { | ||||||
|  |                 const singlePort = port[i]; | ||||||
|  |                 await kill(Number(singlePort)); | ||||||
|  |             } | ||||||
|  |         } else if (port) { | ||||||
|  |             await kill(Number(port)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } catch (error: any) { | ||||||
|  |         console.log( | ||||||
|  |             `${colors.FgRed}Error:${colors.Reset} Child Process couldn't be killed! ${error.message}` | ||||||
|  |         ); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								utils/preflight.ts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										46
									
								
								utils/preflight.ts
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | import { execSync, execFileSync, type ExecSyncOptions } from "child_process"; | ||||||
|  | import colors from "../utils/console-colors"; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * ## Preflight Function | ||||||
|  |  * @param {string[] | string} preflight | ||||||
|  |  * @param {boolean} [postflight] | ||||||
|  |  * @returns {boolean} | ||||||
|  |  */ | ||||||
|  | export default function preflightFn( | ||||||
|  |     preflight?: string[] | string, | ||||||
|  |     postflight?: boolean | ||||||
|  | ): boolean { | ||||||
|  |     const tag = postflight ? "Postflight" : "Preflight"; | ||||||
|  |     console.log(`${tag} Running ...`); | ||||||
|  | 
 | ||||||
|  |     const options: ExecSyncOptions = { | ||||||
|  |         cwd: process.cwd(), | ||||||
|  |         stdio: "inherit", | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |         if (typeof preflight == "string") { | ||||||
|  |             execFileSync(preflight, options); | ||||||
|  |         } else if (typeof preflight == "object" && preflight?.[0]) { | ||||||
|  |             for (let i = 0; i < preflight.length; i++) { | ||||||
|  |                 const cmd = preflight[i]; | ||||||
|  |                 try { | ||||||
|  |                     const execCmd = execSync(cmd, options); | ||||||
|  |                 } catch (error: any) { | ||||||
|  |                     console.log( | ||||||
|  |                         `${colors.FgRed}Error:${colors.Reset} ${tag} command ${cmd} Failed! => ${error.message}` | ||||||
|  |                     ); | ||||||
|  |                     return false; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } catch (error: any) { | ||||||
|  |         console.log( | ||||||
|  |             `${colors.FgRed}Error:${colors.Reset} ${tag} Failed! => ${error.message}` | ||||||
|  |         ); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								utils/run.ts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										46
									
								
								utils/run.ts
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | import { spawn, ChildProcess } from "child_process"; | ||||||
|  | import colors from "./console-colors"; | ||||||
|  | 
 | ||||||
|  | let redeployments = 0; | ||||||
|  | 
 | ||||||
|  | const KILL_SIGNAL: NodeJS.Signals | number = "SIGTERM"; | ||||||
|  | 
 | ||||||
|  | const pTitle = "nodecid"; | ||||||
|  | process.title = pTitle; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * ## Preflight Function | ||||||
|  |  * @param {string} command | ||||||
|  |  * @returns {ChildProcess | null} | ||||||
|  |  */ | ||||||
|  | export default function run(command: string): ChildProcess | null { | ||||||
|  |     console.log("\n******************************"); | ||||||
|  |     console.log( | ||||||
|  |         `****** ${colors.FgGreen}Starting App ...${colors.Reset} ******` | ||||||
|  |     ); | ||||||
|  |     console.log("******************************\n"); | ||||||
|  | 
 | ||||||
|  |     const startCommandArray = command.split(" ").filter((str) => str.trim()); | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |         const firstCommand = startCommandArray.shift(); | ||||||
|  | 
 | ||||||
|  |         if (!firstCommand) { | ||||||
|  |             throw new Error("No Starting Command Found in command string!"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let childProcess = spawn(firstCommand, startCommandArray, { | ||||||
|  |             stdio: "inherit", | ||||||
|  |             killSignal: KILL_SIGNAL, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         redeployments++; | ||||||
|  | 
 | ||||||
|  |         return childProcess; | ||||||
|  |     } catch (error: any) { | ||||||
|  |         console.log( | ||||||
|  |             `${colors.FgRed}Error:${colors.Reset} running start command => ${error.message}` | ||||||
|  |         ); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										123
									
								
								utils/start.ts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										123
									
								
								utils/start.ts
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,123 @@ | |||||||
|  | import fs from "fs"; | ||||||
|  | import { ChildProcess } from "child_process"; | ||||||
|  | import colors from "./console-colors"; | ||||||
|  | import kill from "kill-port"; | ||||||
|  | import preflightFn from "./preflight"; | ||||||
|  | import run from "./run"; | ||||||
|  | import killChild from "./kill-child"; | ||||||
|  | 
 | ||||||
|  | let redeployments = 0; | ||||||
|  | 
 | ||||||
|  | let childProcess: ChildProcess | null = null; | ||||||
|  | 
 | ||||||
|  | const pTitle = "nodecid"; | ||||||
|  | process.title = pTitle; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * # Start the process | ||||||
|  |  * @param {object} param0 | ||||||
|  |  * @param {string} param0.command | ||||||
|  |  * @param {string[] | string} param0.preflight | ||||||
|  |  * @param {string[] | string} [param0.postflight] | ||||||
|  |  * @param {string} param0.redeploy_file | ||||||
|  |  * @param {string | number | (string | number)[]} [param0.port] - The port to kill on rebuild | ||||||
|  |  * @param {boolean} [param0.first_run] - Whether to run the preflight on first run. Default `false` | ||||||
|  |  */ | ||||||
|  | export default function startProcess({ | ||||||
|  |     command, | ||||||
|  |     preflight, | ||||||
|  |     postflight, | ||||||
|  |     redeploy_file, | ||||||
|  |     port, | ||||||
|  |     first_run, | ||||||
|  | }: { | ||||||
|  |     command: string; | ||||||
|  |     preflight: string[] | string; | ||||||
|  |     postflight?: string[] | string; | ||||||
|  |     redeploy_file: string; | ||||||
|  |     port?: string | number | (string | number)[]; | ||||||
|  |     first_run?: boolean; | ||||||
|  | }) { | ||||||
|  |     try { | ||||||
|  |         if (first_run) { | ||||||
|  |             console.log("First Run ..."); | ||||||
|  |             const runPreflight = preflightFn(preflight); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (!preflight) { | ||||||
|  |             console.log( | ||||||
|  |                 `${colors.FgRed}Error:${colors.Reset} No preflight included in config file. If you don't want to run any preflight command simply add an empty array.` | ||||||
|  |             ); | ||||||
|  |             process.exit(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         childProcess = run(command); | ||||||
|  | 
 | ||||||
|  |         if (!childProcess) { | ||||||
|  |             console.log( | ||||||
|  |                 `${colors.FgRed}Error:${colors.Reset} Process couldn't start. Exiting...` | ||||||
|  |             ); | ||||||
|  |             process.exit(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         console.log("Watching", redeploy_file); | ||||||
|  | 
 | ||||||
|  |         fs.watchFile(redeploy_file, { interval: 100 }, (curr, prev) => { | ||||||
|  |             console.log(`${colors.BgBlue}File Changed${colors.Reset}`); | ||||||
|  | 
 | ||||||
|  |             if (redeployments == 0) return; | ||||||
|  | 
 | ||||||
|  |             if (childProcess) { | ||||||
|  |                 console.log("******************************"); | ||||||
|  |                 console.log( | ||||||
|  |                     `******** ${colors.FgBlue}Rebuilding ${colors.FgMagenta}${redeployments}${colors.Reset} ********` | ||||||
|  |                 ); | ||||||
|  |                 console.log("******************************"); | ||||||
|  | 
 | ||||||
|  |                 try { | ||||||
|  |                     const runPreflight = preflightFn(preflight); | ||||||
|  | 
 | ||||||
|  |                     if (!runPreflight) { | ||||||
|  |                         // TODO: Action to take if preflight fails
 | ||||||
|  | 
 | ||||||
|  |                         console.log( | ||||||
|  |                             `${colors.FgRed}Error:${colors.Reset} Preflight Failed.` | ||||||
|  |                         ); | ||||||
|  |                     } else { | ||||||
|  |                         killChild(port).then((kill) => { | ||||||
|  |                             if (kill) { | ||||||
|  |                                 childProcess = run(command); | ||||||
|  | 
 | ||||||
|  |                                 if (postflight) { | ||||||
|  |                                     const runPostflight = preflightFn( | ||||||
|  |                                         postflight, | ||||||
|  |                                         true | ||||||
|  |                                     ); | ||||||
|  | 
 | ||||||
|  |                                     if (!runPostflight) { | ||||||
|  |                                         // TODO: Action to take if postflight fails
 | ||||||
|  | 
 | ||||||
|  |                                         console.log( | ||||||
|  |                                             `${colors.FgRed}Error:${colors.Reset} Postflight Failed.` | ||||||
|  |                                         ); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } else { | ||||||
|  |                                 process.exit(); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|  |                 } catch (error: any) { | ||||||
|  |                     console.log( | ||||||
|  |                         `${colors.FgRed}Error:${colors.Reset} killing child processes => ${error.message}` | ||||||
|  |                     ); | ||||||
|  |                     process.exit(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } catch (error: any) { | ||||||
|  |         console.log( | ||||||
|  |             `${colors.FgRed}Error:${colors.Reset} First run failed! => ${error.message}` | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Benjamin Toby
						Benjamin Toby