Skip to content

Commit

Permalink
Require Node.js 18
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed May 5, 2024
1 parent 6832717 commit 0f2a0aa
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 95 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@ jobs:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
- 22
- 18
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
52 changes: 26 additions & 26 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import {Buffer} from 'node:buffer';
import {promises as fsPromises} from 'node:fs';
import {promisify} from 'node:util';
import fsPromises from 'node:fs/promises';
import path from 'node:path';
import fs from 'graceful-fs';
import FileType from 'file-type';
import {fileTypeFromBuffer} from 'file-type';
import {globby} from 'globby';
import pPipe from 'p-pipe';
import replaceExt from 'replace-ext';
import junk from 'junk';
import changeFileExtension from 'change-file-extension';
import {isNotJunk} from 'junk';
import convertToUnixPath from 'slash';

const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
import {assertUint8Array} from 'uint8array-extras';
import {isBrowser} from 'environment';
import ow from 'ow';

const handleFile = async (sourcePath, {destination, plugins = []}) => {
if (plugins && !Array.isArray(plugins)) {
throw new TypeError('The `plugins` option should be an `Array`');
}
ow(plugins, ow.optional.array.message('The `plugins` option should be an `Array`'));

let data = await readFile(sourcePath);
let data = await fsPromises.readFile(sourcePath);
data = await (plugins.length > 0 ? pPipe(...plugins)(data) : data);

const {ext} = await FileType.fromBuffer(data) || {ext: path.extname(sourcePath)};
const {ext} = await fileTypeFromBuffer(data) ?? {ext: path.extname(sourcePath)};
let destinationPath = destination ? path.join(destination, path.basename(sourcePath)) : undefined;
destinationPath = ext === 'webp' ? replaceExt(destinationPath, '.webp') : destinationPath;
destinationPath = ext === 'webp' ? changeFileExtension(destinationPath, 'webp') : destinationPath;

const returnValue = {
data,
data: new Uint8Array(data),
sourcePath,
destinationPath,
};
Expand All @@ -36,22 +31,24 @@ const handleFile = async (sourcePath, {destination, plugins = []}) => {
}

await fsPromises.mkdir(path.dirname(returnValue.destinationPath), {recursive: true});
await writeFile(returnValue.destinationPath, returnValue.data);
await fsPromises.writeFile(returnValue.destinationPath, returnValue.data);

return returnValue;
};

