@optique/core 1.0.0-dev.1116 → 1.0.0-dev.1129
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/completion.cjs +20 -9
- package/dist/completion.js +20 -9
- package/dist/facade.cjs +18 -1
- package/dist/facade.d.cts +2 -0
- package/dist/facade.d.ts +2 -0
- package/dist/facade.js +18 -1
- package/package.json +1 -1
package/dist/completion.cjs
CHANGED
|
@@ -41,6 +41,17 @@ function encodePattern(pattern) {
|
|
|
41
41
|
return pattern.replace(/%/g, "%25").replace(/:/g, "%3A");
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
+
* Replaces control characters that would corrupt shell completion protocols.
|
|
45
|
+
* Shell completion formats use tabs as field delimiters and newlines as record
|
|
46
|
+
* delimiters. Null bytes are used as delimiters in zsh's format.
|
|
47
|
+
* @param description The description string to sanitize.
|
|
48
|
+
* @returns The sanitized description with control characters replaced by spaces.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
function sanitizeDescription(description) {
|
|
52
|
+
return description.replace(/[\t\n\r\0]/g, " ");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
44
55
|
* The Bash shell completion generator.
|
|
45
56
|
* @since 0.6.0
|
|
46
57
|
*/
|
|
@@ -183,7 +194,7 @@ function _${programName} () {
|
|
|
183
194
|
done < <(${programName} ${escapedArgs} "\${prev[@]}" "$current" 2>/dev/null)
|
|
184
195
|
}
|
|
185
196
|
|
|
186
|
-
complete -F _${programName} ${programName}
|
|
197
|
+
complete -F _${programName} -- ${programName}
|
|
187
198
|
`;
|
|
188
199
|
},
|
|
189
200
|
*encodeSuggestions(suggestions) {
|
|
@@ -314,12 +325,12 @@ compdef _${programName.replace(/[^a-zA-Z0-9]/g, "_")} ${programName}
|
|
|
314
325
|
},
|
|
315
326
|
*encodeSuggestions(suggestions) {
|
|
316
327
|
for (const suggestion of suggestions) if (suggestion.kind === "literal") {
|
|
317
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
328
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
318
329
|
yield `${suggestion.text}\0${description}\0`;
|
|
319
330
|
} else {
|
|
320
331
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
321
332
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
322
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
333
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
323
334
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
324
335
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\0${description}\0`;
|
|
325
336
|
}
|
|
@@ -482,12 +493,12 @@ complete -c ${programName} -f -a '(${functionName})'
|
|
|
482
493
|
for (const suggestion of suggestions) {
|
|
483
494
|
if (i > 0) yield "\n";
|
|
484
495
|
if (suggestion.kind === "literal") {
|
|
485
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
496
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
486
497
|
yield `${suggestion.text}\t${description}`;
|
|
487
498
|
} else {
|
|
488
499
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
489
500
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
490
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
501
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
491
502
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
492
503
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\t${description}`;
|
|
493
504
|
}
|
|
@@ -726,12 +737,12 @@ ${functionName}-external
|
|
|
726
737
|
for (const suggestion of suggestions) {
|
|
727
738
|
if (i > 0) yield "\n";
|
|
728
739
|
if (suggestion.kind === "literal") {
|
|
729
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
740
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
730
741
|
yield `${suggestion.text}\t${description}`;
|
|
731
742
|
} else {
|
|
732
743
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
733
744
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
734
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
745
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
735
746
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
736
747
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\t${description}`;
|
|
737
748
|
}
|
|
@@ -896,12 +907,12 @@ ${escapedArgs ? ` \$completionArgs += @(${escapedArgs})
|
|
|
896
907
|
for (const suggestion of suggestions) {
|
|
897
908
|
if (i > 0) yield "\n";
|
|
898
909
|
if (suggestion.kind === "literal") {
|
|
899
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
910
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
900
911
|
yield `${suggestion.text}\t${suggestion.text}\t${description}`;
|
|
901
912
|
} else {
|
|
902
913
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
903
914
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
904
|
-
const description = suggestion.description == null ? "" : require_message.formatMessage(suggestion.description, { colors: false });
|
|
915
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
905
916
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
906
917
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\t[file]\t${description}`;
|
|
907
918
|
}
|
package/dist/completion.js
CHANGED
|
@@ -41,6 +41,17 @@ function encodePattern(pattern) {
|
|
|
41
41
|
return pattern.replace(/%/g, "%25").replace(/:/g, "%3A");
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
+
* Replaces control characters that would corrupt shell completion protocols.
|
|
45
|
+
* Shell completion formats use tabs as field delimiters and newlines as record
|
|
46
|
+
* delimiters. Null bytes are used as delimiters in zsh's format.
|
|
47
|
+
* @param description The description string to sanitize.
|
|
48
|
+
* @returns The sanitized description with control characters replaced by spaces.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
function sanitizeDescription(description) {
|
|
52
|
+
return description.replace(/[\t\n\r\0]/g, " ");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
44
55
|
* The Bash shell completion generator.
|
|
45
56
|
* @since 0.6.0
|
|
46
57
|
*/
|
|
@@ -183,7 +194,7 @@ function _${programName} () {
|
|
|
183
194
|
done < <(${programName} ${escapedArgs} "\${prev[@]}" "$current" 2>/dev/null)
|
|
184
195
|
}
|
|
185
196
|
|
|
186
|
-
complete -F _${programName} ${programName}
|
|
197
|
+
complete -F _${programName} -- ${programName}
|
|
187
198
|
`;
|
|
188
199
|
},
|
|
189
200
|
*encodeSuggestions(suggestions) {
|
|
@@ -314,12 +325,12 @@ compdef _${programName.replace(/[^a-zA-Z0-9]/g, "_")} ${programName}
|
|
|
314
325
|
},
|
|
315
326
|
*encodeSuggestions(suggestions) {
|
|
316
327
|
for (const suggestion of suggestions) if (suggestion.kind === "literal") {
|
|
317
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
328
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
318
329
|
yield `${suggestion.text}\0${description}\0`;
|
|
319
330
|
} else {
|
|
320
331
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
321
332
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
322
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
333
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
323
334
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
324
335
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\0${description}\0`;
|
|
325
336
|
}
|
|
@@ -482,12 +493,12 @@ complete -c ${programName} -f -a '(${functionName})'
|
|
|
482
493
|
for (const suggestion of suggestions) {
|
|
483
494
|
if (i > 0) yield "\n";
|
|
484
495
|
if (suggestion.kind === "literal") {
|
|
485
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
496
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
486
497
|
yield `${suggestion.text}\t${description}`;
|
|
487
498
|
} else {
|
|
488
499
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
489
500
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
490
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
501
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
491
502
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
492
503
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\t${description}`;
|
|
493
504
|
}
|
|
@@ -726,12 +737,12 @@ ${functionName}-external
|
|
|
726
737
|
for (const suggestion of suggestions) {
|
|
727
738
|
if (i > 0) yield "\n";
|
|
728
739
|
if (suggestion.kind === "literal") {
|
|
729
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
740
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
730
741
|
yield `${suggestion.text}\t${description}`;
|
|
731
742
|
} else {
|
|
732
743
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
733
744
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
734
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
745
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
735
746
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
736
747
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\t${description}`;
|
|
737
748
|
}
|
|
@@ -896,12 +907,12 @@ ${escapedArgs ? ` \$completionArgs += @(${escapedArgs})
|
|
|
896
907
|
for (const suggestion of suggestions) {
|
|
897
908
|
if (i > 0) yield "\n";
|
|
898
909
|
if (suggestion.kind === "literal") {
|
|
899
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
910
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
900
911
|
yield `${suggestion.text}\t${suggestion.text}\t${description}`;
|
|
901
912
|
} else {
|
|
902
913
|
const extensions = suggestion.extensions?.join(",") || "";
|
|
903
914
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
904
|
-
const description = suggestion.description == null ? "" : formatMessage(suggestion.description, { colors: false });
|
|
915
|
+
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
905
916
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
906
917
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}\t[file]\t${description}`;
|
|
907
918
|
}
|
package/dist/facade.cjs
CHANGED
|
@@ -710,6 +710,23 @@ function handleCompletion(completionArgs, programName, parser, completionParser,
|
|
|
710
710
|
return callOnCompletion(0);
|
|
711
711
|
});
|
|
712
712
|
}
|
|
713
|
+
/**
|
|
714
|
+
* Validates the configured version value.
|
|
715
|
+
*
|
|
716
|
+
* @param value Runtime version value from configuration.
|
|
717
|
+
* @returns The validated version string.
|
|
718
|
+
* @throws {TypeError} If the value is not a string, is empty, or contains
|
|
719
|
+
* ASCII control characters.
|
|
720
|
+
*/
|
|
721
|
+
function validateVersionValue(value$1) {
|
|
722
|
+
if (typeof value$1 !== "string") {
|
|
723
|
+
const type = Array.isArray(value$1) ? "array" : typeof value$1;
|
|
724
|
+
throw new TypeError(`Expected version value to be a string, but got ${type}.`);
|
|
725
|
+
}
|
|
726
|
+
if (value$1 === "") throw new TypeError("Version value must not be empty.");
|
|
727
|
+
if (/[\x00-\x1f\x7f]/.test(value$1)) throw new TypeError("Version value must not contain control characters.");
|
|
728
|
+
return value$1;
|
|
729
|
+
}
|
|
713
730
|
function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsParam) {
|
|
714
731
|
const isProgram = typeof programNameOrArgs !== "string";
|
|
715
732
|
let parser;
|
|
@@ -746,7 +763,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
746
763
|
const onHelp = options.help?.onShow ?? (() => ({}));
|
|
747
764
|
const versionCommandConfig = norm(options.version?.command);
|
|
748
765
|
const versionOptionConfig = norm(options.version?.option);
|
|
749
|
-
const versionValue = options.version
|
|
766
|
+
const versionValue = options.version ? validateVersionValue(options.version.value) : void 0;
|
|
750
767
|
const onVersion = options.version?.onShow ?? (() => ({}));
|
|
751
768
|
const completionCommandConfig = norm(options.completion?.command);
|
|
752
769
|
const completionOptionConfig = norm(options.completion?.option);
|
package/dist/facade.d.cts
CHANGED
|
@@ -272,6 +272,8 @@ interface RunOptions<THelp, TError> {
|
|
|
272
272
|
* @param options Configuration options for output formatting and callbacks.
|
|
273
273
|
* @returns The parsed result value, or the return value of `onHelp`/`onError`
|
|
274
274
|
* callbacks.
|
|
275
|
+
* @throws {TypeError} If `options.version.value` is not a non-empty string
|
|
276
|
+
* without ASCII control characters.
|
|
275
277
|
* @throws {RunParserError} When parsing fails and no `onError` callback is
|
|
276
278
|
* provided.
|
|
277
279
|
* @since 0.10.0 Added support for {@link Program} objects.
|
package/dist/facade.d.ts
CHANGED
|
@@ -272,6 +272,8 @@ interface RunOptions<THelp, TError> {
|
|
|
272
272
|
* @param options Configuration options for output formatting and callbacks.
|
|
273
273
|
* @returns The parsed result value, or the return value of `onHelp`/`onError`
|
|
274
274
|
* callbacks.
|
|
275
|
+
* @throws {TypeError} If `options.version.value` is not a non-empty string
|
|
276
|
+
* without ASCII control characters.
|
|
275
277
|
* @throws {RunParserError} When parsing fails and no `onError` callback is
|
|
276
278
|
* provided.
|
|
277
279
|
* @since 0.10.0 Added support for {@link Program} objects.
|
package/dist/facade.js
CHANGED
|
@@ -710,6 +710,23 @@ function handleCompletion(completionArgs, programName, parser, completionParser,
|
|
|
710
710
|
return callOnCompletion(0);
|
|
711
711
|
});
|
|
712
712
|
}
|
|
713
|
+
/**
|
|
714
|
+
* Validates the configured version value.
|
|
715
|
+
*
|
|
716
|
+
* @param value Runtime version value from configuration.
|
|
717
|
+
* @returns The validated version string.
|
|
718
|
+
* @throws {TypeError} If the value is not a string, is empty, or contains
|
|
719
|
+
* ASCII control characters.
|
|
720
|
+
*/
|
|
721
|
+
function validateVersionValue(value$1) {
|
|
722
|
+
if (typeof value$1 !== "string") {
|
|
723
|
+
const type = Array.isArray(value$1) ? "array" : typeof value$1;
|
|
724
|
+
throw new TypeError(`Expected version value to be a string, but got ${type}.`);
|
|
725
|
+
}
|
|
726
|
+
if (value$1 === "") throw new TypeError("Version value must not be empty.");
|
|
727
|
+
if (/[\x00-\x1f\x7f]/.test(value$1)) throw new TypeError("Version value must not contain control characters.");
|
|
728
|
+
return value$1;
|
|
729
|
+
}
|
|
713
730
|
function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsParam) {
|
|
714
731
|
const isProgram = typeof programNameOrArgs !== "string";
|
|
715
732
|
let parser;
|
|
@@ -746,7 +763,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
746
763
|
const onHelp = options.help?.onShow ?? (() => ({}));
|
|
747
764
|
const versionCommandConfig = norm(options.version?.command);
|
|
748
765
|
const versionOptionConfig = norm(options.version?.option);
|
|
749
|
-
const versionValue = options.version
|
|
766
|
+
const versionValue = options.version ? validateVersionValue(options.version.value) : void 0;
|
|
750
767
|
const onVersion = options.version?.onShow ?? (() => ({}));
|
|
751
768
|
const completionCommandConfig = norm(options.completion?.command);
|
|
752
769
|
const completionOptionConfig = norm(options.completion?.option);
|