From b3bd4e51e391baea9f608e642293406f061af6b1 Mon Sep 17 00:00:00 2001 From: Kyle Hensel Date: Tue, 17 Oct 2023 17:34:39 +1300 Subject: [PATCH] add CLI --- .github/workflows/test.yml | 2 +- CHANGELOG.md | 4 ++- README.md | 16 ++++++++++- bin/cli.mjs | 57 ++++++++++++++++++++++++++++++++++++++ package.json | 5 +++- 5 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 bin/cli.mjs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1111d8c..b695b03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - node-version: [16.x, 18.x, 20.x] + node-version: [16.17, 18.x, 20.x, 21.x] steps: - name: ⏬ Checkout code diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a675ce..6efb76b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -- 💥 BREAKING CHANGE: Drop support for node v14 + +- 💥 BREAKING CHANGE: Drop support for node v14 and v16. The minimum version is now v16.17 +- Added a CLI ## 2.1.2 (2023-10-04) diff --git a/README.md b/README.md index affb2d4..f65dc82 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Useful for unit tests of PDFs -Supports nodejs v16 to v20. +Supports nodejs v16.17+, and comes with a CLI. ## Install @@ -76,3 +76,17 @@ const doc = await pdf("example.pdf", { scale: 2.0, // use this for PDFs with high resolution images if the generated image is low quality }); ``` + +## CLI + +```sh +npm i -g pdf-to-img@latest + +# example: +pdf2img inputFile.pdf + +# options: +# -s / --scale: set the scale (defaults to 3) +# -p / --password: the password to unlock the PDF +# -o / --output: the output folder, relative to the current working directory. +``` diff --git a/bin/cli.mjs b/bin/cli.mjs new file mode 100644 index 0000000..2bc44ee --- /dev/null +++ b/bin/cli.mjs @@ -0,0 +1,57 @@ +#!/usr/bin/env node + +// @ts-check +/* eslint-disable import/extensions */ +import { promises as fs } from "node:fs"; +import { parseArgs } from "node:util"; +import { join } from "node:path"; +import { pdf } from "../dist/index.js"; + +const { values, positionals } = parseArgs({ + options: { + scale: { short: "s", type: "string", default: "3" }, + password: { short: "p", type: "string" }, + output: { short: "o", type: "string" }, + }, + allowPositionals: true, +}); + +const [inputFile] = positionals; + +if (!inputFile) { + throw new Error( + "Please specify an input file, for example, `pdf2img -s 3 example.pdf`" + ); +} + +/** the name of the file, without the file extension */ +const inputFileBaseName = /** @type {string} */ ( + inputFile.split("/").at(-1) +).replace(/\.pdf$/, ""); + +const fullInputFilePath = join(process.cwd(), inputFile); +const outputFolder = join(process.cwd(), values.output || ""); + +async function main() { + let pageNumber = 1; + + const document = await pdf(fullInputFilePath, { + scale: +(values.scale || 3), + password: values.password, + }); + + if (values.output) { + // if the user specified a custom output folder, + // create it if it does't already exist. + await fs.mkdir(outputFolder, { recursive: true }); + } + + for await (const image of document) { + const outputImageName = `${inputFileBaseName}-${pageNumber}.png`; + console.log(outputImageName); + await fs.writeFile(join(outputFolder, outputImageName), image); + pageNumber++; + } +} + +main(); diff --git a/package.json b/package.json index 119e4d4..146830f 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,11 @@ "test": "jest", "trypublish": "npm publish || true" }, + "bin": { + "pdf2img": "./bin/cli.mjs" + }, "engines": { - "node": ">=16" + "node": ">=16.17" }, "dependencies": { "canvas": "2.11.2",