export default async function imagemin(input, {glob = true, ...options} = {}) {
if (!Array.isArray(input)) {
throw new TypeError(`Expected an \`Array\`, got \`${typeof input}\``);
if (isBrowser) {
throw new Error('This package does not work in the browser.');
}

ow(input, ow.array);

const unixFilePaths = input.map(path => convertToUnixPath(path));
const filePaths = glob ? await globby(unixFilePaths, {onlyFiles: true}) : input;

return Promise.all(
filePaths
.filter(filePath => junk.not(path.basename(filePath)))
.filter(filePath => isNotJunk(path.basename(filePath)))
.map(async filePath => {
try {
return await handleFile(filePath, options);
Expand All @@ -63,14 +60,17 @@ export default async function imagemin(input, {glob = true, ...options} = {}) {
);
}

imagemin.buffer = async (input, {plugins = []} = {}) => {
if (!Buffer.isBuffer(input)) {
throw new TypeError(`Expected a \`Buffer\`, got \`${typeof input}\``);
imagemin.buffer = async (data, {plugins = []} = {}) => {
if (isBrowser) {
throw new Error('This package does not work in the browser.');
}

assertUint8Array(data);

if (plugins.length === 0) {
return input;
return new Uint8Array(data);
}

return pPipe(...plugins)(input);
// The `new Uint8Array` can be removed if all plugins are changed to return `Uint8Array` instead of `Buffer`.
return new Uint8Array(await pPipe(...plugins)(data));
};
30 changes: 16 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
"description": "Minify images seamlessly",
"license": "MIT",
"repository": "imagemin/imagemin",
"funding": "https://github.com/sponsors/sindresorhus",
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=12"
"node": ">=18"
},
"scripts": {
"test": "xo && ava"
Expand All @@ -27,22 +28,23 @@
"svg"
],
"dependencies": {
"file-type": "^16.5.3",
"globby": "^12.0.0",
"graceful-fs": "^4.2.8",
"junk": "^3.1.0",
"change-file-extension": "^0.1.1",
"environment": "^1.0.0",
"file-type": "^19.0.0",
"globby": "^14.0.1",
"junk": "^4.0.1",
"ow": "^2.0.0",
"p-pipe": "^4.0.0",
"replace-ext": "^2.0.0",
"slash": "^3.0.0"
"slash": "^5.1.0",
"uint8array-extras": "^1.1.0"
},
"devDependencies": {
"ava": "^3.15.0",
"del": "^6.0.0",
"ava": "^6.1.2",
"del": "^7.1.0",
"imagemin-jpegtran": "^7.0.0",
"imagemin-svgo": "^9.0.0",
"imagemin-webp": "^6.0.0",
"is-jpg": "^2.0.0",
"tempy": "^1.0.1",
"xo": "^0.43.0"
"imagemin-svgo": "^10.0.1",
"imagemin-webp": "^8.0.0",
"tempy": "^3.1.0",
"xo": "^0.58.0"
}
}
35 changes: 10 additions & 25 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,6 @@
</a>
<br>
<br>
<br>
<a href="https://doppler.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=imagemin&utm_source=github">
<div>
<img src="https://dashboard.doppler.com/imgs/logo-long.svg" width="240" alt="Doppler">
</div>
<b>All your environment variables, in one place</b>
<div>
<span>Stop struggling with scattered API keys, hacking together home-brewed tools,</span>
<br>
<span>and avoiding access controls. Keep your team and servers in sync with Doppler.</span>
</div>
</a>
<br>
<a href="https://strapi.io/?ref=sindresorhus">
<div>
<img src="https://sindresorhus.com/assets/thanks/strapi-logo-white-bg.png" width="200" alt="Strapi">
Expand All @@ -52,8 +39,8 @@

## Install

```
$ npm install imagemin
```sh
npm install imagemin
```

## Usage
Expand All @@ -74,14 +61,14 @@ const files = await imagemin(['images/*.{jpg,png}'], {
});

console.log(files);
//=> [{data: <Buffer 89 50 4e …>, destinationPath: 'build/images/foo.jpg'}, …]
//=> [{data: <Uint8Array 89 50 4e …>, destinationPath: 'build/images/foo.jpg'}, …]
```

## API

### imagemin(input, options?)

Returns `Promise<object[]>` in the format `{data: Buffer, sourcePath: string, destinationPath: string}`.
Returns `Promise<object[]>` in the format `{data: Uint8Array, sourcePath: string, destinationPath: string}`.

#### input

Expand All @@ -103,7 +90,7 @@ Set the destination folder to where your files will be written. If no destinatio

Type: `Array`

[Plugins](https://www.npmjs.com/browse/keyword/imageminplugin) to use.
The [plugins](https://www.npmjs.com/browse/keyword/imageminplugin) to use.

##### glob

Expand All @@ -112,15 +99,15 @@ Default: `true`

Enable globbing when matching file paths.

### imagemin.buffer(buffer, options?)
### imagemin.buffer(data, options?)

Returns `Promise<Buffer>`.
Returns `Promise<Uint8Array>`.

#### buffer
#### data

Type: `Buffer`
Type: `Uint8Array`

Buffer to optimize.
The image data to optimize.

#### options

Expand All @@ -135,6 +122,4 @@ Type: `Array`
## Related

- [imagemin-cli](https://github.com/imagemin/imagemin-cli) - CLI for this module
- [imagemin-app](https://github.com/imagemin/imagemin-app) - GUI app for this module
- [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) - Gulp plugin
- [grunt-contrib-imagemin](https://github.com/gruntjs/grunt-contrib-imagemin) - Grunt plugin

0 comments on commit 0f2a0aa

Please sign in to comment.