@optique/core 1.0.0-dev.1136 → 1.0.0-dev.1155
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 +8 -5
- package/dist/completion.js +8 -5
- package/dist/facade.cjs +61 -0
- package/dist/facade.d.cts +4 -1
- package/dist/facade.d.ts +4 -1
- package/dist/facade.js +61 -0
- package/dist/valueparser.cjs +20 -2
- package/dist/valueparser.d.cts +2 -0
- package/dist/valueparser.d.ts +2 -0
- package/dist/valueparser.js +20 -2
- package/package.json +1 -1
package/dist/completion.cjs
CHANGED
|
@@ -40,6 +40,9 @@ function validateProgramName(programName) {
|
|
|
40
40
|
function encodePattern(pattern) {
|
|
41
41
|
return pattern.replace(/%/g, "%25").replace(/:/g, "%3A");
|
|
42
42
|
}
|
|
43
|
+
function encodeExtensions(extensions) {
|
|
44
|
+
return extensions?.map((ext) => ext.replace(/^\./, "")).join(",") ?? "";
|
|
45
|
+
}
|
|
43
46
|
/**
|
|
44
47
|
* Replaces control characters that would corrupt shell completion protocols.
|
|
45
48
|
* Shell completion formats use tabs as field delimiters and newlines as record
|
|
@@ -211,7 +214,7 @@ complete -F _${programName} -- ${programName}
|
|
|
211
214
|
if (i > 0) yield "\n";
|
|
212
215
|
if (suggestion.kind === "literal") yield `${suggestion.text}`;
|
|
213
216
|
else {
|
|
214
|
-
const extensions = suggestion.extensions
|
|
217
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
215
218
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
216
219
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
217
220
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}`;
|
|
@@ -336,7 +339,7 @@ compdef _${programName.replace(/[^a-zA-Z0-9]/g, "_")} ${programName}
|
|
|
336
339
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
337
340
|
yield `${suggestion.text}\0${description}\0`;
|
|
338
341
|
} else {
|
|
339
|
-
const extensions = suggestion.extensions
|
|
342
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
340
343
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
341
344
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
342
345
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
@@ -508,7 +511,7 @@ complete -c ${programName} -f -a '(${functionName})'
|
|
|
508
511
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
509
512
|
yield `${suggestion.text}\t${description}`;
|
|
510
513
|
} else {
|
|
511
|
-
const extensions = suggestion.extensions
|
|
514
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
512
515
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
513
516
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
514
517
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
@@ -756,7 +759,7 @@ ${functionName}-external
|
|
|
756
759
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
757
760
|
yield `${suggestion.text}\t${description}`;
|
|
758
761
|
} else {
|
|
759
|
-
const extensions = suggestion.extensions
|
|
762
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
760
763
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
761
764
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
762
765
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
@@ -926,7 +929,7 @@ ${escapedArgs ? ` \$completionArgs += @(${escapedArgs})
|
|
|
926
929
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
927
930
|
yield `${suggestion.text}\t${suggestion.text}\t${description}`;
|
|
928
931
|
} else {
|
|
929
|
-
const extensions = suggestion.extensions
|
|
932
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
930
933
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
931
934
|
const description = suggestion.description == null ? "" : sanitizeDescription(require_message.formatMessage(suggestion.description, { colors: false }));
|
|
932
935
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
package/dist/completion.js
CHANGED
|
@@ -40,6 +40,9 @@ function validateProgramName(programName) {
|
|
|
40
40
|
function encodePattern(pattern) {
|
|
41
41
|
return pattern.replace(/%/g, "%25").replace(/:/g, "%3A");
|
|
42
42
|
}
|
|
43
|
+
function encodeExtensions(extensions) {
|
|
44
|
+
return extensions?.map((ext) => ext.replace(/^\./, "")).join(",") ?? "";
|
|
45
|
+
}
|
|
43
46
|
/**
|
|
44
47
|
* Replaces control characters that would corrupt shell completion protocols.
|
|
45
48
|
* Shell completion formats use tabs as field delimiters and newlines as record
|
|
@@ -211,7 +214,7 @@ complete -F _${programName} -- ${programName}
|
|
|
211
214
|
if (i > 0) yield "\n";
|
|
212
215
|
if (suggestion.kind === "literal") yield `${suggestion.text}`;
|
|
213
216
|
else {
|
|
214
|
-
const extensions = suggestion.extensions
|
|
217
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
215
218
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
216
219
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
217
220
|
yield `__FILE__:${suggestion.type}:${extensions}:${pattern}:${hidden}`;
|
|
@@ -336,7 +339,7 @@ compdef _${programName.replace(/[^a-zA-Z0-9]/g, "_")} ${programName}
|
|
|
336
339
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
337
340
|
yield `${suggestion.text}\0${description}\0`;
|
|
338
341
|
} else {
|
|
339
|
-
const extensions = suggestion.extensions
|
|
342
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
340
343
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
341
344
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
342
345
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
@@ -508,7 +511,7 @@ complete -c ${programName} -f -a '(${functionName})'
|
|
|
508
511
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
509
512
|
yield `${suggestion.text}\t${description}`;
|
|
510
513
|
} else {
|
|
511
|
-
const extensions = suggestion.extensions
|
|
514
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
512
515
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
513
516
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
514
517
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
@@ -756,7 +759,7 @@ ${functionName}-external
|
|
|
756
759
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
757
760
|
yield `${suggestion.text}\t${description}`;
|
|
758
761
|
} else {
|
|
759
|
-
const extensions = suggestion.extensions
|
|
762
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
760
763
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
761
764
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
762
765
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
|
@@ -926,7 +929,7 @@ ${escapedArgs ? ` \$completionArgs += @(${escapedArgs})
|
|
|
926
929
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
927
930
|
yield `${suggestion.text}\t${suggestion.text}\t${description}`;
|
|
928
931
|
} else {
|
|
929
|
-
const extensions = suggestion.extensions
|
|
932
|
+
const extensions = encodeExtensions(suggestion.extensions);
|
|
930
933
|
const hidden = suggestion.includeHidden ? "1" : "0";
|
|
931
934
|
const description = suggestion.description == null ? "" : sanitizeDescription(formatMessage(suggestion.description, { colors: false }));
|
|
932
935
|
const pattern = encodePattern(suggestion.pattern ?? "");
|
package/dist/facade.cjs
CHANGED
|
@@ -727,6 +727,61 @@ function validateVersionValue(value$1) {
|
|
|
727
727
|
if (/[\x00-\x1f\x7f]/.test(value$1)) throw new TypeError("Version value must not contain control characters.");
|
|
728
728
|
return value$1;
|
|
729
729
|
}
|
|
730
|
+
/**
|
|
731
|
+
* Escapes control characters in a string for display in error messages.
|
|
732
|
+
*
|
|
733
|
+
* @param value The string to escape.
|
|
734
|
+
* @returns The escaped string with control characters replaced by escape
|
|
735
|
+
* sequences.
|
|
736
|
+
*/
|
|
737
|
+
function escapeControlChars(value$1) {
|
|
738
|
+
return value$1.replace(/[\x00-\x1f\x7f]/g, (ch) => {
|
|
739
|
+
const code = ch.charCodeAt(0);
|
|
740
|
+
switch (code) {
|
|
741
|
+
case 9: return "\\t";
|
|
742
|
+
case 10: return "\\n";
|
|
743
|
+
case 13: return "\\r";
|
|
744
|
+
default: return `\\x${code.toString(16).padStart(2, "0")}`;
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Validates meta option names at runtime.
|
|
750
|
+
*
|
|
751
|
+
* @param names The option names to validate.
|
|
752
|
+
* @param label A human-readable label for error messages (e.g.,
|
|
753
|
+
* `"Help option"`).
|
|
754
|
+
* @throws {TypeError} If the names array is empty, or any name is empty,
|
|
755
|
+
* lacks a valid prefix, or contains whitespace or control characters.
|
|
756
|
+
*/
|
|
757
|
+
function validateOptionNames(names, label) {
|
|
758
|
+
if (names.length === 0) throw new TypeError(`Expected at least one ${label.toLowerCase()} name.`);
|
|
759
|
+
for (const name of names) {
|
|
760
|
+
if (name === "") throw new TypeError(`${label} name must not be empty.`);
|
|
761
|
+
if (/^\s+$/.test(name)) throw new TypeError(`${label} name must not be whitespace-only: "${escapeControlChars(name)}".`);
|
|
762
|
+
if (/[\x00-\x1f\x7f]/.test(name)) throw new TypeError(`${label} name must not contain control characters: "${escapeControlChars(name)}".`);
|
|
763
|
+
if (/\s/.test(name)) throw new TypeError(`${label} name must not contain whitespace: "${escapeControlChars(name)}".`);
|
|
764
|
+
if (!/^(--|[-/+])/.test(name)) throw new TypeError(`${label} name must start with "--", "-", "/", or "+": "${name}".`);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Validates meta command names at runtime.
|
|
769
|
+
*
|
|
770
|
+
* @param names The command names to validate.
|
|
771
|
+
* @param label A human-readable label for error messages (e.g.,
|
|
772
|
+
* `"Help command"`).
|
|
773
|
+
* @throws {TypeError} If the names array is empty, or any name is empty,
|
|
774
|
+
* whitespace-only, or contains whitespace or control characters.
|
|
775
|
+
*/
|
|
776
|
+
function validateCommandNames(names, label) {
|
|
777
|
+
if (names.length === 0) throw new TypeError(`Expected at least one ${label.toLowerCase()} name.`);
|
|
778
|
+
for (const name of names) {
|
|
779
|
+
if (name === "") throw new TypeError(`${label} name must not be empty.`);
|
|
780
|
+
if (/^\s+$/.test(name)) throw new TypeError(`${label} name must not be whitespace-only: "${escapeControlChars(name)}".`);
|
|
781
|
+
if (/[\x00-\x1f\x7f]/.test(name)) throw new TypeError(`${label} name must not contain control characters: "${escapeControlChars(name)}".`);
|
|
782
|
+
if (/\s/.test(name)) throw new TypeError(`${label} name must not contain whitespace: "${escapeControlChars(name)}".`);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
730
785
|
function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsParam) {
|
|
731
786
|
const isProgram = typeof programNameOrArgs !== "string";
|
|
732
787
|
let parser;
|
|
@@ -770,6 +825,12 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
770
825
|
const onCompletion = options.completion?.onShow ?? (() => ({}));
|
|
771
826
|
const onCompletionResult = (code) => onCompletion(code);
|
|
772
827
|
const onErrorResult = (code) => onError(code);
|
|
828
|
+
if (helpOptionConfig?.names) validateOptionNames(helpOptionConfig.names, "Help option");
|
|
829
|
+
if (helpCommandConfig?.names) validateCommandNames(helpCommandConfig.names, "Help command");
|
|
830
|
+
if (versionOptionConfig?.names) validateOptionNames(versionOptionConfig.names, "Version option");
|
|
831
|
+
if (versionCommandConfig?.names) validateCommandNames(versionCommandConfig.names, "Version command");
|
|
832
|
+
if (completionOptionConfig?.names) validateOptionNames(completionOptionConfig.names, "Completion option");
|
|
833
|
+
if (completionCommandConfig?.names) validateCommandNames(completionCommandConfig.names, "Completion command");
|
|
773
834
|
const helpOptionNames = helpOptionConfig?.names ?? ["--help"];
|
|
774
835
|
const helpCommandNames = helpCommandConfig?.names ?? ["help"];
|
|
775
836
|
const versionOptionNames = versionOptionConfig?.names ?? ["--version"];
|
package/dist/facade.d.cts
CHANGED
|
@@ -273,7 +273,10 @@ interface RunOptions<THelp, TError> {
|
|
|
273
273
|
* @returns The parsed result value, or the return value of `onHelp`/`onError`
|
|
274
274
|
* callbacks.
|
|
275
275
|
* @throws {TypeError} If `options.version.value` is not a non-empty string
|
|
276
|
-
* without ASCII control characters
|
|
276
|
+
* without ASCII control characters, or if any meta command/option
|
|
277
|
+
* name is empty, whitespace-only, contains whitespace or control
|
|
278
|
+
* characters, or (for option names) lacks a valid prefix (`--`,
|
|
279
|
+
* `-`, `/`, or `+`).
|
|
277
280
|
* @throws {RunParserError} When parsing fails and no `onError` callback is
|
|
278
281
|
* provided.
|
|
279
282
|
* @since 0.10.0 Added support for {@link Program} objects.
|
package/dist/facade.d.ts
CHANGED
|
@@ -273,7 +273,10 @@ interface RunOptions<THelp, TError> {
|
|
|
273
273
|
* @returns The parsed result value, or the return value of `onHelp`/`onError`
|
|
274
274
|
* callbacks.
|
|
275
275
|
* @throws {TypeError} If `options.version.value` is not a non-empty string
|
|
276
|
-
* without ASCII control characters
|
|
276
|
+
* without ASCII control characters, or if any meta command/option
|
|
277
|
+
* name is empty, whitespace-only, contains whitespace or control
|
|
278
|
+
* characters, or (for option names) lacks a valid prefix (`--`,
|
|
279
|
+
* `-`, `/`, or `+`).
|
|
277
280
|
* @throws {RunParserError} When parsing fails and no `onError` callback is
|
|
278
281
|
* provided.
|
|
279
282
|
* @since 0.10.0 Added support for {@link Program} objects.
|
package/dist/facade.js
CHANGED
|
@@ -727,6 +727,61 @@ function validateVersionValue(value$1) {
|
|
|
727
727
|
if (/[\x00-\x1f\x7f]/.test(value$1)) throw new TypeError("Version value must not contain control characters.");
|
|
728
728
|
return value$1;
|
|
729
729
|
}
|
|
730
|
+
/**
|
|
731
|
+
* Escapes control characters in a string for display in error messages.
|
|
732
|
+
*
|
|
733
|
+
* @param value The string to escape.
|
|
734
|
+
* @returns The escaped string with control characters replaced by escape
|
|
735
|
+
* sequences.
|
|
736
|
+
*/
|
|
737
|
+
function escapeControlChars(value$1) {
|
|
738
|
+
return value$1.replace(/[\x00-\x1f\x7f]/g, (ch) => {
|
|
739
|
+
const code = ch.charCodeAt(0);
|
|
740
|
+
switch (code) {
|
|
741
|
+
case 9: return "\\t";
|
|
742
|
+
case 10: return "\\n";
|
|
743
|
+
case 13: return "\\r";
|
|
744
|
+
default: return `\\x${code.toString(16).padStart(2, "0")}`;
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Validates meta option names at runtime.
|
|
750
|
+
*
|
|
751
|
+
* @param names The option names to validate.
|
|
752
|
+
* @param label A human-readable label for error messages (e.g.,
|
|
753
|
+
* `"Help option"`).
|
|
754
|
+
* @throws {TypeError} If the names array is empty, or any name is empty,
|
|
755
|
+
* lacks a valid prefix, or contains whitespace or control characters.
|
|
756
|
+
*/
|
|
757
|
+
function validateOptionNames(names, label) {
|
|
758
|
+
if (names.length === 0) throw new TypeError(`Expected at least one ${label.toLowerCase()} name.`);
|
|
759
|
+
for (const name of names) {
|
|
760
|
+
if (name === "") throw new TypeError(`${label} name must not be empty.`);
|
|
761
|
+
if (/^\s+$/.test(name)) throw new TypeError(`${label} name must not be whitespace-only: "${escapeControlChars(name)}".`);
|
|
762
|
+
if (/[\x00-\x1f\x7f]/.test(name)) throw new TypeError(`${label} name must not contain control characters: "${escapeControlChars(name)}".`);
|
|
763
|
+
if (/\s/.test(name)) throw new TypeError(`${label} name must not contain whitespace: "${escapeControlChars(name)}".`);
|
|
764
|
+
if (!/^(--|[-/+])/.test(name)) throw new TypeError(`${label} name must start with "--", "-", "/", or "+": "${name}".`);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Validates meta command names at runtime.
|
|
769
|
+
*
|
|
770
|
+
* @param names The command names to validate.
|
|
771
|
+
* @param label A human-readable label for error messages (e.g.,
|
|
772
|
+
* `"Help command"`).
|
|
773
|
+
* @throws {TypeError} If the names array is empty, or any name is empty,
|
|
774
|
+
* whitespace-only, or contains whitespace or control characters.
|
|
775
|
+
*/
|
|
776
|
+
function validateCommandNames(names, label) {
|
|
777
|
+
if (names.length === 0) throw new TypeError(`Expected at least one ${label.toLowerCase()} name.`);
|
|
778
|
+
for (const name of names) {
|
|
779
|
+
if (name === "") throw new TypeError(`${label} name must not be empty.`);
|
|
780
|
+
if (/^\s+$/.test(name)) throw new TypeError(`${label} name must not be whitespace-only: "${escapeControlChars(name)}".`);
|
|
781
|
+
if (/[\x00-\x1f\x7f]/.test(name)) throw new TypeError(`${label} name must not contain control characters: "${escapeControlChars(name)}".`);
|
|
782
|
+
if (/\s/.test(name)) throw new TypeError(`${label} name must not contain whitespace: "${escapeControlChars(name)}".`);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
730
785
|
function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsParam) {
|
|
731
786
|
const isProgram = typeof programNameOrArgs !== "string";
|
|
732
787
|
let parser;
|
|
@@ -770,6 +825,12 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
770
825
|
const onCompletion = options.completion?.onShow ?? (() => ({}));
|
|
771
826
|
const onCompletionResult = (code) => onCompletion(code);
|
|
772
827
|
const onErrorResult = (code) => onError(code);
|
|
828
|
+
if (helpOptionConfig?.names) validateOptionNames(helpOptionConfig.names, "Help option");
|
|
829
|
+
if (helpCommandConfig?.names) validateCommandNames(helpCommandConfig.names, "Help command");
|
|
830
|
+
if (versionOptionConfig?.names) validateOptionNames(versionOptionConfig.names, "Version option");
|
|
831
|
+
if (versionCommandConfig?.names) validateCommandNames(versionCommandConfig.names, "Version command");
|
|
832
|
+
if (completionOptionConfig?.names) validateOptionNames(completionOptionConfig.names, "Completion option");
|
|
833
|
+
if (completionCommandConfig?.names) validateCommandNames(completionCommandConfig.names, "Completion command");
|
|
773
834
|
const helpOptionNames = helpOptionConfig?.names ?? ["--help"];
|
|
774
835
|
const helpCommandNames = helpCommandConfig?.names ?? ["help"];
|
|
775
836
|
const versionOptionNames = versionOptionConfig?.names ?? ["--version"];
|
package/dist/valueparser.cjs
CHANGED
|
@@ -453,10 +453,28 @@ function float(options = {}) {
|
|
|
453
453
|
* object.
|
|
454
454
|
* @param options Configuration options for the URL parser.
|
|
455
455
|
* @returns A {@link ValueParser} that converts string input to `URL` objects.
|
|
456
|
+
* @throws {TypeError} If any `allowedProtocols` entry is not a valid protocol
|
|
457
|
+
* string ending with a colon (e.g., `"https:"`).
|
|
456
458
|
*/
|
|
457
459
|
function url(options = {}) {
|
|
458
|
-
const
|
|
459
|
-
const
|
|
460
|
+
const originalProtocolsList = [];
|
|
461
|
+
const normalizedProtocolsList = [];
|
|
462
|
+
if (options.allowedProtocols != null) {
|
|
463
|
+
const seen = /* @__PURE__ */ new Set();
|
|
464
|
+
for (const protocol of options.allowedProtocols) {
|
|
465
|
+
if (typeof protocol !== "string" || !/^[a-z][a-z0-9+\-.]*:$/i.test(protocol)) {
|
|
466
|
+
const rendered = typeof protocol === "string" ? JSON.stringify(protocol) : String(protocol);
|
|
467
|
+
throw new TypeError(`Each allowed protocol must be a valid protocol ending with a colon (e.g., "https:"), got: ${rendered}.`);
|
|
468
|
+
}
|
|
469
|
+
const normalized = protocol.toLowerCase();
|
|
470
|
+
if (seen.has(normalized)) continue;
|
|
471
|
+
seen.add(normalized);
|
|
472
|
+
originalProtocolsList.push(protocol);
|
|
473
|
+
normalizedProtocolsList.push(normalized);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const originalProtocols = options.allowedProtocols != null ? Object.freeze(originalProtocolsList) : void 0;
|
|
477
|
+
const allowedProtocols = options.allowedProtocols != null ? Object.freeze(normalizedProtocolsList) : void 0;
|
|
460
478
|
const metavar = options.metavar ?? "URL";
|
|
461
479
|
require_nonempty.ensureNonEmptyString(metavar);
|
|
462
480
|
const invalidUrl = options.errors?.invalidUrl;
|
package/dist/valueparser.d.cts
CHANGED
|
@@ -491,6 +491,8 @@ interface UrlOptions {
|
|
|
491
491
|
* object.
|
|
492
492
|
* @param options Configuration options for the URL parser.
|
|
493
493
|
* @returns A {@link ValueParser} that converts string input to `URL` objects.
|
|
494
|
+
* @throws {TypeError} If any `allowedProtocols` entry is not a valid protocol
|
|
495
|
+
* string ending with a colon (e.g., `"https:"`).
|
|
494
496
|
*/
|
|
495
497
|
declare function url(options?: UrlOptions): ValueParser<"sync", URL>;
|
|
496
498
|
/**
|
package/dist/valueparser.d.ts
CHANGED
|
@@ -491,6 +491,8 @@ interface UrlOptions {
|
|
|
491
491
|
* object.
|
|
492
492
|
* @param options Configuration options for the URL parser.
|
|
493
493
|
* @returns A {@link ValueParser} that converts string input to `URL` objects.
|
|
494
|
+
* @throws {TypeError} If any `allowedProtocols` entry is not a valid protocol
|
|
495
|
+
* string ending with a colon (e.g., `"https:"`).
|
|
494
496
|
*/
|
|
495
497
|
declare function url(options?: UrlOptions): ValueParser<"sync", URL>;
|
|
496
498
|
/**
|
package/dist/valueparser.js
CHANGED
|
@@ -453,10 +453,28 @@ function float(options = {}) {
|
|
|
453
453
|
* object.
|
|
454
454
|
* @param options Configuration options for the URL parser.
|
|
455
455
|
* @returns A {@link ValueParser} that converts string input to `URL` objects.
|
|
456
|
+
* @throws {TypeError} If any `allowedProtocols` entry is not a valid protocol
|
|
457
|
+
* string ending with a colon (e.g., `"https:"`).
|
|
456
458
|
*/
|
|
457
459
|
function url(options = {}) {
|
|
458
|
-
const
|
|
459
|
-
const
|
|
460
|
+
const originalProtocolsList = [];
|
|
461
|
+
const normalizedProtocolsList = [];
|
|
462
|
+
if (options.allowedProtocols != null) {
|
|
463
|
+
const seen = /* @__PURE__ */ new Set();
|
|
464
|
+
for (const protocol of options.allowedProtocols) {
|
|
465
|
+
if (typeof protocol !== "string" || !/^[a-z][a-z0-9+\-.]*:$/i.test(protocol)) {
|
|
466
|
+
const rendered = typeof protocol === "string" ? JSON.stringify(protocol) : String(protocol);
|
|
467
|
+
throw new TypeError(`Each allowed protocol must be a valid protocol ending with a colon (e.g., "https:"), got: ${rendered}.`);
|
|
468
|
+
}
|
|
469
|
+
const normalized = protocol.toLowerCase();
|
|
470
|
+
if (seen.has(normalized)) continue;
|
|
471
|
+
seen.add(normalized);
|
|
472
|
+
originalProtocolsList.push(protocol);
|
|
473
|
+
normalizedProtocolsList.push(normalized);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const originalProtocols = options.allowedProtocols != null ? Object.freeze(originalProtocolsList) : void 0;
|
|
477
|
+
const allowedProtocols = options.allowedProtocols != null ? Object.freeze(normalizedProtocolsList) : void 0;
|
|
460
478
|
const metavar = options.metavar ?? "URL";
|
|
461
479
|
ensureNonEmptyString(metavar);
|
|
462
480
|
const invalidUrl = options.errors?.invalidUrl;
|