go-dev 0.4.2 → 0.5.0
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/LICENSE +20 -20
- package/README.md +243 -230
- package/bin/go-dev +18 -14
- package/package.json +1 -1
- package/src/cli-args.js +83 -0
- package/src/config.js +133 -122
- package/src/dependency-resolver.js +103 -101
- package/src/index.js +9 -4
- package/src/logger.js +47 -0
- package/src/orchestrator.js +180 -171
- package/src/prefix-lines.js +19 -19
- package/src/process-manager.js +308 -306
- package/src/service-colors.js +58 -0
- package/src/services/base.js +63 -51
- package/src/services/cmd.js +237 -148
- package/src/services/docker.js +194 -197
- package/src/terminal-formatting/apply-formatting-codes.js +223 -223
- package/src/terminal-formatting/constants.js +150 -150
- package/src/terminal-formatting/detect-last-formatting.js +10 -10
- package/src/terminal-formatting/extract-formatting-codes.js +26 -26
- package/test/go-dev.yml +84 -0
package/src/cli-args.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses go-dev CLI arguments.
|
|
3
|
+
*
|
|
4
|
+
* Recognizes:
|
|
5
|
+
* <preset> — positional preset name (first non-flag arg)
|
|
6
|
+
* -c <path>, --config <path>, -c=<path>, --config=<path>
|
|
7
|
+
* -l <level>, --log-level <level>, -l=<lvl>, --log-level=<lvl>
|
|
8
|
+
*
|
|
9
|
+
* Flags are only interpreted before the first `--args-for` token. Everything
|
|
10
|
+
* from `--args-for` onward is preserved verbatim in `remaining` so the
|
|
11
|
+
* orchestrator's per-service args parser can consume it untouched.
|
|
12
|
+
*
|
|
13
|
+
* @param {string[]} argv - argv tail (already stripped of node + script path).
|
|
14
|
+
* @returns {{ presetName?: string, configPath?: string, logLevel?: string, remaining: string[] }}
|
|
15
|
+
*/
|
|
16
|
+
function parseCliArgs(argv) {
|
|
17
|
+
let presetName;
|
|
18
|
+
let configPath;
|
|
19
|
+
let logLevel;
|
|
20
|
+
const remaining = [];
|
|
21
|
+
|
|
22
|
+
let i = 0;
|
|
23
|
+
for (; i < argv.length; i++) {
|
|
24
|
+
const arg = argv[i];
|
|
25
|
+
|
|
26
|
+
if (arg === '--args-for') {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (arg === '-c' || arg === '--config') {
|
|
31
|
+
const value = argv[i + 1];
|
|
32
|
+
if (value == null) {
|
|
33
|
+
throw new Error(`'${arg}' flag requires a path argument.`);
|
|
34
|
+
}
|
|
35
|
+
configPath = value;
|
|
36
|
+
i++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (arg.startsWith('--config=')) {
|
|
41
|
+
configPath = arg.slice('--config='.length);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (arg.startsWith('-c=')) {
|
|
45
|
+
configPath = arg.slice('-c='.length);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (arg === '-l' || arg === '--log-level') {
|
|
50
|
+
const value = argv[i + 1];
|
|
51
|
+
if (value == null) {
|
|
52
|
+
throw new Error(`'${arg}' flag requires a level argument (error|warn|info|debug).`);
|
|
53
|
+
}
|
|
54
|
+
logLevel = value;
|
|
55
|
+
i++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (arg.startsWith('--log-level=')) {
|
|
60
|
+
logLevel = arg.slice('--log-level='.length);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (arg.startsWith('-l=')) {
|
|
64
|
+
logLevel = arg.slice('-l='.length);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (presetName == null && !arg.startsWith('-')) {
|
|
69
|
+
presetName = arg;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
remaining.push(arg);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for (; i < argv.length; i++) {
|
|
77
|
+
remaining.push(argv[i]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { presetName, configPath, logLevel, remaining };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = { parseCliArgs };
|
package/src/config.js
CHANGED
|
@@ -1,123 +1,134 @@
|
|
|
1
|
-
const Joi = require('joi');
|
|
2
|
-
const yaml = require('js-yaml');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
|
|
5
|
-
const dependencyEntrySchema = Joi.alternatives().try(
|
|
6
|
-
Joi.string(),
|
|
7
|
-
Joi.object({
|
|
8
|
-
service: Joi.string().required(),
|
|
9
|
-
mode: Joi.string().required()
|
|
10
|
-
})
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
const commandSchema = Joi.array().items(Joi.string().min(1)).min(1);
|
|
14
|
-
const commandObjectSchema = Joi.object({
|
|
15
|
-
command: commandSchema,
|
|
16
|
-
directory: Joi.string().min(1).optional(),
|
|
17
|
-
restartOnError: Joi.boolean().optional(),
|
|
18
|
-
})
|
|
19
|
-
const commandConfigSchema = Joi.alternatives().try(
|
|
20
|
-
commandSchema,
|
|
21
|
-
commandObjectSchema
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Joi.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
1
|
+
const Joi = require('joi');
|
|
2
|
+
const yaml = require('js-yaml');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const dependencyEntrySchema = Joi.alternatives().try(
|
|
6
|
+
Joi.string(),
|
|
7
|
+
Joi.object({
|
|
8
|
+
service: Joi.string().required(),
|
|
9
|
+
mode: Joi.string().required()
|
|
10
|
+
})
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const commandSchema = Joi.array().items(Joi.string().min(1)).min(1);
|
|
14
|
+
const commandObjectSchema = Joi.object({
|
|
15
|
+
command: commandSchema,
|
|
16
|
+
directory: Joi.string().min(1).optional(),
|
|
17
|
+
restartOnError: Joi.boolean().optional(),
|
|
18
|
+
})
|
|
19
|
+
const commandConfigSchema = Joi.alternatives().try(
|
|
20
|
+
commandSchema,
|
|
21
|
+
commandObjectSchema
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const serviceRefSchema = Joi.object({
|
|
25
|
+
service: Joi.string().min(1).required(),
|
|
26
|
+
mode: Joi.string().min(1).optional(),
|
|
27
|
+
});
|
|
28
|
+
const preCommandConfigSchema = Joi.alternatives().try(
|
|
29
|
+
commandSchema,
|
|
30
|
+
commandObjectSchema,
|
|
31
|
+
serviceRefSchema,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const cmdServiceConfigSchema = Joi.object({
|
|
35
|
+
type: Joi.string().valid('cmd').required(),
|
|
36
|
+
preCommands: Joi.array().items(preCommandConfigSchema).default([]),
|
|
37
|
+
commands: Joi.alternatives().try(
|
|
38
|
+
commandConfigSchema,
|
|
39
|
+
Joi.array().items(commandObjectSchema).min(1)
|
|
40
|
+
),
|
|
41
|
+
defaultCommand: Joi.string().default('start'),
|
|
42
|
+
directory: Joi.string(),
|
|
43
|
+
dependencies: Joi.array().items(dependencyEntrySchema).default([]),
|
|
44
|
+
healthCheck: Joi.boolean().default(false)
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const dockerServiceConfigSchema = Joi.object({
|
|
48
|
+
type: Joi.string().valid('docker').required(),
|
|
49
|
+
service: Joi.string().required(),
|
|
50
|
+
composeFile: Joi.string().default('docker-compose.yml'),
|
|
51
|
+
dependencies: Joi.array().items(dependencyEntrySchema).default([]),
|
|
52
|
+
healthCheck: Joi.boolean().default(true)
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const serviceSchema = Joi.alternatives().try(
|
|
56
|
+
cmdServiceConfigSchema,
|
|
57
|
+
dockerServiceConfigSchema,
|
|
58
|
+
Joi.object({
|
|
59
|
+
type: Joi.string().valid('hybrid').required(),
|
|
60
|
+
defaultMode: Joi.string(),
|
|
61
|
+
modes: Joi.object().pattern(
|
|
62
|
+
Joi.string(),
|
|
63
|
+
Joi.alternatives().try(
|
|
64
|
+
cmdServiceConfigSchema,
|
|
65
|
+
dockerServiceConfigSchema
|
|
66
|
+
)
|
|
67
|
+
).min(2).required()
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const configSchema = Joi.object({
|
|
72
|
+
serviceArgsKeyword: Joi.string().min(1).optional(),
|
|
73
|
+
logLevel: Joi.string().valid('error', 'warn', 'info', 'debug').optional(),
|
|
74
|
+
services: Joi.object().pattern(Joi.string(), serviceSchema).required(),
|
|
75
|
+
presets: Joi.object().pattern(
|
|
76
|
+
Joi.string(),
|
|
77
|
+
Joi.object({
|
|
78
|
+
services: Joi.array().items(Joi.string()).required(),
|
|
79
|
+
modes: Joi.object().pattern(Joi.string(), Joi.string()).default({})
|
|
80
|
+
})
|
|
81
|
+
).default({})
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const possibleNames = [
|
|
85
|
+
'go-dev'
|
|
86
|
+
].flatMap(baseName => {
|
|
87
|
+
return [
|
|
88
|
+
baseName,
|
|
89
|
+
`.${baseName}`
|
|
90
|
+
];
|
|
91
|
+
}).flatMap(baseName => {
|
|
92
|
+
return [
|
|
93
|
+
baseName,
|
|
94
|
+
`${baseName}.config`
|
|
95
|
+
];
|
|
96
|
+
}).flatMap(baseName => {
|
|
97
|
+
return [
|
|
98
|
+
`${baseName}.yml`,
|
|
99
|
+
`${baseName}.yaml`
|
|
100
|
+
];
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
function findConfigFile() {
|
|
104
|
+
for (const name of possibleNames) {
|
|
105
|
+
if (fs.existsSync(name)) {
|
|
106
|
+
return name;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
throw new Error(`No config file found. Expected one of: ${possibleNames.join(', ')}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function loadConfig(configPath) {
|
|
114
|
+
if (!configPath) {
|
|
115
|
+
configPath = findConfigFile();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!fs.existsSync(configPath)) {
|
|
119
|
+
throw new Error(`Config file not found: ${configPath}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
123
|
+
const config = yaml.load(configContent);
|
|
124
|
+
|
|
125
|
+
const { error, value } = configSchema.validate(config);
|
|
126
|
+
|
|
127
|
+
if (error) {
|
|
128
|
+
throw new Error(`Invalid config: ${error.message}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
|
|
123
134
|
module.exports = { loadConfig };
|
|
@@ -1,102 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
1
|
+
const log = require('./logger');
|
|
2
|
+
|
|
3
|
+
function resolveServiceExecutionGraph(config, presetName) {
|
|
4
|
+
const preset = config.presets[presetName];
|
|
5
|
+
if (!preset) {
|
|
6
|
+
throw new Error(`Preset '${presetName}' not found in configuration.`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const services = [];
|
|
10
|
+
const dependencies = [];
|
|
11
|
+
|
|
12
|
+
for (const serviceName of preset.services) {
|
|
13
|
+
addService(
|
|
14
|
+
serviceName,
|
|
15
|
+
preset.modes[serviceName],
|
|
16
|
+
null,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return { dependencies, services };
|
|
21
|
+
|
|
22
|
+
function addService(serviceName, mode, dependentService) {
|
|
23
|
+
const service = config.services[serviceName];
|
|
24
|
+
if (service == null) {
|
|
25
|
+
throw new Error(`Service named '${serviceName}' not found in configuration.`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (dependentService != null) {
|
|
29
|
+
const existingService = services.find(({ name }) => {
|
|
30
|
+
return name === serviceName;
|
|
31
|
+
});
|
|
32
|
+
if (existingService != null) {
|
|
33
|
+
log.warn(
|
|
34
|
+
`Ignoring dependency '${serviceName}' for '${dependentService}' because it is flagged to be run as service in mode '${existingService.mode}'.`
|
|
35
|
+
);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
const existingDependencyIndex = dependencies.findIndex(({ name }) => {
|
|
40
|
+
return name === serviceName;
|
|
41
|
+
});
|
|
42
|
+
if (existingDependencyIndex >= 0) {
|
|
43
|
+
log.warn(
|
|
44
|
+
`Removing service '${serviceName}' from dependencies because it is flagged to be run as service in mode '${dependencies[existingDependencyIndex].mode}'.`
|
|
45
|
+
);
|
|
46
|
+
dependencies.splice(existingDependencyIndex, 1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
mode = (service.type === 'hybrid' ?
|
|
51
|
+
mode ?? service.defaultMode ?? 'dev' :
|
|
52
|
+
mode ?? 'dev'
|
|
53
|
+
);
|
|
54
|
+
const serviceConfig = (service.type === 'hybrid' ?
|
|
55
|
+
service.modes[mode] :
|
|
56
|
+
(mode === 'dev' ? service : undefined)
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
if (serviceConfig == null) {
|
|
60
|
+
throw new Error(`Mode named '${mode}' not found in service '${serviceName}'.`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (dependentService == null) {
|
|
64
|
+
services.push({
|
|
65
|
+
name: serviceName,
|
|
66
|
+
mode,
|
|
67
|
+
config: serviceConfig,
|
|
68
|
+
});
|
|
69
|
+
} else {
|
|
70
|
+
dependencies.unshift({
|
|
71
|
+
name: serviceName,
|
|
72
|
+
mode,
|
|
73
|
+
config: serviceConfig,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
for (let index = serviceConfig.dependencies.length - 1; index >= 0; index--) {
|
|
78
|
+
const dependency = serviceConfig.dependencies[index];
|
|
79
|
+
const {
|
|
80
|
+
service: dependencyName,
|
|
81
|
+
mode: dependencyMode,
|
|
82
|
+
} = (typeof dependency === 'string' ?
|
|
83
|
+
{ service: dependency, mode: 'dev' } :
|
|
84
|
+
dependency
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const existingDependencyIndex = dependencies.find(({ name }) => {
|
|
88
|
+
return name === dependencyName;
|
|
89
|
+
});
|
|
90
|
+
if (existingDependencyIndex != null) {
|
|
91
|
+
log.warn(`Skipping dependency '${dependencyName}' for '${serviceName}' because it's already present in dependencies list.`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
addService(
|
|
96
|
+
dependencyName,
|
|
97
|
+
dependencyMode,
|
|
98
|
+
serviceName,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
102
104
|
module.exports = { resolveServiceExecutionGraph };
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
const Orchestrator = require('./orchestrator');
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const Orchestrator = require('./orchestrator');
|
|
2
|
+
const { parseCliArgs } = require('./cli-args');
|
|
3
|
+
|
|
4
|
+
const { presetName, configPath, logLevel, remaining } = parseCliArgs(process.argv.slice(2));
|
|
5
|
+
|
|
6
|
+
process.argv = [process.argv[0], process.argv[1], presetName, ...remaining];
|
|
7
|
+
|
|
8
|
+
const orchestrator = new Orchestrator(configPath, { logLevel });
|
|
9
|
+
orchestrator.start(presetName);
|
package/src/logger.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const LEVELS = Object.freeze({
|
|
2
|
+
error: 0,
|
|
3
|
+
warn: 1,
|
|
4
|
+
info: 2,
|
|
5
|
+
debug: 3,
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
let currentLevel = LEVELS.info;
|
|
9
|
+
|
|
10
|
+
function setLogLevel(name) {
|
|
11
|
+
if (!Object.prototype.hasOwnProperty.call(LEVELS, name)) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`Unknown log level '${name}'. Expected one of: ${Object.keys(LEVELS).join(', ')}.`,
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
currentLevel = LEVELS[name];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getLogLevel() {
|
|
20
|
+
return Object.keys(LEVELS).find(name => LEVELS[name] === currentLevel);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function error(...args) {
|
|
24
|
+
if (currentLevel >= LEVELS.error) console.error(...args);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function warn(...args) {
|
|
28
|
+
if (currentLevel >= LEVELS.warn) console.warn(...args);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function info(...args) {
|
|
32
|
+
if (currentLevel >= LEVELS.info) console.log(...args);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function debug(...args) {
|
|
36
|
+
if (currentLevel >= LEVELS.debug) console.log(...args);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
LEVELS,
|
|
41
|
+
setLogLevel,
|
|
42
|
+
getLogLevel,
|
|
43
|
+
error,
|
|
44
|
+
warn,
|
|
45
|
+
info,
|
|
46
|
+
debug,
|
|
47
|
+
};
|