Building a CLI Tool with jMencode: Step-by-Step Tutorial
This tutorial shows how to build a simple, reliable command-line interface (CLI) tool that uses jMencode for encoding and decoding data. Assumptions: you want a cross-platform Node.js-based CLI, jMencode is available as an npm package named “jmencode”, and you have Node.js 18+ installed. If your environment differs, adjust commands accordingly.
What you’ll build
A CLI named jmtools with commands:
- encode: read input (file or stdin), output encoded data
- decode: read input (file or stdin), output decoded data
- –input / -i and –output / -o flags for files
- –format / -f to choose encoding format (default: base64)
- –help and –version
1) Project setup
- Create project folder and initialize npm:
Code
mkdir jmtools cd jmtools npm init -y
- Install dependencies:
Code
npm install jmencode commander chalk
- jmencode: the encoding library.
- commander: CLI argument parsing.
- chalk: colored terminal output.
2) Create entry script
- Add bin in package.json:
json
“bin”: { “jmtools”: ”./bin/jmtools.js” }
- Create folder and file:
Code
mkdir bin touch bin/jmtools.js chmod +x bin/jmtools.js
3) Implement CLI logic
Paste the following into bin/jmtools.js (Node.js module script):
javascript
#!/usr/bin/env node const fs = require(‘fs’); const { program } = require(‘commander’); const chalk = require(‘chalk’); const jmencode = require(‘jmencode’); // assume default export program .name(‘jmtools’) .description(‘CLI tool for encoding/decoding using jMencode’) .version(require(’../package.json’).version); program .command(‘encode’) .description(‘Encode input’) .option(’-i, –input‘ , ‘input file (defaults to stdin)’) .option(’-o, –output‘ , ‘output file (defaults to stdout)’) .option(’-f, –format‘ , ‘encoding format (default: base64)’, ‘base64’) .action(async (opts) => { try { const input = opts.input ? fs.readFileSync(opts.input) : fs.readFileSync(0); const encoded = jmencode.encode(input, { format: opts.format }); if (opts.output) fs.writeFileSync(opts.output, encoded); else process.stdout.write(encoded); } catch (err) { console.error(chalk.red(‘Error:’), err.message); process.exit(1); } }); program .command(‘decode’) .description(‘Decode input’) .option(’-i, –input‘ , ‘input file (defaults to stdin)’) .option(’-o, –output‘ , ‘output file (defaults to stdout)’) .option(’-f, –format‘ , ‘encoding format (default: base64)’, ‘base64’) .action(async (opts) => { try { const input = opts.input ? fs.readFileSync(opts.input, ‘utf8’) : fs.readFileSync(0, ‘utf8’); const decoded = jmencode.decode(input, { format: opts.format }); if (opts.output) fs.writeFileSync(opts.output, decoded); else { if (Buffer.isBuffer(decoded)) process.stdout.write(decoded); else process.stdout.write(String(decoded)); } } catch (err) { console.error(chalk.red(‘Error:’), err.message); process.exit(1); } }); program.parse(process.argv);
Notes:
- Adjust jmencode import/use based on its API (replace jmencode.encode/decode as needed).
- Synchronous fs methods simplify the example; switch to async if preferred.
4) Local testing
- Link package locally:
Code
npm link
- Run commands:
Code
echo “hello” | jmtools encode jmtools encode -i file.txt -o out.txt jmtools decode -i out.txt
5) Packaging and publishing
- Update package.json metadata (author, license, keywords).
- Publish to npm:
Code
npm publish –access public
(Ensure you have an npm account and versioning set.)
6) Enhancements (optional)
- Add streaming support for large files using streams instead of readFileSync.
- Add subcommands for different algorithms or presets.
- Add tests with Jest or AVA.
- Add CI (GitHub Actions) for linting and publishing.
Troubleshooting
- If jmencode API differs, consult its docs and adapt encode/decode calls.
- Permission errors on unix: ensure bin file is executable.
- For Windows, ensure Node is in PATH and use npx or npm link.
This gives a functional, extendable CLI using jMencode. Adjust format names and API calls to match the actual jmencode package.
Leave a Reply