yini-cli 1.3.4 → 1.4.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/README.md +1 -1
- package/dist/commands/commonFunctions.d.ts +15 -0
- package/dist/commands/commonFunctions.js +76 -0
- package/dist/commands/parseCommand.d.ts +1 -1
- package/dist/commands/parseCommand.js +64 -51
- package/dist/commands/validateCommand.d.ts +6 -1
- package/dist/commands/validateCommand.js +440 -402
- package/dist/descriptions.js +6 -1
- package/dist/globalOptions/helpOption.js +9 -6
- package/dist/index.js +51 -31
- package/dist/utils/string.js +1 -0
- package/package.json +2 -2
package/dist/descriptions.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export const descriptions = {
|
|
2
2
|
yini: 'The official terminal / command-line (CLI) for parsing and validating YINI configuration files.',
|
|
3
3
|
'For-command-parse': 'Parse a YINI file (*.yini) and output the result as JSON or JavaScript.',
|
|
4
|
-
'For-command-validate':
|
|
4
|
+
'For-command-validate': `Validate one or more YINI files.
|
|
5
|
+
|
|
6
|
+
<file> Validate a single file.
|
|
7
|
+
<directory> Validate all .yini files in the directory.
|
|
8
|
+
|
|
9
|
+
You can provide multiple files and directories, separated by spaces.`,
|
|
5
10
|
'For-command-info': 'Display extended information about the YINI CLI environment.',
|
|
6
11
|
};
|
|
@@ -8,7 +8,7 @@ import { getPackageName, getPackageVersion } from '../utils/yiniCliHelpers.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export const getHelpTextBefore = () => {
|
|
10
10
|
return `${getPackageName()} ${getPackageVersion()}
|
|
11
|
-
YINI CLI (
|
|
11
|
+
YINI CLI (by the YINI-lang project)
|
|
12
12
|
|
|
13
13
|
The official terminal / command-line (CLI) for parsing and validating YINI
|
|
14
14
|
configuration files. A config format, inspired by INI, with type-safe values,
|
|
@@ -28,7 +28,8 @@ Quick Examples:
|
|
|
28
28
|
$ yini parse file.yini --json
|
|
29
29
|
$ yini parse file.yini --js
|
|
30
30
|
$ yini parse file.yini -o output.json
|
|
31
|
-
$ yini validate
|
|
31
|
+
$ yini validate config.yini --stats
|
|
32
|
+
$ yini validate . --strict
|
|
32
33
|
|
|
33
34
|
For help with a specific command, use -h or --help. For example:
|
|
34
35
|
$ yini validate --help
|
|
@@ -40,11 +41,13 @@ Example YINI configuration file (config.yini)
|
|
|
40
41
|
title = 'My App'
|
|
41
42
|
items = 10
|
|
42
43
|
debug = ON
|
|
44
|
+
tags = ['web', 'demo', 'prod']
|
|
43
45
|
|
|
44
46
|
^ Server
|
|
45
|
-
host
|
|
46
|
-
port
|
|
47
|
+
host = 'localhost'
|
|
48
|
+
port = 8080
|
|
47
49
|
useTLS = OFF
|
|
50
|
+
limits = { timeout: 30, keepAlive: true }
|
|
48
51
|
|
|
49
52
|
// Sub-section of Server.
|
|
50
53
|
^^ Login
|
|
@@ -52,10 +55,10 @@ Example YINI configuration file (config.yini)
|
|
|
52
55
|
password = 'secret'
|
|
53
56
|
========================================================
|
|
54
57
|
|
|
55
|
-
More
|
|
58
|
+
More information:
|
|
56
59
|
https://github.com/YINI-lang/yini-cli
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
Homepage:
|
|
59
62
|
https://yini-lang.org
|
|
60
63
|
`;
|
|
61
64
|
};
|
package/dist/index.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
//
|
|
3
3
|
// (!) IMPORTANT: Leave the top shebang as the very first line! (otherwise command will break)
|
|
4
4
|
//
|
|
5
|
-
// index.ts
|
|
5
|
+
// src/index.ts
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
|
-
import { Command } from 'commander';
|
|
7
|
+
import { Command, Option } from 'commander';
|
|
8
8
|
import { enableHelpAll } from './cli/helpAll.js';
|
|
9
9
|
import { printInfo } from './commands/infoCommand.js';
|
|
10
10
|
import { parseFile } from './commands/parseCommand.js';
|
|
11
|
-
import {
|
|
11
|
+
import { validateTargets, } from './commands/validateCommand.js';
|
|
12
12
|
import { isDebug, isDev } from './config/env.js';
|
|
13
13
|
import { descriptions as descr } from './descriptions.js';
|
|
14
14
|
import { getHelpTextAfter, getHelpTextBefore, } from './globalOptions/helpOption.js';
|
|
@@ -43,20 +43,21 @@ const program = new Command()
|
|
|
43
43
|
.description(descr.yini)
|
|
44
44
|
// Below will replace all auto-registered items (especially the descriptions starting with a capital and ending with a period).
|
|
45
45
|
.version(getPackageVersion(), '-v, --version', 'Display the version number.')
|
|
46
|
-
.helpOption('-h, --help', 'Display full help for all commands.')
|
|
46
|
+
.helpOption('-h, --help', 'Display full help for all commands.') // Yes, shows help for ALL commands via the enableHelpAll() function.
|
|
47
47
|
.helpCommand('help <command>', 'Display help for a specific command.');
|
|
48
48
|
program.addHelpText('before', getHelpTextBefore());
|
|
49
49
|
program.addHelpText('after', getHelpTextAfter());
|
|
50
50
|
/**
|
|
51
|
-
* The (main/global)
|
|
51
|
+
* The (main/global) options: "--strict, --quiet, --silent"
|
|
52
52
|
*/
|
|
53
53
|
// Suggestions for future: --verbose, --debug, --no-color, --color, --timing, --stdin
|
|
54
54
|
program
|
|
55
55
|
.option('--strict', 'Enable strict parsing mode.')
|
|
56
|
+
.option('--lenient', 'Use lenient mode (this is the default).')
|
|
56
57
|
// .option('-f, --force', 'Continue parsing even if errors occur.')
|
|
57
|
-
.option('-q, --quiet', '
|
|
58
|
-
.option('-s, --silent', 'Suppress
|
|
59
|
-
.option('--verbose', '
|
|
58
|
+
.option('-q, --quiet', 'Suppress successful per-file output; still show failures and final summary.')
|
|
59
|
+
.option('-s, --silent', 'Suppress validation output and use exit code only.')
|
|
60
|
+
.option('--verbose', 'Show extra processing details.')
|
|
60
61
|
.action((options) => {
|
|
61
62
|
debugPrint('Run global options');
|
|
62
63
|
if (isDebug()) {
|
|
@@ -88,10 +89,6 @@ const parseCmd = program
|
|
|
88
89
|
.action((file, options) => {
|
|
89
90
|
const globals = program.opts(); // Global options.
|
|
90
91
|
const mergedOptions = { ...globals, ...options }; // Merge global options with per-command options.
|
|
91
|
-
if (mergedOptions.js && mergedOptions.compact) {
|
|
92
|
-
console.error('Error: --js and --compact cannot be combined.');
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
92
|
debugPrint('Run command "parse"');
|
|
96
93
|
debugPrint('isDebug(): ' + isDebug());
|
|
97
94
|
debugPrint('isDev() : ' + isDev());
|
|
@@ -104,33 +101,54 @@ const parseCmd = program
|
|
|
104
101
|
});
|
|
105
102
|
appendGlobalOptionsTo(parseCmd);
|
|
106
103
|
/**
|
|
107
|
-
* The command: "validate <
|
|
104
|
+
* The command: "validate <fileOrDirectory...>"
|
|
108
105
|
*/
|
|
109
106
|
const validateCmd = program
|
|
110
|
-
.command('validate <
|
|
107
|
+
.command('validate <fileOrDirectory...>')
|
|
111
108
|
.description(descr['For-command-validate'])
|
|
112
|
-
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
// ─────────────────────────────
|
|
110
|
+
// Reporting / behavior
|
|
111
|
+
// ─────────────────────────────
|
|
112
|
+
.option('--warnings-as-errors', 'Treat warnings as errors for exit code purposes.')
|
|
113
|
+
.option('--stats', 'In text mode, stats only shown when file mode validates exactly one file.')
|
|
114
|
+
.addOption(new Option('--format <type>', 'Output format for validation results: text | json')
|
|
115
|
+
.choices(['text', 'json'])
|
|
116
|
+
.default('text'))
|
|
117
|
+
// Execution controls (nice-to-have)
|
|
118
|
+
.option('--fail-fast', 'Stop after first file that fails validation.')
|
|
119
|
+
.option('--max-errors <n>', 'Stop after N total errors (across files).', (v) => {
|
|
120
|
+
const n = Number.parseInt(v, 10);
|
|
121
|
+
if (!Number.isFinite(n) || n < 1) {
|
|
122
|
+
throw new Error('--max-errors must be a positive integer.');
|
|
123
|
+
}
|
|
124
|
+
return n;
|
|
125
|
+
})
|
|
126
|
+
// ─────────────────────────────
|
|
127
|
+
// Input handling
|
|
128
|
+
// ─────────────────────────────
|
|
129
|
+
// Default: recursive (so only expose the negated option)
|
|
130
|
+
.option('--no-recursive', 'Do not scan subdirectories.')
|
|
131
|
+
// ─────────────────────────────
|
|
132
|
+
// Output handling - WAIT WITH THESE
|
|
133
|
+
// ─────────────────────────────
|
|
134
|
+
// .option('-o, --output <file>', 'Write validation report to file.')
|
|
135
|
+
// .option('--overwrite', 'Allow overwriting an existing output file.')
|
|
136
|
+
// .option('--no-overwrite', 'Prevent overwriting an existing output file.')
|
|
137
|
+
.action((fileOrDirectories, options) => {
|
|
138
|
+
const globals = program.opts();
|
|
139
|
+
const mergedOptions = { ...globals, ...options };
|
|
140
|
+
debugPrint('Run command "validate"');
|
|
121
141
|
debugPrint('isDebug(): ' + isDebug());
|
|
122
|
-
debugPrint('isDev()
|
|
123
|
-
|
|
142
|
+
debugPrint('isDev(): ' + isDev());
|
|
143
|
+
// console.log('options:')
|
|
144
|
+
// console.log(options)
|
|
124
145
|
if (isDebug()) {
|
|
125
146
|
console.log('mergedOptions:');
|
|
126
147
|
console.log(toPrettyJSON(mergedOptions));
|
|
127
148
|
}
|
|
128
|
-
if (
|
|
129
|
-
validateFile(file, mergedOptions);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
149
|
+
if (!fileOrDirectories?.length)
|
|
132
150
|
program.help();
|
|
133
|
-
|
|
151
|
+
validateTargets(fileOrDirectories, mergedOptions);
|
|
134
152
|
});
|
|
135
153
|
appendGlobalOptionsTo(validateCmd);
|
|
136
154
|
/**
|
|
@@ -150,4 +168,6 @@ appendGlobalOptionsTo(infoCmd);
|
|
|
150
168
|
// NOTE: Converting YINI files to other formats than json and js.
|
|
151
169
|
// Other format should go into a new CLI-command called 'yini-convert' to not let this command grow too large.
|
|
152
170
|
enableHelpAll(program);
|
|
153
|
-
program.parseAsync()
|
|
171
|
+
// program.parseAsync()
|
|
172
|
+
const normalizedArgv = process.argv.map((arg) => arg === '--no-subdirs' ? '--no-recursive' : arg);
|
|
173
|
+
program.parseAsync(normalizedArgv);
|
package/dist/utils/string.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yini-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Official YINI CLI for validating, parsing, and converting a human-friendly config format with real structure, nested sections, and predictable strict or lenient parsing.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yini",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"commander": "^14.0.1",
|
|
73
73
|
"xmlbuilder2": "^4.0.3",
|
|
74
74
|
"yaml": "^2.8.2",
|
|
75
|
-
"yini-parser": "^1.
|
|
75
|
+
"yini-parser": "^1.5.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@eslint/js": "^9.31.0",
|