* Run a function if the module is the main entry for `node` process. * * @param currentModule - Current module. It's used to determine if the module * is the main entry script for `node` * @param {*} fn - An function. It can be sync or async. The return or resolved * value is handled as follows
(currentModule, fn, ...args)
| 127 | * @param {*} args - Arguments for the function |
| 128 | */ |
| 129 | function runMain(currentModule, fn, ...args) { |
| 130 | assert( |
| 131 | typeof currentModule === 'object' && currentModule.filename, |
| 132 | 'The first argument must be a module object', |
| 133 | ); |
| 134 | assert(typeof fn === 'function', 'The second argument must be a function'); |
| 135 | // Only run the function if the module is the main entry script for `node` |
| 136 | if (require.main !== currentModule) return; |
| 137 | |
| 138 | // Error handler |
| 139 | const handleError = err => { |
| 140 | console.error(err); |
| 141 | process.exit(err.exitCode || 1); |
| 142 | }; |
| 143 | |
| 144 | // Return handler |
| 145 | const handleReturn = val => { |
| 146 | if (val != null) { |
| 147 | if (val === true) return; |
| 148 | if (val === false) { |
| 149 | process.exit(1); |
| 150 | } |
| 151 | if (typeof val === 'object' && typeof val.exitCode === 'number') { |
| 152 | process.exit(val.exitCode); |
| 153 | } else { |
| 154 | console.log(val); |
| 155 | } |
| 156 | } |
| 157 | }; |
| 158 | let valueOrPromise; |
| 159 | try { |
| 160 | valueOrPromise = fn(...args); |
| 161 | if (typeof valueOrPromise.then === 'function') { |
| 162 | // Handle the promise |
| 163 | valueOrPromise.then(handleReturn, handleError); |
| 164 | } else { |
| 165 | // Handle the return value |
| 166 | handleReturn(valueOrPromise); |
| 167 | } |
| 168 | } catch (err) { |
| 169 | // Handle error thrown synchronously |
| 170 | handleError(err); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | exports.isDryRun = isDryRun; |
| 175 | exports.isJsonEqual = isJsonEqual; |
no test coverage detected