@trenskow/arguments-parser 0.2.11 → 0.2.13

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.
Files changed (2) hide show
  1. package/lib/index.js +103 -64
  2. package/package.json +2 -2
package/lib/index.js CHANGED
@@ -23,13 +23,25 @@ plugins.use(() => ({
23
23
  formalize: (schema) => schema
24
24
  }));
25
25
 
26
- const argumentsParser = ({ args = process.argv.slice(2), argvLevel = 0, placeholder = '<>', command, strings = {} } = {}) => {
26
+ const argumentsParser = (
27
+ {
28
+ args = process.argv.slice(2),
29
+ argvLevel = 0,
30
+ placeholder = '<>',
31
+ command,
32
+ strings = {},
33
+ help: {
34
+ usage: helpUsage,
35
+ options: helpOptions,
36
+ } = {}
37
+ } = {}
38
+ ) => {
27
39
 
28
40
  const [ opening, closing ] = placeholder.split('');
29
41
 
30
42
  const base = `${process.argv.slice(1, argvLevel + 2).map(((arg) => basename(arg))).join(' ')}`;
31
43
 
32
- const list = (items) => {
44
+ const list = (print, items) => {
33
45
 
34
46
  const maxLength = Object.keys(items)
35
47
  .reduce((length, key) => Math.max(length, key.length), 0);
@@ -42,18 +54,49 @@ const argumentsParser = ({ args = process.argv.slice(2), argvLevel = 0, placehol
42
54
 
43
55
  };
44
56
 
57
+ if (typeof helpUsage === 'undefined') {
58
+ helpUsage = [
59
+ strings?.help?.usage || 'Usage:',
60
+ base
61
+ ];
62
+ }
63
+
64
+ const printHelp = (error) => {
65
+
66
+ print();
67
+
68
+ print(helpUsage.join(' '));
69
+
70
+ if (helpOptions) {
71
+ print.nn(helpOptions);
72
+ }
73
+
74
+ if (error) {
75
+ print();
76
+ print.bold((strings?.commands?.help?.error || 'Error: <message>')
77
+ .replace('<message>', error.message));
78
+ }
79
+
80
+ print();
81
+
82
+ process.exit(error ? 1 : 0);
83
+
84
+ };
85
+
86
+ const checkHelp = () => {
87
+ if (args[0] === '--help') printHelp();
88
+ };
89
+
45
90
  return {
46
91
  get base() {
47
92
  return base;
48
93
  },
49
94
  command: async (commands) => {
50
95
 
51
- const printHelp = (error) => {
96
+ helpUsage.push(`${opening}${strings?.commands?.help?.placeholder || 'command'}${closing}`);
97
+
98
+ helpOptions = print.toString((print) => {
52
99
 
53
- print();
54
- print((strings?.commands?.help?.usage || 'Usage: <base> <command>')
55
- .replace('<base>', base)
56
- .replace('<command>', `${opening}command${closing}`));
57
100
  print();
58
101
  print(strings?.commands?.help?.available || 'Available commands:');
59
102
  print();
@@ -65,24 +108,15 @@ const argumentsParser = ({ args = process.argv.slice(2), argvLevel = 0, placehol
65
108
 
66
109
  tools.sort((a, b) => a.name > b.name ? 1 : -1);
67
110
 
68
- list(Object.fromEntries(tools
111
+ list(print, Object.fromEntries(tools
69
112
  .map((tool) => [tool.name, tool.description || (strings?.commands?.help?.noDescription || 'No description')])));
70
113
 
71
- if (error) {
72
- print();
73
- print();
74
- print((strings?.commands?.help?.error || 'Error: <message>')
75
- .replace('<message>', error.message));
76
- }
77
-
78
- print();
79
-
80
- process.exit(error ? 1 : 0);
81
-
82
- };
114
+ });
83
115
 
84
116
  if (args.length === 0) printHelp();
85
117
 
118
+ checkHelp();
119
+
86
120
  const tool = caseit(args[0]);
87
121
 
88
122
  if (!commands[tool]) {
@@ -129,29 +163,16 @@ const argumentsParser = ({ args = process.argv.slice(2), argvLevel = 0, placehol
129
163
  .all()
130
164
  .filter((keyPath) => keyPath);
131
165
 
132
- const printHelp = (error) => {
166
+ helpUsage.push(`${opening}${strings?.options?.help?.placeholder || 'options'}${closing}`);
133
167
 
134
- if (typeof options?.command?.description === 'string') {
135
- print();
136
- print(options.command.description);
137
- }
168
+ if (allKeyPaths.length) {
138
169
 
139
- print();
140
- print.nn(
141
- (strings?.options?.help?.usage || 'Usage: <base> <options>')
142
- .replace('<base>', base)
143
- .replace('<options>', `${opening}options${closing}`));
144
-
145
- if (options.help?.postfix) print.nn(options.help.postfix);
146
-
147
- print();
148
-
149
- if (allKeyPaths.length) {
170
+ helpOptions = print.toString((print) => {
150
171
 
151
172
  print();
152
- print(strings?.options?.help?.options || 'Options:');
173
+ print(strings?.options?.help?.title || 'Options:');
153
174
 
154
- list(Object.fromEntries(allKeyPaths
175
+ list(print, Object.fromEntries(allKeyPaths
155
176
  .map((keyPath) => {
156
177
 
157
178
  const keyPathSchema = keyPaths(schema).get(keyPath);
@@ -191,28 +212,10 @@ const argumentsParser = ({ args = process.argv.slice(2), argvLevel = 0, placehol
191
212
 
192
213
  })));
193
214
 
194
- }
195
-
196
- print();
197
-
198
- if (error) {
199
-
200
- (error.errors || [error])
201
- .forEach((error) => {
202
- if (error.keyPath) {
203
- print.err(`--${caseit(error.keyPath.join('.'), 'kebab')}: ${error.message}`);
204
- } else {
205
- print.err(error.message);
206
- }
207
- });
208
-
209
- print();
210
-
211
- }
212
-
213
- process.exit(error ? 1 : 0);
215
+ });
216
+ }
214
217
 
215
- };
218
+ checkHelp();
216
219
 
217
220
  let data = {};
218
221
  let rest = [];
@@ -230,8 +233,6 @@ const argumentsParser = ({ args = process.argv.slice(2), argvLevel = 0, placehol
230
233
 
231
234
  const key = caseit(arg);
232
235
 
233
- if (key === 'help') printHelp();
234
-
235
236
  if (!keyPaths(schema).all().includes(key)) {
236
237
  printHelp(
237
238
  new Error(
@@ -281,9 +282,47 @@ const argumentsParser = ({ args = process.argv.slice(2), argvLevel = 0, placehol
281
282
  });
282
283
 
283
284
  },
284
- pop: async () => {
285
- if (args.length === 0) return;
286
- return args.shift();
285
+ values: async (schema) => {
286
+
287
+ schema = formalize(schema);
288
+
289
+ if (schema.type !== Object) {
290
+ throw new Error('Schema must be an object.');
291
+ }
292
+
293
+ const schemaKeyPaths = keyPaths(schema);
294
+
295
+ const allKeyPaths = schemaKeyPaths.all({ maxDepth: 2 })
296
+ .filter((keyPath) => keyPath);
297
+
298
+ let lastNonRequiredIndex = -1;
299
+
300
+ allKeyPaths
301
+ .forEach((keyPath, idx) => {
302
+
303
+ const schema = schemaKeyPaths.get(keyPath);
304
+
305
+ if (schema.required && idx > lastNonRequiredIndex + 1) {
306
+ throw new Error('Required arguments must come first.');
307
+ }
308
+
309
+ if (schema.type !== String) {
310
+ throw new Error('Schema must be an object of strings.');
311
+ }
312
+
313
+ helpUsage = helpUsage.concat([`${opening}${caseit(keyPath, 'kebab')}${closing}`]);
314
+
315
+ });
316
+
317
+ checkHelp();
318
+
319
+ try {
320
+ return await isvalid(Object.fromEntries(
321
+ allKeyPaths.map((keyPath, idx) => [keyPath, args[idx]])), schema);
322
+ } catch (error) {
323
+ return printHelp(error);
324
+ }
325
+
287
326
  }
288
327
  };
289
328
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trenskow/arguments-parser",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Yet another arguments parser.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "homepage": "https://github.com/trenskow/arguments-parser#readme",
26
26
  "dependencies": {
27
27
  "@trenskow/caseit": "^1.4.6",
28
- "@trenskow/print": "^0.1.6",
28
+ "@trenskow/print": "^0.1.7",
29
29
  "isvalid": "^4.1.27"
30
30
  },
31
31
  "devDependencies": {