UNPKG

zod-opts

Version:

node.js CLI option parser / validator using Zod

80 lines (79 loc) 3.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.uniq = uniq; exports.findDuplicateValues = findDuplicateValues; exports.errorExit = errorExit; exports.validateParamOptionsAndPositionalArguments = validateParamOptionsAndPositionalArguments; exports.assertNever = assertNever; const zod_1 = require("zod"); function uniq(array) { return [...new Set(array)]; } function findDuplicateValues(array) { return array.filter((e, i, a) => a.indexOf(e) !== i); } 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); } 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); } function assertNever(value) { throw new Error(`Unreachable code reached: ${JSON.stringify(value)}`); }