Skip to content

Commit

Permalink
Dev tools (#195)
Browse files Browse the repository at this point in the history
* style: added prettier

* chore: added husky and lint-staged to run prettier with pre-commit hook
  • Loading branch information
mskec authored Dec 20, 2023
1 parent 0007bf7 commit 3b8f51f
Show file tree
Hide file tree
Showing 18 changed files with 410 additions and 379 deletions.
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
7 changes: 7 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"trailingComma": "all",
"tabWidth": 2,
"semi": true,
"printWidth": 120,
"singleQuote": true
}
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
"@typescript-eslint/parser": "^6.2.1",
"chai": "^4.3.7",
"eslint": "^8.46.0",
"husky": "^8.0.3",
"lint-staged": "^15.2.0",
"mocha": "^10.2.0",
"nyc": "^15.1.0",
"prettier": "^3.1.1",
"rimraf": "^5.0.1",
"rollup": "^3.27.2",
"ts-node": "^10.9.1",
Expand All @@ -37,7 +40,8 @@
"rollup": "rollup -c",
"clean": "rimraf ./dist",
"lint": "eslint --ext .ts .",
"build": "npm run test && npm run clean && npm run rollup"
"build": "npm run test && npm run clean && npm run rollup",
"prepare": "husky install"
},
"engines": {
"node": ">=14"
Expand Down Expand Up @@ -72,5 +76,8 @@
"bugs": {
"url": "https://github.com/yakovmeister/pdf2image/issues"
},
"homepage": "https://github.com/yakovmeister/pdf2image#readme"
"homepage": "https://github.com/yakovmeister/pdf2image#readme",
"lint-staged": {
"*.{js,ts}": ["prettier --write", "eslint --fix"]
}
}
73 changes: 36 additions & 37 deletions src/graphics.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import gm from "gm";
import path from "path";
import fs from "fs";
import gm from 'gm';
import path from 'path';
import fs from 'fs';
import { BufferResponse, ToBase64Response, WriteImageResponse } from './types/convertResponse';
import { Options } from "./types/options";
import { Options } from './types/options';

export class Graphics {
private quality = 0;

private format = "png";
private format = 'png';

private width = 768;

Expand All @@ -17,21 +17,21 @@ export class Graphics {

private density = 72;

private savePath = "./";
private savePath = './';

private saveFilename = "untitled";
private saveFilename = 'untitled';

private compression = "jpeg";
private compression = 'jpeg';

private gm: gm.SubClass = gm.subClass({ imageMagick: false });

public generateValidFilename(page?: number): string {
let filePath = path.join(this.savePath, this.saveFilename);
if (this.savePath.startsWith('./')) {
filePath = `./${filePath}`
filePath = `./${filePath}`;
}

if (typeof page === "number") {
if (typeof page === 'number') {
filePath = `${filePath}.${page + 1}`;
}

Expand All @@ -43,13 +43,13 @@ export class Graphics {
.density(this.density, this.density)
.resize(this.width, this.height, this.preserveAspectRatio ? '^' : '!')
.quality(this.quality)
.compress(this.compression)
.compress(this.compression);
}

public async toBase64(stream: fs.ReadStream, page?: number): Promise<ToBase64Response> {
const { buffer, size, page: pageResponse } = await this.toBuffer(stream, page);

return { base64: buffer.toString("base64"), size, page: pageResponse }
return { base64: buffer.toString('base64'), size, page: pageResponse };
}

public toBuffer(stream: fs.ReadStream, page?: number): Promise<BufferResponse> {
Expand All @@ -67,11 +67,11 @@ export class Graphics {
.on('data', (data) => {
buffers.push(data);
})
.on("end", () => {
.on('end', () => {
return resolve({
buffer: Buffer.concat(buffers),
size: `${this.width}x${this.height}`,
page: page + 1
page: page + 1,
});
});
});
Expand All @@ -83,20 +83,19 @@ export class Graphics {
const pageSetup = `${stream.path}[${page}]`;

return new Promise((resolve, reject) => {
this.gmBaseCommand(stream, pageSetup)
.write(output, (error) => {
if (error) {
return reject(error);
}
this.gmBaseCommand(stream, pageSetup).write(output, (error) => {
if (error) {
return reject(error);
}

return resolve({
name: path.basename(output),
size: `${this.width}x${this.height}`,
fileSize: fs.statSync(output).size / 1000.0,
path: output,
page: page + 1
});
return resolve({
name: path.basename(output),
size: `${this.width}x${this.height}`,
fileSize: fs.statSync(output).size / 1000.0,
path: output,
page: page + 1,
});
});
});
}

Expand All @@ -110,7 +109,7 @@ export class Graphics {
return reject(error);
}

return resolve(data.replace(/^[\w\W]*?1/, "1"));
return resolve(data.replace(/^[\w\W]*?1/, '1'));
});
} else {
image.identify((error, data) => {
Expand All @@ -119,7 +118,7 @@ export class Graphics {
}

return resolve(data);
})
});
}
});
}
Expand Down Expand Up @@ -174,13 +173,13 @@ export class Graphics {
}

