UNPKG

json2zod

Version:

A CLI tool and library to convert JSON to Zod schemas with optional OpenAPI examples.

137 lines (118 loc) 4.67 kB
#!/usr/bin/env node import { generateZodSchema } from './generator'; // Import the core generator function import * as path from 'path'; /** * Main function for the CLI tool. * Reads JSON input, processes arguments, and prints the generated Zod schema. */ async function main() { const args = process.argv.slice(2); let jsonString: string | undefined; let addOpenApiExamples = false; // Default behavior changed to NOT include OpenAPI examples let exampleFormat: 'openapi' | 'meta' = 'meta'; // Default to v4 (meta) // Parse command line arguments for (let i = 0; i < args.length; i++) { const arg = args[i]; if (arg === '--add-openapi-examples') { // Flag to ENABLE OpenAPI examples addOpenApiExamples = true; } else if (arg === '--example-format') { const nextArg = args[i + 1]; if (nextArg && ['v3', 'openapi', 'v4', 'meta'].includes(nextArg)) { exampleFormat = (nextArg === 'v3' || nextArg === 'openapi') ? 'openapi' : 'meta'; i++; // Skip next argument } else { console.error("Error: --example-format requires value 'v3', 'openapi', 'v4', or 'meta'"); process.exit(1); } } else if (arg === '--help' || arg === '-h') { printHelp(); process.exit(0); } else if (arg.startsWith('-')) { console.error(`Error: Unknown option "${arg}"`); printHelp(); process.exit(1); } else if (!jsonString) { // Assume the first non-flag argument is the JSON string jsonString = arg; } else { console.error("Error: Too many arguments provided. Expected a single JSON string or input via stdin."); printHelp(); process.exit(1); } } // If no JSON string is provided via arguments, try reading from stdin if (!jsonString) { // Check if stdin is a TTY (interactive terminal). If so, prompt the user. // If not (e.g., piped input), it will just wait for stdin. if (process.stdin.isTTY) { console.log("Enter JSON (Ctrl+D to finish, Ctrl+C to exit):"); } jsonString = await readFromStdin(); } if (!jsonString) { console.error("Error: No JSON input provided."); printHelp(); process.exit(1); } try { const parsedJson = JSON.parse(jsonString); // Call the core generator function with the parsed JSON and options const zodSchemaOutput = generateZodSchema(parsedJson, { addOpenApiExamples, exampleFormat }); console.log(zodSchemaOutput); } catch (e: any) { if (e instanceof SyntaxError) { console.error(`Error: Invalid JSON input. ${e.message}`); } else { console.error(`An unexpected error occurred: ${e.message}`); } process.exit(1); } } /** * Reads all data from standard input (stdin) until EOF. * @returns A promise that resolves with the accumulated input string. */ function readFromStdin(): Promise<string> { return new Promise((resolve, reject) => { let data = ''; process.stdin.setEncoding('utf8'); process.stdin.on('readable', () => { let chunk; while ((chunk = process.stdin.read()) !== null) { data += chunk; } }); process.stdin.on('end', () => { resolve(data); }); process.stdin.on('error', (err) => { reject(err); }); }); } /** * Prints the help message for the CLI tool. */ function printHelp() { const scriptName = path.basename(process.argv[1] || 'json2zod'); console.log(` Usage: ${scriptName} [options] [json_string] Generate a Zod schema from a JSON string. If no JSON string is provided, input is read from stdin. Options: --add-openapi-examples Include examples in the generated schema. By default, examples are NOT included. --example-format <format> Format for examples: 'v3'/'openapi' or 'v4'/'meta'. Defaults to 'v4'. -h, --help Show this help message and exit. Examples: # Pass JSON as a string argument (no OpenAPI examples by default) ${scriptName} '{"name": "Alice", "age": 30}' # Pipe JSON from a file with OpenAPI examples cat data.json | ${scriptName} --add-openapi-examples --example-format v3 # Pipe JSON from stdin without OpenAPI examples (default) echo '{"item": "pen"}' | ${scriptName} `); } // Execute the main CLI function main();