zod-opts
Version:
node.js CLI option parser / validator using Zod
81 lines • 3.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.assertNever = exports.validateParamOptionsAndPositionalArguments = exports.errorExit = exports.findDuplicateValues = exports.uniq = void 0;
const zod_1 = require("zod");
function uniq(array) {
return [...new Set(array)];
}
exports.uniq = uniq;
function findDuplicateValues(array) {
return array.filter((e, i, a) => a.indexOf(e) !== i);
}
exports.findDuplicateValues = findDuplicateValues;
function errorExit(parseResult, version = "none") {
const { type, help, exitCode } = parseResult;
if (type === "help") {
console.log(help); // eslint-disable-line no-console
}
else if (type === "version") {
console.log(version); // eslint-disable-line no-console
}
else {
console.error(`${parseResult.error.message}\n`); // eslint-disable-line no-console
console.error(help); // eslint-disable-line no-console
}
process.exit(exitCode);
}
exports.errorExit = errorExit;
const IdRegexStr = "^[A-Za-z0-9_]+[A-Za-z0-9_-]*$";
const IdSchema = zod_1.z.string().regex(new RegExp(IdRegexStr)).max(256);
const OptionAliasRegexStr = "^[A-Za-z0-9_]+$";
const OptionAliasSchema = zod_1.z
.string()
.regex(new RegExp(OptionAliasRegexStr))
.max(10);
function validateParamOption(name, { alias }) {
if (!IdSchema.safeParse(name).success) {
throw new Error(`Invalid option name. Supported pattern is /${IdRegexStr}/: ${name}`);
}
if (alias !== undefined && !OptionAliasSchema.safeParse(alias).success) {
throw new Error(`Invalid option alias. Supported pattern is /${OptionAliasRegexStr}/: ${alias}`);
}
}
function validateParamPositionalArg({ name }) {
if (!IdSchema.safeParse(name).success) {
throw new Error(`Invalid positional argument name. Supported pattern is /${IdRegexStr}/: ${name}`);
}
}
function checkForDuplicateOptionNames(options) {
const duplicateName = findDuplicateValues(Object.keys(options !== null && options !== void 0 ? options : {}));
if (duplicateName.length !== 0) {
throw new Error(`Duplicated option name: ${duplicateName.join(", ")}`);
}
}
function checkForDuplicatePositionalOptionNames(positionalArgs) {
const duplicateName = findDuplicateValues(positionalArgs.map((option) => option.name));
if (duplicateName.length !== 0) {
throw new Error(`Duplicated positional argument name: ${duplicateName.join(", ")}`);
}
}
function checkIfOptNameUsedWithPositionalOption(options, positionalArgs) {
Object.keys(options).forEach((optionName) => {
if (positionalArgs.some((option) => option.name === optionName)) {
throw new Error(`Duplicated option name with positional argument name: ${optionName}`);
}
});
}
function validateParamOptionsAndPositionalArguments(options, positionalArgs) {
Object.entries(options).forEach(([optionName, option]) => {
validateParamOption(optionName, option);
});
checkForDuplicateOptionNames(options);
positionalArgs.forEach(validateParamPositionalArg);
checkForDuplicatePositionalOptionNames(positionalArgs);
checkIfOptNameUsedWithPositionalOption(options, positionalArgs);
}
exports.validateParamOptionsAndPositionalArguments = validateParamOptionsAndPositionalArguments;
function assertNever(value) {
throw new Error(`Unreachable code reached: ${JSON.stringify(value)}`);
}
exports.assertNever = assertNever;
//# sourceMappingURL=util.js.map