public setGMClass(gmClass: string | boolean): Graphics {
if (typeof gmClass === "boolean") {
if (typeof gmClass === 'boolean') {
this.gm = gm.subClass({ imageMagick: gmClass });

return this;
}

if (gmClass.toLocaleLowerCase() === "imagemagick") {
if (gmClass.toLocaleLowerCase() === 'imagemagick') {
this.gm = gm.subClass({ imageMagick: true });

return this;
Expand All @@ -193,15 +192,15 @@ export class Graphics {

public getOptions(): Options {
return {
quality: this.quality,
format: this.format,
width: this.width,
height: this.height,
quality: this.quality,
format: this.format,
width: this.width,
height: this.height,
preserveAspectRatio: this.preserveAspectRatio,
density: this.density,
savePath: this.savePath,
density: this.density,
savePath: this.savePath,
saveFilename: this.saveFilename,
compression: this.compression
compression: this.compression,
};
}
}
12 changes: 6 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Convert } from "./types/convert";
import { defaultOptions } from "./utils/defaultOptions";
import { pdf2picCore } from "./pdf2picCore";
import { Convert } from './types/convert';
import { defaultOptions } from './utils/defaultOptions';
import { pdf2picCore } from './pdf2picCore';

export function fromPath(filePath: string, options = defaultOptions): Convert {
return pdf2picCore("path", filePath, options);
return pdf2picCore('path', filePath, options);
}

export function fromBuffer(buffer: Buffer, options = defaultOptions): Convert {
return pdf2picCore("buffer", buffer, options);
return pdf2picCore('buffer', buffer, options);
}

export function fromBase64(b64string: string, options = defaultOptions): Convert {
return pdf2picCore("base64", b64string, options);
return pdf2picCore('base64', b64string, options);
}
47 changes: 23 additions & 24 deletions src/pdf2picCore.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import fs from 'fs';
import { Graphics } from "./graphics";
import type { Convert, ConvertOptions } from "./types/convert";
import { Graphics } from './graphics';
import type { Convert, ConvertOptions } from './types/convert';
import type { ConvertResponse } from './types/convertResponse';
import type { Options } from "./types/options";
import type { Options } from './types/options';
import { bufferToStream } from './utils/converters/bufferToStream';
import { convertToBuffer } from "./utils/converters/convertToBuffer";
import { convertToBuffer } from './utils/converters/convertToBuffer';
import { convertToStream } from './utils/converters/convertToStream';
import { defaultOptions } from "./utils/defaultOptions";
import { defaultOptions } from './utils/defaultOptions';
import { getPages } from './utils/getPages';
import { resolveResponseType } from './utils/resolveResponseType';

Expand All @@ -17,45 +17,44 @@ export function pdf2picCore(source: string, data: string | Buffer, options = def

const _convert = (stream: fs.ReadStream, page: number, convertOptions: ConvertOptions): Promise<ConvertResponse> => {
if (page < 1) {
throw new Error("Page number should be more than or equal 1");
throw new Error('Page number should be more than or equal 1');
}

const responseType = resolveResponseType(convertOptions)
const responseType = resolveResponseType(convertOptions);
switch (responseType) {
case 'base64':
return gm.toBase64(stream, (page - 1))
return gm.toBase64(stream, page - 1);
case 'image':
return gm.writeImage(stream, (page - 1))
return gm.writeImage(stream, page - 1);
case 'buffer':
return gm.toBuffer(stream, (page - 1))
return gm.toBuffer(stream, page - 1);
default:
throw new Error(`Invalid responseType: ${responseType}`)
throw new Error(`Invalid responseType: ${responseType}`);
}
}
};

const _bulk = (stream, pages, convertOptions) => {
return Promise.all(pages.map(page => _convert(stream, page, convertOptions)));
}
return Promise.all(pages.map((page) => _convert(stream, page, convertOptions)));
};

const convert = (page = 1, convertOptions) => {
const stream = convertToStream(source, data);
return _convert(stream, page, convertOptions)
return _convert(stream, page, convertOptions);
};

convert.bulk = async (pages, convertOptions) => {
const buffer = await convertToBuffer(source, data);
const pagesToConvert = pages === -1
? await getPages(gm, bufferToStream(buffer))
: Array.isArray(pages) ? pages : [pages];
const pagesToConvert =
pages === -1 ? await getPages(gm, bufferToStream(buffer)) : Array.isArray(pages) ? pages : [pages];

const results = []
const batchSize = 10
const results = [];
const batchSize = 10;
for (let i = 0; i < pagesToConvert.length; i += batchSize) {
results.push(...await _bulk(bufferToStream(buffer), pagesToConvert.slice(i, i + batchSize), convertOptions))
results.push(...(await _bulk(bufferToStream(buffer), pagesToConvert.slice(i, i + batchSize), convertOptions)));
}

return results
}
return results;
};

convert.setOptions = (): void => setGMOptions(gm, options);

Expand All @@ -78,7 +77,7 @@ function setGMOptions(gm: Graphics, options: Options): void {
.setDensity(options.density)
.setSavePath(options.savePath)
.setSaveFilename(options.saveFilename)
.setCompression(options.compression)
.setCompression(options.compression);

return;
}
8 changes: 4 additions & 4 deletions src/types/convert.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { BufferResponse, ToBase64Response, WriteImageResponse } from './convertResponse';

export type ResponseType = 'image' | 'base64' | 'buffer'
export type ResponseType = 'image' | 'base64' | 'buffer';
export type ConvertOptions = {
responseType: ResponseType
}
responseType: ResponseType;
};

