@xyo-network/xl1-cli-lib 1.20.14 → 1.20.16
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/README.md +9 -2831
- package/dist/node/index.mjs +1 -1
- package/dist/node/xl1.mjs +1 -1
- package/package.json +142 -34
- package/src/commands/api/apiCommand.ts +0 -39
- package/src/commands/api/index.ts +0 -1
- package/src/commands/bridge/bridgeCommand.ts +0 -19
- package/src/commands/bridge/index.ts +0 -2
- package/src/commands/bridge/runBridge.ts +0 -34
- package/src/commands/index.ts +0 -9
- package/src/commands/mempool/index.ts +0 -1
- package/src/commands/mempool/mempoolCommand.ts +0 -19
- package/src/commands/producer/index.ts +0 -1
- package/src/commands/producer/producerCommand.ts +0 -19
- package/src/commands/rewardRedemption/index.ts +0 -2
- package/src/commands/rewardRedemption/rewardRedemptionCommand.ts +0 -19
- package/src/commands/rewardRedemption/runRewardRedemptionApi.ts +0 -36
- package/src/commands/start/index.ts +0 -1
- package/src/commands/start/startCommand.ts +0 -127
- package/src/commands/types.ts +0 -9
- package/src/commands/validator/index.ts +0 -1
- package/src/commands/validator/runValidator.ts +0 -33
- package/src/commands/withDeprecationWarning.ts +0 -17
- package/src/configMiddleware.ts +0 -55
- package/src/images.ts +0 -19
- package/src/index.ts +0 -4
- package/src/initLogger.ts +0 -23
- package/src/optionsFromGlobalZodRegistry.ts +0 -19
- package/src/runCLI.ts +0 -126
- package/src/start.ts +0 -8
- package/src/waitForHostPort.ts +0 -26
- package/src/xl1.ts +0 -8
package/src/configMiddleware.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { createDeepMerge } from '@xylabs/sdk-js'
|
|
2
|
-
import { tryParseConfig } from '@xyo-network/chain-orchestration'
|
|
3
|
-
import type { Config } from '@xyo-network/xl1-sdk'
|
|
4
|
-
import {
|
|
5
|
-
ConfigZod, isZodError, resolveConfig,
|
|
6
|
-
} from '@xyo-network/xl1-sdk'
|
|
7
|
-
|
|
8
|
-
const deepMerge = createDeepMerge({ arrayStrategy: 'concat' })
|
|
9
|
-
|
|
10
|
-
export async function configMiddleware(argv: Record<string, unknown>, setConfiguration: (config: Config) => void): Promise<void> {
|
|
11
|
-
try {
|
|
12
|
-
// Parse the various config sources
|
|
13
|
-
const configPath = argv.config as string | undefined
|
|
14
|
-
const parsedConfigFile = await tryParseConfig({ configPath }) // Config file
|
|
15
|
-
const parsedConfigArgs = ConfigZod.safeParse(argv).data ?? {} // Command-line arguments & ENV VARs
|
|
16
|
-
const parseResult = ConfigZod.safeParse(deepMerge(parsedConfigFile, parsedConfigArgs))
|
|
17
|
-
if (!parseResult.success) {
|
|
18
|
-
throw parseResult.error
|
|
19
|
-
}
|
|
20
|
-
// Deep merge with precedence
|
|
21
|
-
// TODO: Would like precedence to be defaults < file < ENV < CLI Args
|
|
22
|
-
// but there is currently no way to determine which are defaults vs
|
|
23
|
-
// user-supplied CLI Args since we set the CLI args to the defaults
|
|
24
|
-
// and receive a flattened object. We might need to manually invoke
|
|
25
|
-
// the parser without the defaults to achieve this.
|
|
26
|
-
// const mergedConfig = deepMerge(parsedConfigArgs, parsedConfigFile)
|
|
27
|
-
const mergedConfig = parseResult.data
|
|
28
|
-
const validatedMergedConfigResult = ConfigZod.safeParse(mergedConfig)
|
|
29
|
-
if (!validatedMergedConfigResult.success) {
|
|
30
|
-
throw validatedMergedConfigResult.error
|
|
31
|
-
}
|
|
32
|
-
const resolvedConfig = resolveConfig(validatedMergedConfigResult.data)
|
|
33
|
-
// Validate the merged configuration
|
|
34
|
-
const validatedConfigResult = ConfigZod.safeParse(resolvedConfig)
|
|
35
|
-
if (!validatedConfigResult.success) {
|
|
36
|
-
throw validatedConfigResult.error
|
|
37
|
-
}
|
|
38
|
-
setConfiguration(validatedConfigResult.data)
|
|
39
|
-
|
|
40
|
-
// Check if user wants to dump config and exit
|
|
41
|
-
if (argv['dump-config']) {
|
|
42
|
-
console.log(JSON.stringify(validatedConfigResult.data, null, 2))
|
|
43
|
-
// eslint-disable-next-line unicorn/no-process-exit
|
|
44
|
-
process.exit(0)
|
|
45
|
-
}
|
|
46
|
-
} catch (err) {
|
|
47
|
-
if (isZodError(err)) {
|
|
48
|
-
console.error(`Zod error: ${err.message}`)
|
|
49
|
-
} else {
|
|
50
|
-
console.error(`Error parsing configuration: ${err}`)
|
|
51
|
-
}
|
|
52
|
-
console.error(`Stack: ${err instanceof Error ? err.stack : 'N/A'}`)
|
|
53
|
-
throw new Error('Invalid configuration')
|
|
54
|
-
}
|
|
55
|
-
}
|
package/src/images.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @stylistic/max-len */
|
|
2
|
-
export const XL1LogoColorizedAscii = `[38;2;128;128;128m [0m[38;2;118;111;144m_[0m
|
|
3
|
-
[38;2;128;128;128m [0m[38;2;72;32;223m╠[0m[38;2;66;21;234m╠[0m
|
|
4
|
-
[38;2;128;128;128m ╠╠[0m[38;2;103;85;170m_[0m
|
|
5
|
-
[38;2;128;128;128m [0m[38;2;79;121;152m╦[0m[38;2;82;121;151m╦[0m[38;2;112;125;136m_ [0m[38;2;88;59;196m[[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠[0m[38;2;73;34;221m▒ [0m[38;2;121;121;127m_[0m[38;2;100;101;128m╔[0m[38;2;93;94;127m╦[0m
|
|
6
|
-
[38;2;128;128;128m [0m[38;2;82;121;151m²[0m[38;2;44;116;170m╠[0m[38;2;44;116;171m▒[0m[38;2;51;117;167mD[0m[38;2;80;121;152m╦[0m[38;2;111;125;136m_ [0m[38;2;67;23;232m╠[0m[38;2;66;21;234m╠╠╠ [0m[38;2;120;121;128m_[0m[38;2;100;101;127m╔[0m[38;2;79;81;127mR[0m[38;2;71;73;128m▒[0m[38;2;71;73;128m▒[0m[38;2;88;90;127m╙[0m
|
|
7
|
-
[38;2;128;128;128m [0m[38;2;55;117;165m╚[0m[38;2;44;116;171m▒[0m[38;2;44;116;171m▒▒[0m[38;2;50;116;167mD[0m[38;2;80;121;152m╦ [0m[38;2;106;90;165mj[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠╠[0m[38;2;89;61;194mH [0m[38;2;99;100;127m╔[0m[38;2;79;80;127mD[0m[38;2;71;73;128m▒[0m[38;2;71;73;128m▒▒╠[0m
|
|
8
|
-
[38;2;128;128;128m [0m[38;2;83;121;150m²[0m[38;2;44;116;170m▒[0m[38;2;44;116;171m▒▒▒ [0m[38;2;76;38;217m╠[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠╠╠ [0m[38;2;74;76;128m╠[0m[38;2;71;73;128m▒▒▒[0m[38;2;89;90;128m╙[0m
|
|
9
|
-
[38;2;128;128;128m [0m[38;2;90;118;148m\`[0m[38;2;89;107;153m_[0m[38;2;93;97;154m,[0m[38;2;105;89;166m╓[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠╠╠╠[0m[38;2;95;72;183m╓[0m[38;2;106;96;152m_[0m[38;2;100;94;143m\`[0m[38;2;101;100;133m\`[0m
|
|
10
|
-
[38;2;128;128;128m [0m[38;2;122;118;137m_[0m[38;2;113;102;153m,[0m[38;2;108;94;161m╓[0m[38;2;104;86;169m╓[0m[38;2;98;77;178m╔[0m[38;2;93;67;188m╗[0m[38;2;88;59;196mφ[0m[38;2;83;51;204m@[0m[38;2;78;42;213mD[0m[38;2;72;32;223m▒[0m[38;2;68;24;231m╠[0m[38;2;66;21;234m╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠[0m[38;2;71;30;225m▒[0m[38;2;77;40;215m▒[0m[38;2;82;49;206mK[0m[38;2;87;57;198mφ[0m[38;2;91;65;190m╗[0m[38;2;97;75;180m╦[0m[38;2;103;84;171m╖[0m[38;2;107;92;163m²[0m[38;2;112;101;154m_[0m[38;2;119;112;143m_[0m
|
|
11
|
-
[38;2;128;128;128m [0m[38;2;106;91;164m\`[0m[38;2;94;70;185m^[0m[38;2;89;62;193m╙[0m[38;2;85;54;201m╙[0m[38;2;80;45;210m╚[0m[38;2;74;35;220m╝[0m[38;2;69;26;229m╠[0m[38;2;66;22;233m╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠[0m[38;2;73;33;222m╝[0m[38;2;79;43;212m╩[0m[38;2;84;52;203m╜[0m[38;2;88;60;195m╙[0m[38;2;93;68;187m^[0m[38;2;100;80;175m\`[0m
|
|
12
|
-
[38;2;128;128;128m [0m[38;2;113;84;152m\`[0m[38;2;103;79;169m'[0m[38;2;95;72;183m"[0m[38;2;87;57;198m╙[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠╠╠╠[0m[38;2;80;46;209m╜[0m[38;2;94;70;185m^[0m[38;2;102;77;175m^[0m[38;2;112;81;162m\`[0m[38;2;115;92;155m\`[0m
|
|
13
|
-
[38;2;128;128;128m [0m[38;2;145;116;107m,[0m[38;2;199;82;45m╠[0m[38;2;207;77;35m▒[0m[38;2;207;77;35m▒╠ [0m[38;2;70;28;227m╠[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠╠╠ [0m[38;2;189;49;97må[0m[38;2;203;32;90m╠[0m[38;2;203;32;90m╠╠[0m[38;2;155;92;114m,[0m
|
|
14
|
-
[38;2;128;128;128m [0m[38;2;175;98;73m╔[0m[38;2;207;77;35m▒[0m[38;2;207;77;35m▒▒▒[0m[38;2;197;83;47m╩ [0m[38;2;98;76;179m[[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠╠[0m[38;2;81;48;207mH [0m[38;2;188;51;98m╚[0m[38;2;203;32;90m╠[0m[38;2;203;32;90m╠╠╠[0m[38;2;183;57;100mH[0m
|
|
15
|
-
[38;2;128;128;128m [0m[38;2;146;116;106m,[0m[38;2;199;82;44m╠[0m[38;2;207;77;35m▒[0m[38;2;207;77;35m▒[0m[38;2;196;84;48m╩[0m[38;2;168;102;81m^ [0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠╠ [0m[38;2;160;87;111m'[0m[38;2;187;52;98m╚[0m[38;2;203;32;90m╠[0m[38;2;203;32;90m╠╠[0m[38;2;156;91;113m,[0m
|
|
16
|
-
[38;2;128;128;128m [0m[38;2;198;83;46m╩[0m[38;2;194;85;50m╩[0m[38;2;167;102;82m^ [0m[38;2;81;46;209m╚[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠╠ [0m[38;2;159;88;112m'[0m[38;2;186;53;98m╚[0m[38;2;197;40;93m╩[0m
|
|
17
|
-
[38;2;128;128;128m [0m[38;2;110;97;158m'[0m[38;2;66;21;234m╠[0m[38;2;66;21;234m╠[0m[38;2;94;69;186mH[0m
|
|
18
|
-
[38;2;128;128;128m [0m[38;2;68;25;230m╠[0m[38;2;66;21;234m╠[0m
|
|
19
|
-
[38;2;128;128;128m [0m[38;2;108;93;162m²[0m[38;2;99;79;176m^[0m`
|
package/src/index.ts
DELETED
package/src/initLogger.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { Logger, LogLevelValue } from '@xylabs/sdk-js'
|
|
2
|
-
import {
|
|
3
|
-
Base,
|
|
4
|
-
ConsoleLogger, isDefined,
|
|
5
|
-
LogLevel, SilentLogger,
|
|
6
|
-
} from '@xylabs/sdk-js'
|
|
7
|
-
import type { BaseConfig } from '@xyo-network/xl1-sdk'
|
|
8
|
-
|
|
9
|
-
export const initLogger = (config: BaseConfig): Logger => {
|
|
10
|
-
let logger: Logger
|
|
11
|
-
if (config.log.silent) {
|
|
12
|
-
logger = new SilentLogger()
|
|
13
|
-
} else {
|
|
14
|
-
let level: LogLevelValue | undefined
|
|
15
|
-
if (isDefined(config.log.logLevel)) {
|
|
16
|
-
const parsed = LogLevel[config.log.logLevel.toLowerCase() as keyof typeof LogLevel]
|
|
17
|
-
if (isDefined(parsed)) level = parsed
|
|
18
|
-
}
|
|
19
|
-
logger = new ConsoleLogger(level)
|
|
20
|
-
}
|
|
21
|
-
Base.defaultLogger = logger
|
|
22
|
-
return logger
|
|
23
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { UsageMeta } from '@xyo-network/xl1-sdk'
|
|
2
|
-
import { isUsageMeta } from '@xyo-network/xl1-sdk'
|
|
3
|
-
import type { Options } from 'yargs'
|
|
4
|
-
import { globalRegistry } from 'zod'
|
|
5
|
-
|
|
6
|
-
const usageMetaToOptions = (meta: UsageMeta): Options => {
|
|
7
|
-
return meta
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const optionsFromGlobalZodRegistry = (): Record<string, Options> => {
|
|
11
|
-
const opts: Record<string, Options> = {}
|
|
12
|
-
for (const schema of Object.values(globalRegistry._map)) {
|
|
13
|
-
if (isUsageMeta(schema)) {
|
|
14
|
-
if (schema.hidden) continue // skip hidden options
|
|
15
|
-
opts[schema.title] = usageMetaToOptions(schema)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return opts
|
|
19
|
-
}
|
package/src/runCLI.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { isDefined } from '@xylabs/sdk-js'
|
|
2
|
-
import {
|
|
3
|
-
contextFromConfigWithoutLocator, locatorsFromConfig, Orchestrator,
|
|
4
|
-
} from '@xyo-network/chain-orchestration'
|
|
5
|
-
import type { ActorConfig, Config } from '@xyo-network/xl1-sdk'
|
|
6
|
-
import { ActorConfigZod, ConfigZod } from '@xyo-network/xl1-sdk'
|
|
7
|
-
import type { Argv } from 'yargs'
|
|
8
|
-
import yargs from 'yargs'
|
|
9
|
-
import { hideBin } from 'yargs/helpers'
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
apiCommand,
|
|
13
|
-
bridgeCommand,
|
|
14
|
-
mempoolCommand,
|
|
15
|
-
producerCommand,
|
|
16
|
-
rewardRedemptionCommand,
|
|
17
|
-
startCommand,
|
|
18
|
-
withDeprecationWarning,
|
|
19
|
-
} from './commands/index.ts'
|
|
20
|
-
import { configMiddleware } from './configMiddleware.ts'
|
|
21
|
-
import { XL1LogoColorizedAscii } from './images.ts'
|
|
22
|
-
import { initLogger } from './initLogger.ts'
|
|
23
|
-
import { optionsFromGlobalZodRegistry } from './optionsFromGlobalZodRegistry.ts'
|
|
24
|
-
|
|
25
|
-
/** Version string injected by Rollup at build time. */
|
|
26
|
-
declare const __VERSION__: string
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* The configuration that will be used throughout the CLI.
|
|
30
|
-
* This is materialized after parsing the command-line arguments,
|
|
31
|
-
* environment variables, and defaults.
|
|
32
|
-
*/
|
|
33
|
-
let configuration: Config
|
|
34
|
-
|
|
35
|
-
const version = isDefined(__VERSION__) ? __VERSION__ : 'unknown'
|
|
36
|
-
|
|
37
|
-
function getConfiguration(): Config {
|
|
38
|
-
return configuration
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function getLocatorsFromConfig(actors: string[], configuration: Config) {
|
|
42
|
-
const actorConfigs: ActorConfig[] = []
|
|
43
|
-
for (const actorName of actors) {
|
|
44
|
-
const existingConfig = configuration.actors.find(actor => actor.name === actorName)
|
|
45
|
-
if (existingConfig) {
|
|
46
|
-
actorConfigs.push(existingConfig)
|
|
47
|
-
} else {
|
|
48
|
-
const actorConfig = ActorConfigZod.loose().parse({ name: actorName })
|
|
49
|
-
actorConfigs.push(actorConfig)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const config = ConfigZod.parse({ ...configuration, actors: actorConfigs })
|
|
54
|
-
|
|
55
|
-
const logger = initLogger(configuration)
|
|
56
|
-
const orchestrator = await Orchestrator.create({ logger })
|
|
57
|
-
const context = await contextFromConfigWithoutLocator(config, logger, 'xl1-cli', version)
|
|
58
|
-
const locators = await locatorsFromConfig(context, config)
|
|
59
|
-
// Handle cancellation (Ctrl+C)
|
|
60
|
-
process.on('SIGINT', () => {
|
|
61
|
-
void (async () => {
|
|
62
|
-
try {
|
|
63
|
-
logger.log('\nSIGINT received. Attempting graceful shutdown...')
|
|
64
|
-
await orchestrator?.stop()
|
|
65
|
-
logger.log('Orchestrator stopped, exiting now.')
|
|
66
|
-
process.exit(0)
|
|
67
|
-
} catch (err) {
|
|
68
|
-
logger.error('Error stopping orchestrator:', err)
|
|
69
|
-
process.exit(1)
|
|
70
|
-
}
|
|
71
|
-
})()
|
|
72
|
-
})
|
|
73
|
-
return { locators, orchestrator }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Main entry point
|
|
77
|
-
export async function runCLI() {
|
|
78
|
-
// Parse command-line arguments using Yargs
|
|
79
|
-
const y = yargs(hideBin(process.argv)) as Argv<Config>
|
|
80
|
-
const argv = y
|
|
81
|
-
.usage(`
|
|
82
|
-
🚀 XL1 Node CLI (${version})
|
|
83
|
-
${XL1LogoColorizedAscii}
|
|
84
|
-
Run various components of the XL1 ecosystem.
|
|
85
|
-
|
|
86
|
-
Usage:
|
|
87
|
-
$0 <command> [options]`)
|
|
88
|
-
.parserConfiguration({
|
|
89
|
-
'dot-notation': true, // foo.bar → { foo: { bar } }
|
|
90
|
-
'parse-numbers': false, // Don't auto-parse numbers to allow strings like "0x1"
|
|
91
|
-
'populate--': true, // Populate -- with all options so we can detected user-supplied vs defaults
|
|
92
|
-
})
|
|
93
|
-
.env('XL1')
|
|
94
|
-
.scriptName('xl1')
|
|
95
|
-
.middleware(async (argv) => {
|
|
96
|
-
await configMiddleware(argv, (config) => {
|
|
97
|
-
configuration = config
|
|
98
|
-
})
|
|
99
|
-
})
|
|
100
|
-
.options(optionsFromGlobalZodRegistry())
|
|
101
|
-
.wrap(y.terminalWidth())
|
|
102
|
-
.command(withDeprecationWarning(apiCommand(getConfiguration, getLocatorsFromConfig)))
|
|
103
|
-
.command(withDeprecationWarning(bridgeCommand(getConfiguration, getLocatorsFromConfig)))
|
|
104
|
-
.command(withDeprecationWarning(mempoolCommand(getConfiguration, getLocatorsFromConfig)))
|
|
105
|
-
.command(withDeprecationWarning(producerCommand(getConfiguration, getLocatorsFromConfig)))
|
|
106
|
-
.command(withDeprecationWarning(rewardRedemptionCommand(getConfiguration, getLocatorsFromConfig)))
|
|
107
|
-
.command(startCommand(getConfiguration, getLocatorsFromConfig))
|
|
108
|
-
.options({
|
|
109
|
-
'config': {
|
|
110
|
-
type: 'string',
|
|
111
|
-
description: 'Path to a config file to use instead of the default search.',
|
|
112
|
-
alias: 'c',
|
|
113
|
-
},
|
|
114
|
-
'dump-config': {
|
|
115
|
-
type: 'boolean',
|
|
116
|
-
description: 'Just process the configuration and print the resolved config to stdout, then exit.',
|
|
117
|
-
default: false,
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
.help()
|
|
121
|
-
.alias('help', 'h')
|
|
122
|
-
.version(version)
|
|
123
|
-
.argv
|
|
124
|
-
|
|
125
|
-
await argv
|
|
126
|
-
}
|
package/src/start.ts
DELETED
package/src/waitForHostPort.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
|
|
3
|
-
export const waitForHostPort = (host: string, port: number): Promise<void> => {
|
|
4
|
-
return new Promise((resolve) => {
|
|
5
|
-
const tryConnect = () => {
|
|
6
|
-
const socket = new net.Socket()
|
|
7
|
-
|
|
8
|
-
socket
|
|
9
|
-
.setTimeout(1000)
|
|
10
|
-
.once('error', () => {
|
|
11
|
-
socket.destroy()
|
|
12
|
-
setTimeout(tryConnect, 500) // retry after 500ms
|
|
13
|
-
})
|
|
14
|
-
.once('timeout', () => {
|
|
15
|
-
socket.destroy()
|
|
16
|
-
setTimeout(tryConnect, 500)
|
|
17
|
-
})
|
|
18
|
-
.connect(port, host, () => {
|
|
19
|
-
socket.end()
|
|
20
|
-
resolve()
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
tryConnect()
|
|
25
|
-
})
|
|
26
|
-
}
|
package/src/xl1.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { start } from './start.ts'
|
|
2
|
-
|
|
3
|
-
start().catch((err) => {
|
|
4
|
-
// If we're in development mode, log the stack trace to the console
|
|
5
|
-
if (process.env.NODE_ENV === 'development') console.error('An error occurred during startup:', err)
|
|
6
|
-
// eslint-disable-next-line unicorn/no-process-exit
|
|
7
|
-
process.exit(1)
|
|
8
|
-
})
|