diff --git a/.eslintrc b/.eslintrc index 50f81e7..d317642 100644 --- a/.eslintrc +++ b/.eslintrc @@ -33,7 +33,8 @@ "**/*.test.ts", "**/*.spec.ts", "vitest.config.ts", - "tsup.config.ts" + "tsup.config.ts", + "**/__tests__/**" ] } ], diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 43dd2e9..dae0a69 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -23,6 +23,11 @@ jobs: - name: Install dependencies run: yarn --frozen-lockfile + - name: Install apt dependencies + run: | + sudo apt-get update + sudo apt-get install -y ghostscript + - name: Linting run: yarn lint diff --git a/__tests__/compress.spec.ts b/__tests__/compress.spec.ts new file mode 100644 index 0000000..69756e3 --- /dev/null +++ b/__tests__/compress.spec.ts @@ -0,0 +1,24 @@ +import fs from 'fs'; +import path from 'path'; +import compress from '../src/compress'; +import * as testHelper from './test.helper'; + +describe('compress', () => { + it('should compress a pdf file', async () => { + const originalFilePath = path.resolve( + __dirname, + '../examples/A17_FlightPlan.pdf' + ); + + const originalFile = await fs.promises.readFile(originalFilePath); + const originalPDF = await testHelper.parsePDF(originalFilePath); + + const compressedFile = await compress(originalFilePath); + const compressedPDF = await testHelper.parsePDF(compressedFile); + + expect(compressedFile.length).toBeLessThan(originalFile.length); + expect(compressedPDF.numpages).toEqual(originalPDF.numpages); + expect(compressedPDF.numrender).toEqual(originalPDF.numrender); + expect(compressedPDF.text).toEqual(originalPDF.text); + }); +}); diff --git a/__tests__/test.helper.ts b/__tests__/test.helper.ts new file mode 100644 index 0000000..e686546 --- /dev/null +++ b/__tests__/test.helper.ts @@ -0,0 +1,21 @@ +import fs from 'fs'; +import type pdfParser from 'pdf-parse'; + +// https://gitlab.com/autokent/pdf-parse/-/issues/24 +// eslint-disable-next-line @typescript-eslint/no-var-requires +const PDFParser = require('pdf-parse'); + +export async function parsePDF( + file: string | Buffer, + options?: pdfParser.Options +): Promise { + let dataBuffer: Buffer; + + if (typeof file === 'string') { + dataBuffer = fs.readFileSync(file); + } else dataBuffer = file; + + const data = await PDFParser(dataBuffer, options); + + return data; +} diff --git a/package.json b/package.json index bc0691b..e3bb5c9 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,8 @@ "lodash": "4.17.21" }, "devDependencies": { - "@types/node": "^20.11.6", + "@types/node": "20.11.6", + "@types/pdf-parse": "1.1.4", "@typescript-eslint/eslint-plugin": "6.19.1", "@typescript-eslint/parser": "6.19.1", "@vitest/coverage-istanbul": "1.2.1", @@ -70,6 +71,7 @@ "eslint-plugin-vitest": "0.3.20", "husky": "9.0.3", "lint-staged": "15.2.0", + "pdf-parse": "1.1.1", "prettier": "3.2.4", "tsup": "8.0.1", "tsx": "4.7.0", diff --git a/src/get-gs-module-path.ts b/src/get-gs-module-path.ts deleted file mode 100644 index 1b28cc3..0000000 --- a/src/get-gs-module-path.ts +++ /dev/null @@ -1,35 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import os from 'os'; - -function getGSModulePath(binPath: string, platform: NodeJS.Platform) { - const arch = os.arch(); - - let gsModule = ''; - - if (arch !== 'x64') { - throw new Error('unsupported architecture, this module only supports x64'); - } - - if (platform !== 'linux' && platform !== 'win32') { - throw new Error( - 'not possible to get module path, unsupported platform was provided' - ); - } - - if (platform === 'linux') { - gsModule = path.resolve(binPath, 'usr/local/bin/gs'); - } - - if (platform === 'win32') { - gsModule = path.resolve(binPath, 'bin/gswin64c.exe'); - } - - if (!fs.existsSync(gsModule)) { - throw new Error('The gs module could not be found inside binaries path.'); - } - - return gsModule; -} - -export default getGSModulePath; diff --git a/src/index.ts b/src/index.ts index ef4bd7a..ccb1d7c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -export { default as getGSModulePath } from './get-gs-module-path'; export { default as getBinPath } from './get-bin-path'; export { default as compress } from './compress'; export * from './types'; diff --git a/tsconfig.json b/tsconfig.json index 61e039c..76d7f60 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -69,5 +69,5 @@ // "skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ }, - "include": ["src/**/*", "examples/*", "tsup.config.ts", "vitest.config.ts"] + "include": ["src/**/*", "examples/*", "tsup.config.ts", "vitest.config.ts", "__tests__"] } diff --git a/vitest.config.ts b/vitest.config.ts index 85a95a3..50b27f3 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -6,7 +6,7 @@ export default defineConfig({ globals: true, logHeapUsage: true, passWithNoTests: true, - testTimeout: 10000, + testTimeout: 30000, coverage: { enabled: true, clean: true, diff --git a/yarn.lock b/yarn.lock index e6a20f5..456ee9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -593,7 +593,7 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== -"@types/node@^20.11.6": +"@types/node@20.11.6": version "20.11.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.6.tgz#6adf4241460e28be53836529c033a41985f85b6e" integrity sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q== @@ -605,6 +605,11 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== +"@types/pdf-parse@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@types/pdf-parse/-/pdf-parse-1.1.4.tgz#21a539efd2f16009d08aeed3350133948b5d7ed1" + integrity sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg== + "@types/semver@^7.5.0": version "7.5.6" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" @@ -1352,7 +1357,7 @@ debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3. dependencies: ms "2.1.2" -debug@^3.2.7: +debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -3077,6 +3082,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +node-ensure@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7" + integrity sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw== + node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -3365,6 +3375,14 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== +pdf-parse@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pdf-parse/-/pdf-parse-1.1.1.tgz#745e07408679548b3995ff896fd38e96e19d14a7" + integrity sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A== + dependencies: + debug "^3.1.0" + node-ensure "^0.0.0" + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"