export type Convert = {
(pages?: number, options?: undefined): Promise<WriteImageResponse>;
Expand All @@ -23,4 +23,4 @@ export type Convert = {
setOptions: () => void;

setGMClass: (gmClass: string | boolean) => void;
}
};
2 changes: 1 addition & 1 deletion src/types/convertResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ export interface BufferResponse extends BaseResponse {
buffer?: Buffer;
}

export type ConvertResponse = WriteImageResponse | ToBase64Response | BufferResponse
export type ConvertResponse = WriteImageResponse | ToBase64Response | BufferResponse;
2 changes: 1 addition & 1 deletion src/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export type Options = {
savePath?: string;
saveFilename?: string;
compression?: string;
}
};
6 changes: 3 additions & 3 deletions src/utils/converters/base64ToStream.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ReadStream } from "fs";
import { bufferToStream } from "../../utils/converters/bufferToStream";
import { ReadStream } from 'fs';
import { bufferToStream } from '../../utils/converters/bufferToStream';

export function base64ToStream(base64: string): ReadStream {
const buffer = Buffer.from(base64, "base64");
const buffer = Buffer.from(base64, 'base64');

return bufferToStream(buffer);
}
6 changes: 3 additions & 3 deletions src/utils/converters/bufferToStream.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ReadStream } from "fs";
import { Readable } from "stream";
import { ReadStream } from 'fs';
import { Readable } from 'stream';

export function bufferToStream(buffer: Buffer): ReadStream {
const readableInstanceStream = new Readable({
read() {
this.push(buffer);
this.push(null);
}
},
});

return readableInstanceStream as ReadStream;
Expand Down
Loading

0 comments on commit 3b8f51f

Please sign in to comment.