@optique/core 1.0.0-dev.1438 → 1.0.0-dev.1442
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/dist/usage.cjs +39 -7
- package/dist/usage.d.cts +16 -5
- package/dist/usage.d.ts +16 -5
- package/dist/usage.js +39 -7
- package/package.json +1 -1
package/dist/usage.cjs
CHANGED
|
@@ -181,14 +181,24 @@ function formatUsage(programName, usage, options = {}) {
|
|
|
181
181
|
* sorting terms for better readability, and ensuring consistent structure
|
|
182
182
|
* throughout the usage tree.
|
|
183
183
|
*
|
|
184
|
-
* This function performs
|
|
184
|
+
* This function performs three main operations:
|
|
185
185
|
*
|
|
186
|
-
* 1. *
|
|
186
|
+
* 1. *Stripping*: Removes degenerate terms that would render as empty or
|
|
187
|
+
* malformed output, such as options with no names, commands with empty
|
|
188
|
+
* names, arguments with empty metavars, and container terms (`optional`,
|
|
189
|
+
* `multiple`, `exclusive`) whose top-level terms array is empty after
|
|
190
|
+
* recursive normalization. Exclusive branches representing valid
|
|
191
|
+
* zero-token alternatives (e.g., `conditional()` default branches or
|
|
192
|
+
* `optional(constant(...))`) and empty-value literals are preserved.
|
|
193
|
+
* Only branches that become empty because all their content was
|
|
194
|
+
* malformed are removed.
|
|
195
|
+
*
|
|
196
|
+
* 2. *Flattening*: Recursively processes all usage terms and merges any
|
|
187
197
|
* nested exclusive terms into their parent exclusive term to avoid
|
|
188
198
|
* redundant nesting. For example, an exclusive term containing another
|
|
189
199
|
* exclusive term will have its nested terms flattened into the parent.
|
|
190
200
|
*
|
|
191
|
-
*
|
|
201
|
+
* 3. *Sorting*: Reorders terms to improve readability by placing:
|
|
192
202
|
* - Commands (subcommands) first
|
|
193
203
|
* - Options and other terms in the middle
|
|
194
204
|
* - Positional arguments last (including optional/multiple wrappers around
|
|
@@ -198,11 +208,12 @@ function formatUsage(programName, usage, options = {}) {
|
|
|
198
208
|
* positional arguments and treats them as arguments for sorting purposes.
|
|
199
209
|
*
|
|
200
210
|
* @param usage The usage description to normalize.
|
|
201
|
-
* @returns A normalized usage description with
|
|
202
|
-
* and terms sorted for
|
|
211
|
+
* @returns A normalized usage description with degenerate terms removed,
|
|
212
|
+
* nested exclusive terms flattened, and remaining terms sorted for
|
|
213
|
+
* optimal readability.
|
|
203
214
|
*/
|
|
204
215
|
function normalizeUsage(usage) {
|
|
205
|
-
const terms = usage.map(normalizeUsageTerm);
|
|
216
|
+
const terms = usage.map(normalizeUsageTerm).filter(isNonDegenerateTerm);
|
|
206
217
|
terms.sort((a, b) => {
|
|
207
218
|
const aCmd = a.type === "command";
|
|
208
219
|
const bCmd = b.type === "command";
|
|
@@ -229,7 +240,7 @@ function normalizeUsageTerm(term) {
|
|
|
229
240
|
if (normalized.length >= 1 && normalized[0].type === "exclusive") {
|
|
230
241
|
const rest = normalized.slice(1);
|
|
231
242
|
for (const subUsage of normalized[0].terms) terms.push([...subUsage, ...rest]);
|
|
232
|
-
} else terms.push(normalized);
|
|
243
|
+
} else if (normalized.length > 0 || !containsMalformedLeaf(usage)) terms.push(normalized);
|
|
233
244
|
}
|
|
234
245
|
return {
|
|
235
246
|
type: "exclusive",
|
|
@@ -237,6 +248,27 @@ function normalizeUsageTerm(term) {
|
|
|
237
248
|
};
|
|
238
249
|
} else return term;
|
|
239
250
|
}
|
|
251
|
+
function isNonDegenerateTerm(term) {
|
|
252
|
+
if (term.type === "option") return term.names.length > 0;
|
|
253
|
+
if (term.type === "command") return term.name !== "";
|
|
254
|
+
if (term.type === "argument") return term.metavar.length > 0;
|
|
255
|
+
if (term.type === "optional" || term.type === "multiple" || term.type === "exclusive") return term.terms.length > 0;
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
function containsMalformedLeaf(usage) {
|
|
259
|
+
for (const term of usage) {
|
|
260
|
+
if (term.type === "option" && term.names.length === 0) return true;
|
|
261
|
+
if (term.type === "command" && term.name === "") return true;
|
|
262
|
+
if (term.type === "argument" && term.metavar.length === 0) return true;
|
|
263
|
+
if (term.type === "optional" || term.type === "multiple") {
|
|
264
|
+
if (containsMalformedLeaf(term.terms)) return true;
|
|
265
|
+
}
|
|
266
|
+
if (term.type === "exclusive") {
|
|
267
|
+
for (const branch of term.terms) if (containsMalformedLeaf(branch)) return true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
240
272
|
/**
|
|
241
273
|
* Creates a deep clone of a single {@link UsageTerm}. Recursive term
|
|
242
274
|
* variants (`optional`, `multiple`, `exclusive`) are cloned recursively.
|
package/dist/usage.d.cts
CHANGED
|
@@ -332,14 +332,24 @@ declare function formatUsage(programName: string, usage: Usage, options?: UsageF
|
|
|
332
332
|
* sorting terms for better readability, and ensuring consistent structure
|
|
333
333
|
* throughout the usage tree.
|
|
334
334
|
*
|
|
335
|
-
* This function performs
|
|
335
|
+
* This function performs three main operations:
|
|
336
336
|
*
|
|
337
|
-
* 1. *
|
|
337
|
+
* 1. *Stripping*: Removes degenerate terms that would render as empty or
|
|
338
|
+
* malformed output, such as options with no names, commands with empty
|
|
339
|
+
* names, arguments with empty metavars, and container terms (`optional`,
|
|
340
|
+
* `multiple`, `exclusive`) whose top-level terms array is empty after
|
|
341
|
+
* recursive normalization. Exclusive branches representing valid
|
|
342
|
+
* zero-token alternatives (e.g., `conditional()` default branches or
|
|
343
|
+
* `optional(constant(...))`) and empty-value literals are preserved.
|
|
344
|
+
* Only branches that become empty because all their content was
|
|
345
|
+
* malformed are removed.
|
|
346
|
+
*
|
|
347
|
+
* 2. *Flattening*: Recursively processes all usage terms and merges any
|
|
338
348
|
* nested exclusive terms into their parent exclusive term to avoid
|
|
339
349
|
* redundant nesting. For example, an exclusive term containing another
|
|
340
350
|
* exclusive term will have its nested terms flattened into the parent.
|
|
341
351
|
*
|
|
342
|
-
*
|
|
352
|
+
* 3. *Sorting*: Reorders terms to improve readability by placing:
|
|
343
353
|
* - Commands (subcommands) first
|
|
344
354
|
* - Options and other terms in the middle
|
|
345
355
|
* - Positional arguments last (including optional/multiple wrappers around
|
|
@@ -349,8 +359,9 @@ declare function formatUsage(programName: string, usage: Usage, options?: UsageF
|
|
|
349
359
|
* positional arguments and treats them as arguments for sorting purposes.
|
|
350
360
|
*
|
|
351
361
|
* @param usage The usage description to normalize.
|
|
352
|
-
* @returns A normalized usage description with
|
|
353
|
-
* and terms sorted for
|
|
362
|
+
* @returns A normalized usage description with degenerate terms removed,
|
|
363
|
+
* nested exclusive terms flattened, and remaining terms sorted for
|
|
364
|
+
* optimal readability.
|
|
354
365
|
*/
|
|
355
366
|
declare function normalizeUsage(usage: Usage): Usage;
|
|
356
367
|
/**
|
package/dist/usage.d.ts
CHANGED
|
@@ -332,14 +332,24 @@ declare function formatUsage(programName: string, usage: Usage, options?: UsageF
|
|
|
332
332
|
* sorting terms for better readability, and ensuring consistent structure
|
|
333
333
|
* throughout the usage tree.
|
|
334
334
|
*
|
|
335
|
-
* This function performs
|
|
335
|
+
* This function performs three main operations:
|
|
336
336
|
*
|
|
337
|
-
* 1. *
|
|
337
|
+
* 1. *Stripping*: Removes degenerate terms that would render as empty or
|
|
338
|
+
* malformed output, such as options with no names, commands with empty
|
|
339
|
+
* names, arguments with empty metavars, and container terms (`optional`,
|
|
340
|
+
* `multiple`, `exclusive`) whose top-level terms array is empty after
|
|
341
|
+
* recursive normalization. Exclusive branches representing valid
|
|
342
|
+
* zero-token alternatives (e.g., `conditional()` default branches or
|
|
343
|
+
* `optional(constant(...))`) and empty-value literals are preserved.
|
|
344
|
+
* Only branches that become empty because all their content was
|
|
345
|
+
* malformed are removed.
|
|
346
|
+
*
|
|
347
|
+
* 2. *Flattening*: Recursively processes all usage terms and merges any
|
|
338
348
|
* nested exclusive terms into their parent exclusive term to avoid
|
|
339
349
|
* redundant nesting. For example, an exclusive term containing another
|
|
340
350
|
* exclusive term will have its nested terms flattened into the parent.
|
|
341
351
|
*
|
|
342
|
-
*
|
|
352
|
+
* 3. *Sorting*: Reorders terms to improve readability by placing:
|
|
343
353
|
* - Commands (subcommands) first
|
|
344
354
|
* - Options and other terms in the middle
|
|
345
355
|
* - Positional arguments last (including optional/multiple wrappers around
|
|
@@ -349,8 +359,9 @@ declare function formatUsage(programName: string, usage: Usage, options?: UsageF
|
|
|
349
359
|
* positional arguments and treats them as arguments for sorting purposes.
|
|
350
360
|
*
|
|
351
361
|
* @param usage The usage description to normalize.
|
|
352
|
-
* @returns A normalized usage description with
|
|
353
|
-
* and terms sorted for
|
|
362
|
+
* @returns A normalized usage description with degenerate terms removed,
|
|
363
|
+
* nested exclusive terms flattened, and remaining terms sorted for
|
|
364
|
+
* optimal readability.
|
|
354
365
|
*/
|
|
355
366
|
declare function normalizeUsage(usage: Usage): Usage;
|
|
356
367
|
/**
|
package/dist/usage.js
CHANGED
|
@@ -180,14 +180,24 @@ function formatUsage(programName, usage, options = {}) {
|
|
|
180
180
|
* sorting terms for better readability, and ensuring consistent structure
|
|
181
181
|
* throughout the usage tree.
|
|
182
182
|
*
|
|
183
|
-
* This function performs
|
|
183
|
+
* This function performs three main operations:
|
|
184
184
|
*
|
|
185
|
-
* 1. *
|
|
185
|
+
* 1. *Stripping*: Removes degenerate terms that would render as empty or
|
|
186
|
+
* malformed output, such as options with no names, commands with empty
|
|
187
|
+
* names, arguments with empty metavars, and container terms (`optional`,
|
|
188
|
+
* `multiple`, `exclusive`) whose top-level terms array is empty after
|
|
189
|
+
* recursive normalization. Exclusive branches representing valid
|
|
190
|
+
* zero-token alternatives (e.g., `conditional()` default branches or
|
|
191
|
+
* `optional(constant(...))`) and empty-value literals are preserved.
|
|
192
|
+
* Only branches that become empty because all their content was
|
|
193
|
+
* malformed are removed.
|
|
194
|
+
*
|
|
195
|
+
* 2. *Flattening*: Recursively processes all usage terms and merges any
|
|
186
196
|
* nested exclusive terms into their parent exclusive term to avoid
|
|
187
197
|
* redundant nesting. For example, an exclusive term containing another
|
|
188
198
|
* exclusive term will have its nested terms flattened into the parent.
|
|
189
199
|
*
|
|
190
|
-
*
|
|
200
|
+
* 3. *Sorting*: Reorders terms to improve readability by placing:
|
|
191
201
|
* - Commands (subcommands) first
|
|
192
202
|
* - Options and other terms in the middle
|
|
193
203
|
* - Positional arguments last (including optional/multiple wrappers around
|
|
@@ -197,11 +207,12 @@ function formatUsage(programName, usage, options = {}) {
|
|
|
197
207
|
* positional arguments and treats them as arguments for sorting purposes.
|
|
198
208
|
*
|
|
199
209
|
* @param usage The usage description to normalize.
|
|
200
|
-
* @returns A normalized usage description with
|
|
201
|
-
* and terms sorted for
|
|
210
|
+
* @returns A normalized usage description with degenerate terms removed,
|
|
211
|
+
* nested exclusive terms flattened, and remaining terms sorted for
|
|
212
|
+
* optimal readability.
|
|
202
213
|
*/
|
|
203
214
|
function normalizeUsage(usage) {
|
|
204
|
-
const terms = usage.map(normalizeUsageTerm);
|
|
215
|
+
const terms = usage.map(normalizeUsageTerm).filter(isNonDegenerateTerm);
|
|
205
216
|
terms.sort((a, b) => {
|
|
206
217
|
const aCmd = a.type === "command";
|
|
207
218
|
const bCmd = b.type === "command";
|
|
@@ -228,7 +239,7 @@ function normalizeUsageTerm(term) {
|
|
|
228
239
|
if (normalized.length >= 1 && normalized[0].type === "exclusive") {
|
|
229
240
|
const rest = normalized.slice(1);
|
|
230
241
|
for (const subUsage of normalized[0].terms) terms.push([...subUsage, ...rest]);
|
|
231
|
-
} else terms.push(normalized);
|
|
242
|
+
} else if (normalized.length > 0 || !containsMalformedLeaf(usage)) terms.push(normalized);
|
|
232
243
|
}
|
|
233
244
|
return {
|
|
234
245
|
type: "exclusive",
|
|
@@ -236,6 +247,27 @@ function normalizeUsageTerm(term) {
|
|
|
236
247
|
};
|
|
237
248
|
} else return term;
|
|
238
249
|
}
|
|
250
|
+
function isNonDegenerateTerm(term) {
|
|
251
|
+
if (term.type === "option") return term.names.length > 0;
|
|
252
|
+
if (term.type === "command") return term.name !== "";
|
|
253
|
+
if (term.type === "argument") return term.metavar.length > 0;
|
|
254
|
+
if (term.type === "optional" || term.type === "multiple" || term.type === "exclusive") return term.terms.length > 0;
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
function containsMalformedLeaf(usage) {
|
|
258
|
+
for (const term of usage) {
|
|
259
|
+
if (term.type === "option" && term.names.length === 0) return true;
|
|
260
|
+
if (term.type === "command" && term.name === "") return true;
|
|
261
|
+
if (term.type === "argument" && term.metavar.length === 0) return true;
|
|
262
|
+
if (term.type === "optional" || term.type === "multiple") {
|
|
263
|
+
if (containsMalformedLeaf(term.terms)) return true;
|
|
264
|
+
}
|
|
265
|
+
if (term.type === "exclusive") {
|
|
266
|
+
for (const branch of term.terms) if (containsMalformedLeaf(branch)) return true;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
239
271
|
/**
|
|
240
272
|
* Creates a deep clone of a single {@link UsageTerm}. Recursive term
|
|
241
273
|
* variants (`optional`, `multiple`, `exclusive`) are cloned recursively.
|