diff --git a/eslint.config.cjs b/eslint.config.cjs new file mode 100644 index 0000000..3e45730 --- /dev/null +++ b/eslint.config.cjs @@ -0,0 +1,20 @@ +const globals = require('globals'); + +module.exports = [ + { + files: ['**/*.js'], + languageOptions: { + globals: globals.node, + sourceType: 'module', + parserOptions: { + ecmaVersion: 12, + }, + }, + rules: { + 'no-console': 'off', + 'indent': ['error', 2], + 'linebreak-style': ['error', 'unix'], + 'quotes': ['error', 'single'], + }, + }, +]; diff --git a/package-lock.json b/package-lock.json index 088030e..1583439 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "image-thumbnail", - "version": "1.0.15", + "version": "1.0.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "image-thumbnail", - "version": "1.0.15", + "version": "1.0.16", "license": "MIT", "dependencies": { "axios": "^1.7.3", @@ -15,6 +15,8 @@ "validator": "^13.12.0" }, "devDependencies": { + "eslint": "^9.9.0", + "globals": "^15.9.0", "jest": "^29.7.0" } }, @@ -633,6 +635,15 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.23.6", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", @@ -662,6 +673,153 @@ "tslib": "^2.4.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/js": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.4", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", @@ -1444,6 +1602,41 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1572,6 +1765,43 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1639,9 +1869,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2070,6 +2300,12 @@ } } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -2164,6 +2400,168 @@ "node": ">=8" } }, + "node_modules/eslint": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", + "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.9.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -2177,6 +2575,48 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -2225,12 +2665,33 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -2240,6 +2701,18 @@ "bser": "2.1.1" } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2265,6 +2738,25 @@ "node": ">=8" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -2386,13 +2878,28 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graceful-fs": { @@ -2437,6 +2944,15 @@ "node": ">=10.17.0" } }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/image-size": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", @@ -2451,6 +2967,31 @@ "node": ">=16.x" } }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -2513,6 +3054,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2531,6 +3081,18 @@ "node": ">=6" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2540,6 +3102,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -3276,12 +3847,30 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -3294,6 +3883,15 @@ "node": ">=6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -3312,6 +3910,19 @@ "node": ">=6" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -3330,6 +3941,12 @@ "node": ">=8" } }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3524,6 +4141,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3575,6 +4209,18 @@ "node": ">=6" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -3665,6 +4311,15 @@ "node": ">=8" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -3709,6 +4364,15 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -3733,6 +4397,26 @@ "inherits": "~2.0.3" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -3795,6 +4479,39 @@ "node": ">=10" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -4053,6 +4770,12 @@ "node": ">=8" } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -4086,6 +4809,18 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "optional": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -4143,6 +4878,15 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -4189,6 +4933,15 @@ "node": ">= 8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index acdfbea..1cdb94b 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,11 @@ { "name": "image-thumbnail", - "version": "1.0.16", + "version": "1.0.17", "description": "Generate an image thumbnail.", "main": "index.js", "scripts": { + "lint": "eslint .", + "lint:fix": "eslint . --fix", "test": "jest" }, "repository": { @@ -25,6 +27,8 @@ }, "homepage": "https://github.com/onildoaguiar/image-thumbnail#readme", "devDependencies": { + "eslint": "^9.9.0", + "globals": "^15.9.0", "jest": "^29.7.0" }, "dependencies": { diff --git a/src/index.js b/src/index.js index a371eed..c3006b1 100644 --- a/src/index.js +++ b/src/index.js @@ -13,204 +13,204 @@ const PERCENTAGE = 10; const RESPONSE_TYPE = 'buffer'; const fromBase64 = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor) => { - const imageBuffer = Buffer.from(source, 'base64'); - const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); + const imageBuffer = Buffer.from(source, 'base64'); + const dimensions = getDimensions(imageBuffer, percentage, { width, height }); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); - if (responseType === 'base64') { - return thumbnailBuffer.toString('base64'); - } + if (responseType === 'base64') { + return thumbnailBuffer.toString('base64'); + } - return thumbnailBuffer; + return thumbnailBuffer; }; const fromUri = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor) => { - const response = await axios.get(source.uri, { responseType: 'arraybuffer' }); - const imageBuffer = Buffer.from(response.data, 'binary'); + const response = await axios.get(source.uri, { responseType: 'arraybuffer' }); + const imageBuffer = Buffer.from(response.data, 'binary'); - const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); + const dimensions = getDimensions(imageBuffer, percentage, { width, height }); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); - if (responseType === 'base64') { - return thumbnailBuffer.toString('base64'); - } + if (responseType === 'base64') { + return thumbnailBuffer.toString('base64'); + } - return thumbnailBuffer; + return thumbnailBuffer; }; const fromPath = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor) => { - const imageBuffer = fs.readFileSync(source); + const imageBuffer = fs.readFileSync(source); - const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); + const dimensions = getDimensions(imageBuffer, percentage, { width, height }); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); - if (responseType === 'base64') { - return thumbnailBuffer.toString('base64'); - } + if (responseType === 'base64') { + return thumbnailBuffer.toString('base64'); + } - return thumbnailBuffer; + return thumbnailBuffer; }; const fromReadStream = async ( - source, - percentage, - width, - height, - responseType, - jpegOptions, - fit, - failOnError, - withMetaData, - flattenBackgroundColor, + source, + percentage, + width, + height, + responseType, + jpegOptions, + fit, + failOnError, + withMetaData, + flattenBackgroundColor, ) => { - const imageBuffer = await util.streamToBuffer(source); - const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); + const imageBuffer = await util.streamToBuffer(source); + const dimensions = getDimensions(imageBuffer, percentage, { width, height }); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); - if (responseType === 'base64') { - return thumbnailBuffer.toString('base64'); - } + if (responseType === 'base64') { + return thumbnailBuffer.toString('base64'); + } - return thumbnailBuffer; + return thumbnailBuffer; }; const fromBuffer = async (source, percentage, width, height, responseType, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor) => { - const imageBuffer = source; - const dimensions = getDimensions(imageBuffer, percentage, { width, height }); - const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); + const imageBuffer = source; + const dimensions = getDimensions(imageBuffer, percentage, { width, height }); + const thumbnailBuffer = await sharpResize(imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetaData, flattenBackgroundColor); - if (responseType === 'base64') { - return thumbnailBuffer.toString('base64'); - } + if (responseType === 'base64') { + return thumbnailBuffer.toString('base64'); + } - return thumbnailBuffer; + return thumbnailBuffer; }; module.exports = async (source, options) => { - const percentage = options && options.percentage ? options.percentage : PERCENTAGE; - const width = options && options.width ? options.width : undefined; - const height = options && options.height ? options.height : undefined; - const responseType = options && options.responseType ? options.responseType : RESPONSE_TYPE; - const jpegOptions = options && options.jpegOptions ? options.jpegOptions : undefined; - const fit = options && options.fit ? options.fit : undefined; - const failOnError = options && typeof options.failOnError !== 'undefined' ? options.failOnError : true; - const withMetaData = options && typeof options.withMetaData !== 'undefined' ? options.withMetaData : false; - const flattenBackgroundColor = options && typeof options.flattenBackgroundColor !== 'undefined' ? options.flattenBackgroundColor : '#ffffff'; - - try { - switch (typeof source) { - case 'object': - let response; - if (source instanceof fs.ReadStream || source instanceof stream.PassThrough) { - response = await fromReadStream( - source, - percentage, - width, - height, - responseType, - jpegOptions, - fit, - failOnError, - withMetaData, - flattenBackgroundColor, - ); - } else if (source instanceof Buffer) { - response = await fromBuffer( - source, - percentage, - width, - height, - responseType, - jpegOptions, - fit, - failOnError, - withMetaData, - flattenBackgroundColor, - ); - } else { - response = await fromUri( - source, - percentage, - width, - height, - responseType, - jpegOptions, - fit, - failOnError, - withMetaData, - flattenBackgroundColor, - ); - } - return response; - case 'string': - if (validator.isBase64(source)) { - return await fromBase64( - source, - percentage, - width, - height, - responseType, - jpegOptions, - fit, - failOnError, - withMetaData, - flattenBackgroundColor, - ); - } else { - return await fromPath( - source, - percentage, - width, - height, - responseType, - jpegOptions, - fit, - failOnError, - withMetaData, - flattenBackgroundColor, - ); - } - default: - throw new Error('unsupported source type'); - } - } catch (err) { - throw new Error(err.message); + const percentage = options && options.percentage ? options.percentage : PERCENTAGE; + const width = options && options.width ? options.width : undefined; + const height = options && options.height ? options.height : undefined; + const responseType = options && options.responseType ? options.responseType : RESPONSE_TYPE; + const jpegOptions = options && options.jpegOptions ? options.jpegOptions : undefined; + const fit = options && options.fit ? options.fit : undefined; + const failOnError = options && typeof options.failOnError !== 'undefined' ? options.failOnError : true; + const withMetaData = options && typeof options.withMetaData !== 'undefined' ? options.withMetaData : false; + const flattenBackgroundColor = options && typeof options.flattenBackgroundColor !== 'undefined' ? options.flattenBackgroundColor : '#ffffff'; + + try { + switch (typeof source) { + case 'object': + let response; + if (source instanceof fs.ReadStream || source instanceof stream.PassThrough) { + response = await fromReadStream( + source, + percentage, + width, + height, + responseType, + jpegOptions, + fit, + failOnError, + withMetaData, + flattenBackgroundColor, + ); + } else if (source instanceof Buffer) { + response = await fromBuffer( + source, + percentage, + width, + height, + responseType, + jpegOptions, + fit, + failOnError, + withMetaData, + flattenBackgroundColor, + ); + } else { + response = await fromUri( + source, + percentage, + width, + height, + responseType, + jpegOptions, + fit, + failOnError, + withMetaData, + flattenBackgroundColor, + ); + } + return response; + case 'string': + if (validator.isBase64(source)) { + return await fromBase64( + source, + percentage, + width, + height, + responseType, + jpegOptions, + fit, + failOnError, + withMetaData, + flattenBackgroundColor, + ); + } else { + return await fromPath( + source, + percentage, + width, + height, + responseType, + jpegOptions, + fit, + failOnError, + withMetaData, + flattenBackgroundColor, + ); + } + default: + throw new Error('unsupported source type'); } + } catch (err) { + throw new Error(err.message); + } }; const getDimensions = (imageBuffer, percentageOfImage, dimensions) => { - if (typeof dimensions.width != 'undefined' || typeof dimensions.height != 'undefined') { - return util.removeUndefined(dimensions); - } + if (typeof dimensions.width != 'undefined' || typeof dimensions.height != 'undefined') { + return util.removeUndefined(dimensions); + } - const originalDimensions = sizeOf(imageBuffer); + const originalDimensions = sizeOf(imageBuffer); - const width = parseInt((originalDimensions.width * (percentageOfImage / 100)).toFixed(0)); - const height = parseInt((originalDimensions.height * (percentageOfImage / 100)).toFixed(0)); + const width = parseInt((originalDimensions.width * (percentageOfImage / 100)).toFixed(0)); + const height = parseInt((originalDimensions.height * (percentageOfImage / 100)).toFixed(0)); - return { width, height }; + return { width, height }; }; const sharpResize = (imageBuffer, dimensions, jpegOptions, fit, failOnError, withMetadata, flattenBackgroundColor) => { - return new Promise((resolve, reject) => { - let result = sharp(imageBuffer, { failOnError }) - .resize({ - ...dimensions, - withoutEnlargement: true, - fit: fit ? fit : 'contain', - }) - .flatten({ background: flattenBackgroundColor }); - - if (withMetadata) { - result.withMetadata(); - } - - result.jpeg(jpegOptions ? jpegOptions : { force: false }).toBuffer((err, data) => { - if (err) { - reject(err); - } else { - resolve(data); - } - }); + return new Promise((resolve, reject) => { + let result = sharp(imageBuffer, { failOnError }) + .resize({ + ...dimensions, + withoutEnlargement: true, + fit: fit ? fit : 'contain', + }) + .flatten({ background: flattenBackgroundColor }); + + if (withMetadata) { + result.withMetadata(); + } + + result.jpeg(jpegOptions ? jpegOptions : { force: false }).toBuffer((err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } }); + }); }; diff --git a/src/util.js b/src/util.js index 7f52698..43b08ad 100644 --- a/src/util.js +++ b/src/util.js @@ -1,17 +1,17 @@ module.exports.streamToBuffer = (stream) => { - return new Promise((resolve, reject) => { - const buffers = []; - stream.on("data", function (data) { - buffers.push(data); - }); + return new Promise((resolve, reject) => { + const buffers = []; + stream.on('data', function (data) { + buffers.push(data); + }); - stream.on("end", function () { - resolve(Buffer.concat(buffers)); - }) + stream.on('end', function () { + resolve(Buffer.concat(buffers)); }) + }) } module.exports.removeUndefined = (dimensions) => { - Object.keys(dimensions).forEach(key => dimensions[key] === undefined && delete dimensions[key]); - return dimensions + Object.keys(dimensions).forEach(key => dimensions[key] === undefined && delete dimensions[key]); + return dimensions } \ No newline at end of file diff --git a/test/_fixtures/index.js b/test/_fixtures/index.js index 1de9529..39620e5 100644 --- a/test/_fixtures/index.js +++ b/test/_fixtures/index.js @@ -13,15 +13,15 @@ const thumbnailBase64FromSamsung = require('./thumbnailBase64FromSamsung.json'). const unsupportedSourceType = 'Error: unsupported source type' module.exports = { - imageBase64, - imageUri, - thumbnailBufferFromBase64, - thumbnailBufferFromFilePath, - thumbnailBufferFromUri, - thumbnailBase64FromBase64, - thumbnailBase64FromFilePath, - thumbnailBase64FromUri, - unsupportedSourceType, - imageBaseSamsung, - thumbnailBase64FromSamsung + imageBase64, + imageUri, + thumbnailBufferFromBase64, + thumbnailBufferFromFilePath, + thumbnailBufferFromUri, + thumbnailBase64FromBase64, + thumbnailBase64FromFilePath, + thumbnailBase64FromUri, + unsupportedSourceType, + imageBaseSamsung, + thumbnailBase64FromSamsung }; \ No newline at end of file diff --git a/test/imageThumbnail.test.js b/test/imageThumbnail.test.js index 0fd89ae..2003897 100644 --- a/test/imageThumbnail.test.js +++ b/test/imageThumbnail.test.js @@ -8,182 +8,182 @@ const util = require('../src/util'); const IMAGE_PATH = './resources/images/dog.jpg'; describe('Image Thumbnail', () => { - describe('Thumbnail Buffer', () => { - it('should return a buffer image thumbnail from an image base64', async () => { - const thumbnail = await imageThumbnail(fixtures.imageBase64); + describe('Thumbnail Buffer', () => { + it('should return a buffer image thumbnail from an image base64', async () => { + const thumbnail = await imageThumbnail(fixtures.imageBase64); - expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromBase64); - }); - - it('should return a buffer image thumbnail from an image uri', async () => { - const options = { responseType: 'buffer' }; - const thumbnail = await imageThumbnail({ uri: fixtures.imageUri }, options); + expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromBase64); + }); - expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromUri); - }); + it('should return a buffer image thumbnail from an image uri', async () => { + const options = { responseType: 'buffer' }; + const thumbnail = await imageThumbnail({ uri: fixtures.imageUri }, options); - it('should return a buffer image thumbnail from a file path', async () => { - const options = { responseType: 'buffer' }; - const thumbnail = await imageThumbnail(IMAGE_PATH, options); + expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromUri); + }); - expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromFilePath); - }); + it('should return a buffer image thumbnail from a file path', async () => { + const options = { responseType: 'buffer' }; + const thumbnail = await imageThumbnail(IMAGE_PATH, options); - it('should return a buffer image thumbnail from a stream', async () => { - const imageStream = fs.createReadStream(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageStream); + expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromFilePath); + }); - expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromFilePath); - }); + it('should return a buffer image thumbnail from a stream', async () => { + const imageStream = fs.createReadStream(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageStream); - it('should return a buffer image thumbnail from a buffer', async () => { - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer); + expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromFilePath); + }); - expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromFilePath); - }); + it('should return a buffer image thumbnail from a buffer', async () => { + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer); + expect(thumbnail.toJSON()).toEqual(fixtures.thumbnailBufferFromFilePath); }); - describe('Thumbnail Base64', () => { + }); + + describe('Thumbnail Base64', () => { - it('should return a base64 image thumbnail from an image base64', async () => { - const options = { responseType: 'base64' }; - const thumbnail = await imageThumbnail(fixtures.imageBase64, options); + it('should return a base64 image thumbnail from an image base64', async () => { + const options = { responseType: 'base64' }; + const thumbnail = await imageThumbnail(fixtures.imageBase64, options); - expect(thumbnail).toEqual(fixtures.thumbnailBase64FromBase64); - }); + expect(thumbnail).toEqual(fixtures.thumbnailBase64FromBase64); + }); - it('should return a base64 image thumbnail from a buffer', async () => { - const options = { responseType: 'base64' }; - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer, options); + it('should return a base64 image thumbnail from a buffer', async () => { + const options = { responseType: 'base64' }; + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer, options); - expect(thumbnail).toEqual(fixtures.thumbnailBase64FromFilePath); - }); + expect(thumbnail).toEqual(fixtures.thumbnailBase64FromFilePath); + }); - it('should return a base64 image thumbnail from a stream', async () => { - const options = { responseType: 'base64' }; - const imageStream = fs.createReadStream(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageStream, options); + it('should return a base64 image thumbnail from a stream', async () => { + const options = { responseType: 'base64' }; + const imageStream = fs.createReadStream(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageStream, options); - expect(thumbnail).toEqual(fixtures.thumbnailBase64FromFilePath); - }); + expect(thumbnail).toEqual(fixtures.thumbnailBase64FromFilePath); + }); - it('should return a base64 image thumbnail from an image uri', async () => { - const options = { responseType: 'base64' }; - const thumbnail = await imageThumbnail({ uri: fixtures.imageUri }, options); + it('should return a base64 image thumbnail from an image uri', async () => { + const options = { responseType: 'base64' }; + const thumbnail = await imageThumbnail({ uri: fixtures.imageUri }, options); - expect(thumbnail).toEqual(fixtures.thumbnailBase64FromUri); - }); + expect(thumbnail).toEqual(fixtures.thumbnailBase64FromUri); + }); - it('should return a base64 image thumbnail from a file path', async () => { - const options = { responseType: 'base64' }; - const thumbnail = await imageThumbnail(IMAGE_PATH, options); + it('should return a base64 image thumbnail from a file path', async () => { + const options = { responseType: 'base64' }; + const thumbnail = await imageThumbnail(IMAGE_PATH, options); - expect(thumbnail).toEqual(fixtures.thumbnailBase64FromFilePath); - }); + expect(thumbnail).toEqual(fixtures.thumbnailBase64FromFilePath); + }); - it('should return a base64 image thumbnail from an image from samsung phones due to weird encoding and failOnError set', async () => { - const options = { responseType: 'base64', failOnError: false }; - const thumbnail = await imageThumbnail(fixtures.imageBaseSamsung, options); + it('should return a base64 image thumbnail from an image from samsung phones due to weird encoding and failOnError set', async () => { + const options = { responseType: 'base64', failOnError: false }; + const thumbnail = await imageThumbnail(fixtures.imageBaseSamsung, options); - expect(thumbnail).toEqual(fixtures.thumbnailBase64FromSamsung); - }); + expect(thumbnail).toEqual(fixtures.thumbnailBase64FromSamsung); }); + }); - describe('Options', () => { - it('should return a buffer image and keep aspect 300x200', async () => { - const options = { width: 300, height: 200 }; - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer, options); - const dimensions = sizeOf(thumbnail); + describe('Options', () => { + it('should return a buffer image and keep aspect 300x200', async () => { + const options = { width: 300, height: 200 }; + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer, options); + const dimensions = sizeOf(thumbnail); - expect(dimensions.width).toEqual(300); - expect(dimensions.height).toEqual(200); - }); + expect(dimensions.width).toEqual(300); + expect(dimensions.height).toEqual(200); + }); - it('should return a buffer image with width equals 300', async () => { - const options = { width: 300 }; - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer, options); - const dimensions = sizeOf(thumbnail); + it('should return a buffer image with width equals 300', async () => { + const options = { width: 300 }; + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer, options); + const dimensions = sizeOf(thumbnail); - expect(dimensions.width).toEqual(300); - expect(dimensions.height).toEqual(199); + expect(dimensions.width).toEqual(300); + expect(dimensions.height).toEqual(199); - }); + }); - it('should return a buffer image with height equals 300', async () => { - const options = { height: 300 }; - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer, options); - const dimensions = sizeOf(thumbnail); + it('should return a buffer image with height equals 300', async () => { + const options = { height: 300 }; + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer, options); + const dimensions = sizeOf(thumbnail); - expect(dimensions.width).toEqual(451); - expect(dimensions.height).toEqual(300); + expect(dimensions.width).toEqual(451); + expect(dimensions.height).toEqual(300); - }); + }); - it('should return a buffer image with width equals 300 and height equals 200', async () => { - const options = { width: 300, height: 200 }; - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer, options); - const dimensions = sizeOf(thumbnail); + it('should return a buffer image with width equals 300 and height equals 200', async () => { + const options = { width: 300, height: 200 }; + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer, options); + const dimensions = sizeOf(thumbnail); - expect(dimensions.width).toEqual(300); - expect(dimensions.height).toEqual(200); - }); + expect(dimensions.width).toEqual(300); + expect(dimensions.height).toEqual(200); + }); - it('should return a buffer image with width quals 200', async () => { - const options = { height: 200 }; - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer, options); - const dimensions = sizeOf(thumbnail); + it('should return a buffer image with width quals 200', async () => { + const options = { height: 200 }; + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer, options); + const dimensions = sizeOf(thumbnail); - expect(dimensions.width).toEqual(301); - expect(dimensions.height).toEqual(200); - }); + expect(dimensions.width).toEqual(301); + expect(dimensions.height).toEqual(200); + }); - it('should return a buffer image with width equals 144 and height equals 96', async () => { - const options = { percentage: 15 }; - const imageBuffer = fs.readFileSync(IMAGE_PATH); - const thumbnail = await imageThumbnail(imageBuffer, options); - const dimensions = sizeOf(thumbnail); + it('should return a buffer image with width equals 144 and height equals 96', async () => { + const options = { percentage: 15 }; + const imageBuffer = fs.readFileSync(IMAGE_PATH); + const thumbnail = await imageThumbnail(imageBuffer, options); + const dimensions = sizeOf(thumbnail); - expect(dimensions.width).toEqual(144); - expect(dimensions.height).toEqual(96); - }); + expect(dimensions.width).toEqual(144); + expect(dimensions.height).toEqual(96); }); + }); - describe('Utils', () => { - describe('RemoveUndefined', () => { - it('should return an object only with height', async () => { - const originalObject = { width: undefined, height: 200 }; + describe('Utils', () => { + describe('RemoveUndefined', () => { + it('should return an object only with height', async () => { + const originalObject = { width: undefined, height: 200 }; - const newObject = util.removeUndefined(originalObject) + const newObject = util.removeUndefined(originalObject) - expect(newObject).toEqual({ height: 200 }); - }); + expect(newObject).toEqual({ height: 200 }); + }); - it('should return an object only with width', async () => { - const originalObject = { width: 200, height: undefined }; + it('should return an object only with width', async () => { + const originalObject = { width: 200, height: undefined }; - const newObject = util.removeUndefined(originalObject) + const newObject = util.removeUndefined(originalObject) - expect(newObject).toEqual({ width: 200 }); + expect(newObject).toEqual({ width: 200 }); - }); + }); - it('should return an object with width and height', async () => { - const originalObject = { width: 200, height: 200 }; + it('should return an object with width and height', async () => { + const originalObject = { width: 200, height: 200 }; - const newObject = util.removeUndefined(originalObject) + const newObject = util.removeUndefined(originalObject) - expect(newObject).toEqual(originalObject); + expect(newObject).toEqual(originalObject); - }); - }); + }); }); + }); }); \ No newline at end of file