UNPKG

zod-opts

Version:

node.js CLI option parser / validator using Zod

222 lines (221 loc) 7.78 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Parser = void 0; exports.parser = parser; const node_path_1 = __importDefault(require("node:path")); const zod_1 = require("zod"); const command_parser_1 = require("./command_parser"); const error_1 = require("./error"); const help_1 = require("./help"); const helper = __importStar(require("./parser_helper")); const util = __importStar(require("./util")); class Parser { constructor({ name, version, description, options, positionalArgs, validation, handler, } = {}) { this._options = {}; this._positionalArgs = []; this._name = name; this._version = version; this._description = description; if (options !== undefined) { this._options = options; } if (positionalArgs !== undefined) { this._positionalArgs = positionalArgs; } this._validation = validation; this._handler = handler; } name(name) { this._name = name; return this; } version(version) { this._version = version; return this; } description(description) { this._description = description; return this; } options(options) { util.validateParamOptionsAndPositionalArguments(options, this._positionalArgs); return new Parser({ ...this._currentState(), options, }); } args(positionalArgs) { util.validateParamOptionsAndPositionalArguments(this._options, positionalArgs); return new Parser({ ...this._currentState(), positionalArgs: positionalArgs, }); } _internalHandler(handler) { this._handler = handler; return this; } validation(validation) { this._validation = validation; return this; } showHelp() { const help = this.getHelp(); console.log(help); // eslint-disable-line no-console } getHelp() { const internalOptions = helper.generateInternalOptions(this._options); const internalPositionalArguments = helper.generateInternalPositionalArguments(this._positionalArgs); return (0, help_1.generateGlobalHelp)({ options: internalOptions, positionalArgs: internalPositionalArguments, name: this._scriptName(), description: this._description, version: this._version, }); } parse(args) { const validArgs = args !== null && args !== void 0 ? args : process.argv.slice(2); const { _options: options, _positionalArgs: positionalArgs, _handler: handler, } = this; // Check support of options and positionalArgs before parsing args const shape = helper.generateZodShape(options, positionalArgs); const internalResult = helper.createInternalParserAndParse({ options, positionalArgs, args: validArgs, name: this._scriptName(), description: this._description, version: this._version, }); if (internalResult.type !== "match") { this._handleAndExit(internalResult); } const zodParseResult = this._zodParse(internalResult, shape); if (!zodParseResult.success) { this._handleAndExit(zodParseResult.error); } const validationError = this._validateByCustomValidation(zodParseResult.value, internalResult.help); if (validationError !== undefined) { this._handleAndExit(validationError); } if (handler != null) { handler({ ...internalResult, parsed: zodParseResult.value }); } return zodParseResult.value; } _validateByCustomValidation(value, help) { if (this._validation === undefined) { return undefined; } const validationResult = (() => { try { return this._validation(value); } catch (e) { if (e instanceof Error) { return e.message; } throw e; } })(); if (validationResult !== true) { return { type: "error", error: new error_1.ParseError(validationResult), help, exitCode: 1, }; } } _zodParse(prevResult, shape) { const result = zod_1.z.object(shape).safeParse(prevResult.parsed); if (!result.success) { const firstError = result.error.issues[0]; return { success: false, error: { type: "error", error: new error_1.ParseError(`${firstError.message}: ${firstError.path.join("")}`, result.error), help: prevResult.help, exitCode: 1, }, }; } return { success: true, value: result.data }; } _handleAndExit(handlerArg) { if (this._handler != null) { this._handler(handlerArg); } util.errorExit(handlerArg, this._version); } subcommand(command) { if (Object.keys(this._options).length > 0) { throw new Error("Cannot add subcommand to parser with options()."); } if (Object.keys(this._positionalArgs).length > 0) { throw new Error("Cannot add subcommand to parser with args()."); } return new command_parser_1.CommandParser({ ...this._currentState(), }).subcommand(command); } _currentState() { return { name: this._name, version: this._version, description: this._description, options: this._options, positionalArgs: this._positionalArgs, validation: this._validation, handler: this._handler, }; } _scriptName() { if (this._name !== undefined) { return this._name; } const pathName = process.argv[1]; return node_path_1.default.basename(pathName); } } exports.Parser = Parser; function parser() { return new Parser(); }