sharp 0.32.5 → 0.33.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/output.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  'use strict';
5
5
 
6
- const path = require('path');
6
+ const path = require('node:path');
7
7
  const is = require('./is');
8
8
  const sharp = require('./sharp');
9
9
 
@@ -86,7 +86,8 @@ function toFile (fileOut, callback) {
86
86
  }
87
87
  } else {
88
88
  this.options.fileOut = fileOut;
89
- return this._pipeline(callback);
89
+ const stack = Error();
90
+ return this._pipeline(callback, stack);
90
91
  }
91
92
  return this;
92
93
  }
@@ -157,13 +158,14 @@ function toBuffer (options, callback) {
157
158
  this.options.resolveWithObject = false;
158
159
  }
159
160
  this.options.fileOut = '';
160
- return this._pipeline(is.fn(options) ? options : callback);
161
+ const stack = Error();
162
+ return this._pipeline(is.fn(options) ? options : callback, stack);
161
163
  }
162
164
 
163
165
  /**
164
166
  * Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
165
- * This will also convert to and add a web-friendly sRGB ICC profile unless a custom
166
- * output profile is provided.
167
+ * This will also convert to and add a web-friendly sRGB ICC profile if appropriate,
168
+ * unless a custom output profile is provided.
167
169
  *
168
170
  * The default behaviour, when `withMetadata` is not used, is to convert to the device-independent
169
171
  * sRGB colour space and strip all metadata, including the removal of any ICC profile.
@@ -780,6 +782,7 @@ function trySetAnimationOptions (source, target) {
780
782
  * @param {number} [options.yres=1.0] - vertical resolution in pixels/mm
781
783
  * @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm
782
784
  * @param {number} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit
785
+ * @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite
783
786
  * @returns {Sharp}
784
787
  * @throws {Error} Invalid options
785
788
  */
@@ -817,6 +820,10 @@ function tiff (options) {
817
820
  throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight);
818
821
  }
819
822
  }
823
+ // miniswhite
824
+ if (is.defined(options.miniswhite)) {
825
+ this._setBooleanOption('tiffMiniswhite', options.miniswhite);
826
+ }
820
827
  // pyramid
821
828
  if (is.defined(options.pyramid)) {
822
829
  this._setBooleanOption('tiffPyramid', options.pyramid);
@@ -867,9 +874,6 @@ function tiff (options) {
867
874
  /**
868
875
  * Use these AVIF options for output image.
869
876
  *
870
- * Whilst it is possible to create AVIF images smaller than 16x16 pixels,
871
- * most web browsers do not display these properly.
872
- *
873
877
  * AVIF image sequences are not supported.
874
878
  *
875
879
  * @example
@@ -909,9 +913,9 @@ function avif (options) {
909
913
  *
910
914
  * @since 0.23.0
911
915
  *
912
- * @param {Object} [options] - output options
916
+ * @param {Object} options - output options
917
+ * @param {string} options.compression - compression format: av1, hevc
913
918
  * @param {number} [options.quality=50] - quality, integer 1-100
914
- * @param {string} [options.compression='av1'] - compression format: av1, hevc
915
919
  * @param {boolean} [options.lossless=false] - use lossless compression
916
920
  * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest)
917
921
  * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling
@@ -920,6 +924,11 @@ function avif (options) {
920
924
  */
921
925
  function heif (options) {
922
926
  if (is.object(options)) {
927
+ if (is.string(options.compression) && is.inArray(options.compression, ['av1', 'hevc'])) {
928
+ this.options.heifCompression = options.compression;
929
+ } else {
930
+ throw is.invalidParameterError('compression', 'one of: av1, hevc', options.compression);
931
+ }
923
932
  if (is.defined(options.quality)) {
924
933
  if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
925
934
  this.options.heifQuality = options.quality;
@@ -934,13 +943,6 @@ function heif (options) {
934
943
  throw is.invalidParameterError('lossless', 'boolean', options.lossless);
935
944
  }
936
945
  }
937
- if (is.defined(options.compression)) {
938
- if (is.string(options.compression) && is.inArray(options.compression, ['av1', 'hevc'])) {
939
- this.options.heifCompression = options.compression;
940
- } else {
941
- throw is.invalidParameterError('compression', 'one of: av1, hevc', options.compression);
942
- }
943
- }
944
946
  if (is.defined(options.effort)) {
945
947
  if (is.integer(options.effort) && is.inRange(options.effort, 0, 9)) {
946
948
  this.options.heifEffort = options.effort;
@@ -955,6 +957,8 @@ function heif (options) {
955
957
  throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
956
958
  }
957
959
  }
960
+ } else {
961
+ throw is.invalidParameterError('options', 'Object', options);
958
962
  }
959
963
  return this._updateFormatOut('heif', options);
960
964
  }
@@ -1046,6 +1050,7 @@ function jxl (options) {
1046
1050
  *
1047
1051
  * @param {Object} [options] - output options
1048
1052
  * @param {string} [options.depth='uchar'] - bit depth, one of: char, uchar (default), short, ushort, int, uint, float, complex, double, dpcomplex
1053
+ * @returns {Sharp}
1049
1054
  * @throws {Error} Invalid options
1050
1055
  */
1051
1056
  function raw (options) {
@@ -1284,7 +1289,8 @@ function _read () {
1284
1289
  /* istanbul ignore else */
1285
1290
  if (!this.options.streamOut) {
1286
1291
  this.options.streamOut = true;
1287
- this._pipeline();
1292
+ const stack = Error();
1293
+ this._pipeline(undefined, stack);
1288
1294
  }
1289
1295
  }
1290
1296
 
@@ -1293,18 +1299,30 @@ function _read () {
1293
1299
  * Supports callback, stream and promise variants
1294
1300
  * @private
1295
1301
  */
1296
- function _pipeline (callback) {
1302
+ function _pipeline (callback, stack) {
1297
1303
  if (typeof callback === 'function') {
1298
1304
  // output=file/buffer
1299
1305
  if (this._isStreamInput()) {
1300
1306
  // output=file/buffer, input=stream
1301
1307
  this.on('finish', () => {
1302
1308
  this._flattenBufferIn();
1303
- sharp.pipeline(this.options, callback);
1309
+ sharp.pipeline(this.options, (err, data, info) => {
1310
+ if (err) {
1311
+ callback(is.nativeError(err, stack));
1312
+ } else {
1313
+ callback(null, data, info);
1314
+ }
1315
+ });
1304
1316
  });
1305
1317
  } else {
1306
1318
  // output=file/buffer, input=file/buffer
1307
- sharp.pipeline(this.options, callback);
1319
+ sharp.pipeline(this.options, (err, data, info) => {
1320
+ if (err) {
1321
+ callback(is.nativeError(err, stack));
1322
+ } else {
1323
+ callback(null, data, info);
1324
+ }
1325
+ });
1308
1326
  }
1309
1327
  return this;
1310
1328
  } else if (this.options.streamOut) {
@@ -1315,7 +1333,7 @@ function _pipeline (callback) {
1315
1333
  this._flattenBufferIn();
1316
1334
  sharp.pipeline(this.options, (err, data, info) => {
1317
1335
  if (err) {
1318
- this.emit('error', err);
1336
+ this.emit('error', is.nativeError(err, stack));
1319
1337
  } else {
1320
1338
  this.emit('info', info);
1321
1339
  this.push(data);
@@ -1331,7 +1349,7 @@ function _pipeline (callback) {
1331
1349
  // output=stream, input=file/buffer
1332
1350
  sharp.pipeline(this.options, (err, data, info) => {
1333
1351
  if (err) {
1334
- this.emit('error', err);
1352
+ this.emit('error', is.nativeError(err, stack));
1335
1353
  } else {
1336
1354
  this.emit('info', info);
1337
1355
  this.push(data);
@@ -1350,7 +1368,7 @@ function _pipeline (callback) {
1350
1368
  this._flattenBufferIn();
1351
1369
  sharp.pipeline(this.options, (err, data, info) => {
1352
1370
  if (err) {
1353
- reject(err);
1371
+ reject(is.nativeError(err, stack));
1354
1372
  } else {
1355
1373
  if (this.options.resolveWithObject) {
1356
1374
  resolve({ data, info });
@@ -1366,10 +1384,10 @@ function _pipeline (callback) {
1366
1384
  return new Promise((resolve, reject) => {
1367
1385
  sharp.pipeline(this.options, (err, data, info) => {
1368
1386
  if (err) {
1369
- reject(err);
1387
+ reject(is.nativeError(err, stack));
1370
1388
  } else {
1371
1389
  if (this.options.resolveWithObject) {
1372
- resolve({ data: data, info: info });
1390
+ resolve({ data, info });
1373
1391
  } else {
1374
1392
  resolve(data);
1375
1393
  }
package/lib/resize.js CHANGED
@@ -250,6 +250,9 @@ function resize (widthOrOptions, height, options) {
250
250
  if (isResizeExpected(this.options)) {
251
251
  this.options.debuglog('ignoring previous resize options');
252
252
  }
253
+ if (this.options.widthPost !== -1) {
254
+ this.options.debuglog('operation order will be: extract, resize, extract');
255
+ }
253
256
  if (is.defined(widthOrOptions)) {
254
257
  if (is.object(widthOrOptions) && !is.defined(options)) {
255
258
  options = widthOrOptions;
@@ -437,7 +440,7 @@ function extend (extend) {
437
440
  *
438
441
  * - Use `extract` before `resize` for pre-resize extraction.
439
442
  * - Use `extract` after `resize` for post-resize extraction.
440
- * - Use `extract` before and after for both.
443
+ * - Use `extract` twice and `resize` once for extract-then-resize-then-extract in a fixed operation order.
441
444
  *
442
445
  * @example
443
446
  * sharp(input)
@@ -491,70 +494,67 @@ function extract (options) {
491
494
  *
492
495
  * If the result of this operation would trim an image to nothing then no change is made.
493
496
  *
494
- * The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
495
- * will contain `trimOffsetLeft` and `trimOffsetTop` properties.
497
+ * The `info` response Object will contain `trimOffsetLeft` and `trimOffsetTop` properties.
496
498
  *
497
499
  * @example
498
500
  * // Trim pixels with a colour similar to that of the top-left pixel.
499
- * sharp(input)
501
+ * await sharp(input)
500
502
  * .trim()
501
- * .toFile(output, function(err, info) {
502
- * ...
503
- * });
503
+ * .toFile(output);
504
+ *
504
505
  * @example
505
506
  * // Trim pixels with the exact same colour as that of the top-left pixel.
506
- * sharp(input)
507
- * .trim(0)
508
- * .toFile(output, function(err, info) {
509
- * ...
510
- * });
507
+ * await sharp(input)
508
+ * .trim({
509
+ * threshold: 0
510
+ * })
511
+ * .toFile(output);
512
+ *
511
513
  * @example
512
- * // Trim only pixels with a similar colour to red.
513
- * sharp(input)
514
- * .trim("#FF0000")
515
- * .toFile(output, function(err, info) {
516
- * ...
517
- * });
514
+ * // Assume input is line art and trim only pixels with a similar colour to red.
515
+ * const output = await sharp(input)
516
+ * .trim({
517
+ * background: "#FF0000",
518
+ * lineArt: true
519
+ * })
520
+ * .toBuffer();
521
+ *
518
522
  * @example
519
523
  * // Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
520
- * sharp(input)
524
+ * const output = await sharp(input)
521
525
  * .trim({
522
526
  * background: "yellow",
523
527
  * threshold: 42,
524
528
  * })
525
- * .toFile(output, function(err, info) {
526
- * ...
527
- * });
529
+ * .toBuffer();
528
530
  *
529
- * @param {string|number|Object} trim - the specific background colour to trim, the threshold for doing so or an Object with both.
530
- * @param {string|Object} [trim.background='top-left pixel'] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
531
- * @param {number} [trim.threshold=10] - the allowed difference from the above colour, a positive number.
531
+ * @param {Object} [options]
532
+ * @param {string|Object} [options.background='top-left pixel'] - Background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
533
+ * @param {number} [options.threshold=10] - Allowed difference from the above colour, a positive number.
534
+ * @param {boolean} [options.lineArt=false] - Does the input more closely resemble line art (e.g. vector) rather than being photographic?
532
535
  * @returns {Sharp}
533
536
  * @throws {Error} Invalid parameters
534
537
  */
535
- function trim (trim) {
536
- if (!is.defined(trim)) {
537
- this.options.trimThreshold = 10;
538
- } else if (is.string(trim)) {
539
- this._setBackgroundColourOption('trimBackground', trim);
540
- this.options.trimThreshold = 10;
541
- } else if (is.number(trim)) {
542
- if (trim >= 0) {
543
- this.options.trimThreshold = trim;
544
- } else {
545
- throw is.invalidParameterError('threshold', 'positive number', trim);
546
- }
547
- } else if (is.object(trim)) {
548
- this._setBackgroundColourOption('trimBackground', trim.background);
549
- if (!is.defined(trim.threshold)) {
550
- this.options.trimThreshold = 10;
551
- } else if (is.number(trim.threshold) && trim.threshold >= 0) {
552
- this.options.trimThreshold = trim.threshold;
538
+ function trim (options) {
539
+ this.options.trimThreshold = 10;
540
+ if (is.defined(options)) {
541
+ if (is.object(options)) {
542
+ if (is.defined(options.background)) {
543
+ this._setBackgroundColourOption('trimBackground', options.background);
544
+ }
545
+ if (is.defined(options.threshold)) {
546
+ if (is.number(options.threshold) && options.threshold >= 0) {
547
+ this.options.trimThreshold = options.threshold;
548
+ } else {
549
+ throw is.invalidParameterError('threshold', 'positive number', options.threshold);
550
+ }
551
+ }
552
+ if (is.defined(options.lineArt)) {
553
+ this._setBooleanOption('trimLineArt', options.lineArt);
554
+ }
553
555
  } else {
554
- throw is.invalidParameterError('threshold', 'positive number', trim);
556
+ throw is.invalidParameterError('trim', 'object', options);
555
557
  }
556
- } else {
557
- throw is.invalidParameterError('trim', 'string, number or object', trim);
558
558
  }
559
559
  if (isRotationExpected(this.options)) {
560
560
  this.options.rotateBeforePreExtract = true;
package/lib/sharp.js CHANGED
@@ -3,36 +3,67 @@
3
3
 
4
4
  'use strict';
5
5
 
6
- const platformAndArch = require('./platform')();
6
+ // Inspects the runtime environment and exports the relevant sharp.node binary
7
+
8
+ const { familySync, versionSync } = require('detect-libc');
9
+
10
+ const { runtimePlatformArch, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips');
11
+ const runtimePlatform = runtimePlatformArch();
12
+ const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => runtimePlatform.startsWith(os));
7
13
 
8
14
  /* istanbul ignore next */
9
15
  try {
10
- module.exports = require(`../build/Release/sharp-${platformAndArch}.node`);
11
- } catch (err) {
12
- // Bail early if bindings aren't available
13
- const help = ['', 'Something went wrong installing the "sharp" module', '', err.message, '', 'Possible solutions:'];
14
- if (/dylib/.test(err.message) && /Incompatible library version/.test(err.message)) {
15
- help.push('- Update Homebrew: "brew update && brew upgrade vips"');
16
- } else {
17
- const [platform, arch] = platformAndArch.split('-');
18
- if (platform === 'linux' && /Module did not self-register/.test(err.message)) {
19
- help.push('- Using worker threads? See https://sharp.pixelplumbing.com/install#worker-threads');
20
- }
21
- help.push(
22
- '- Install with verbose logging and look for errors: "npm install --ignore-scripts=false --foreground-scripts --verbose sharp"',
23
- `- Install for the current ${platformAndArch} runtime: "npm install --platform=${platform} --arch=${arch} sharp"`
24
- );
25
- }
26
- help.push(
27
- '- Consult the installation documentation: https://sharp.pixelplumbing.com/install'
28
- );
29
- // Check loaded
30
- if (process.platform === 'win32' || /symbol/.test(err.message)) {
31
- const loadedModule = Object.keys(require.cache).find((i) => /[\\/]build[\\/]Release[\\/]sharp(.*)\.node$/.test(i));
32
- if (loadedModule) {
33
- const [, loadedPackage] = loadedModule.match(/node_modules[\\/]([^\\/]+)[\\/]/);
34
- help.push(`- Ensure the version of sharp aligns with the ${loadedPackage} package: "npm ls sharp"`);
16
+ // Check for local build
17
+ module.exports = require(`../src/build/Release/sharp-${runtimePlatform}.node`);
18
+ } catch (errLocal) {
19
+ try {
20
+ // Check for runtime package
21
+ module.exports = require(`@img/sharp-${runtimePlatform}/sharp.node`);
22
+ } catch (errPackage) {
23
+ const help = ['Could not load the "sharp" module at runtime'];
24
+ if (errLocal.code !== 'MODULE_NOT_FOUND') {
25
+ help.push(`${errLocal.code}: ${errLocal.message}`);
26
+ }
27
+ if (errPackage.code !== 'MODULE_NOT_FOUND') {
28
+ help.push(`${errPackage.code}: ${errPackage.message}`);
29
+ }
30
+ help.push('Possible solutions:');
31
+ // Common error messages
32
+ if (prebuiltPlatforms.includes(runtimePlatform)) {
33
+ help.push('- Add an explicit dependency for the runtime platform:');
34
+ help.push(` npm install --force @img/sharp-${runtimePlatform}`);
35
+ } else {
36
+ help.push(`- The ${runtimePlatform} platform requires manual installation of libvips >= ${minimumLibvipsVersion}`);
37
+ }
38
+ if (isLinux && /symbol not found/i.test(errPackage)) {
39
+ try {
40
+ const { engines } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
41
+ const libcFound = `${familySync()} ${versionSync()}`;
42
+ const libcRequires = `${engines.musl ? 'musl' : 'glibc'} ${engines.musl || engines.glibc}`;
43
+ help.push('- Update your OS:');
44
+ help.push(` Found ${libcFound}`);
45
+ help.push(` Requires ${libcRequires}`);
46
+ } catch (errEngines) {}
47
+ }
48
+ if (isMacOs && /Incompatible library version/.test(errLocal.message)) {
49
+ help.push('- Update Homebrew:');
50
+ help.push(' brew update && brew upgrade vips');
51
+ }
52
+ if (errPackage.code === 'ERR_DLOPEN_DISABLED') {
53
+ help.push('- Run Node.js without using the --no-addons flag');
54
+ }
55
+ if (process.versions.pnp) {
56
+ help.push('- Use a supported yarn linker, either pnpm or node-modules:');
57
+ help.push(' yarn config set nodeLinker node-modules');
58
+ }
59
+ // Link to installation docs
60
+ if (isLinux && /Module did not self-register/.test(errLocal.message + errPackage.message)) {
61
+ help.push('- Using worker threads on Linux? See https://sharp.pixelplumbing.com/install#worker-threads');
62
+ } else if (isWindows && /The specified procedure could not be found/.test(errPackage.message)) {
63
+ help.push('- Using the canvas package on Windows? See https://sharp.pixelplumbing.com/install#canvas-and-windows');
64
+ } else {
65
+ help.push('- Consult the installation documentation: https://sharp.pixelplumbing.com/install');
35
66
  }
67
+ throw new Error(help.join('\n'));
36
68
  }
37
- throw new Error(help.join('\n'));
38
69
  }
package/lib/utility.js CHANGED
@@ -3,15 +3,16 @@
3
3
 
4
4
  'use strict';
5
5
 
6
- const fs = require('fs');
7
- const path = require('path');
8
- const events = require('events');
6
+ const events = require('node:events');
9
7
  const detectLibc = require('detect-libc');
10
8
 
11
9
  const is = require('./is');
12
- const platformAndArch = require('./platform')();
10
+ const { runtimePlatformArch } = require('./libvips');
13
11
  const sharp = require('./sharp');
14
12
 
13
+ const runtimePlatform = runtimePlatformArch();
14
+ const libvipsVersion = sharp.libvipsVersion();
15
+
15
16
  /**
16
17
  * An Object containing nested boolean values representing the available input and output formats/methods.
17
18
  * @member
@@ -46,34 +47,28 @@ const interpolators = {
46
47
  };
47
48
 
48
49
  /**
49
- * An Object containing the version numbers of sharp, libvips and its dependencies.
50
+ * An Object containing the version numbers of sharp, libvips
51
+ * and (when using prebuilt binaries) its dependencies.
52
+ *
50
53
  * @member
51
54
  * @example
52
55
  * console.log(sharp.versions);
53
56
  */
54
57
  let versions = {
55
- vips: sharp.libvipsVersion()
58
+ vips: libvipsVersion.semver
56
59
  };
57
- try {
58
- versions = require(`../vendor/${versions.vips}/${platformAndArch}/versions.json`);
59
- } catch (_err) { /* ignore */ }
60
+ /* istanbul ignore next */
61
+ if (!libvipsVersion.isGlobal) {
62
+ try {
63
+ versions = require(`@img/sharp-${runtimePlatform}/versions`);
64
+ } catch (_) {
65
+ try {
66
+ versions = require(`@img/sharp-libvips-${runtimePlatform}/versions`);
67
+ } catch (_) {}
68
+ }
69
+ }
60
70
  versions.sharp = require('../package.json').version;
61
71
 
62
- /**
63
- * An Object containing the platform and architecture
64
- * of the current and installed vendored binaries.
65
- * @member
66
- * @example
67
- * console.log(sharp.vendor);
68
- */
69
- const vendor = {
70
- current: platformAndArch,
71
- installed: []
72
- };
73
- try {
74
- vendor.installed = fs.readdirSync(path.join(__dirname, `../vendor/${versions.vips}`));
75
- } catch (_err) { /* ignore */ }
76
-
77
72
  /**
78
73
  * Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
79
74
  * Existing entries in the cache will be trimmed after any change in limits.
@@ -280,7 +275,6 @@ module.exports = function (Sharp) {
280
275
  Sharp.format = format;
281
276
  Sharp.interpolators = interpolators;
282
277
  Sharp.versions = versions;
283
- Sharp.vendor = vendor;
284
278
  Sharp.queue = queue;
285
279
  Sharp.block = block;
286
280
  Sharp.unblock = unblock;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sharp",
3
3
  "description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
4
- "version": "0.32.5",
4
+ "version": "0.33.0-alpha.10",
5
5
  "author": "Lovell Fuller <npm@lovell.info>",
6
6
  "homepage": "https://github.com/lovell/sharp",
7
7
  "contributors": [
@@ -86,32 +86,35 @@
86
86
  "Ankur Parihar <ankur.github@gmail.com>",
87
87
  "Brahim Ait elhaj <brahima@gmail.com>",
88
88
  "Mart Jansink <m.jansink@gmail.com>",
89
- "Lachlan Newman <lachnewman007@gmail.com>"
89
+ "Lachlan Newman <lachnewman007@gmail.com>",
90
+ "Dennis Beatty <dennis@dcbeatty.com>"
90
91
  ],
91
92
  "scripts": {
92
- "install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
93
- "clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
93
+ "install": "node install/check",
94
+ "clean": "rm -rf src/build/ .nyc_output/ coverage/ test/fixtures/output.*",
94
95
  "test": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types",
95
96
  "test-lint": "semistandard && cpplint",
96
97
  "test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha",
97
- "test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
98
+ "test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;LGPL-3.0-or-later;MIT\"",
98
99
  "test-leak": "./test/leak/leak.sh",
99
100
  "test-types": "tsd",
101
+ "package-from-local-build": "node npm/from-local-build",
102
+ "package-from-github-release": "node npm/from-github-release",
100
103
  "docs-build": "node docs/build && node docs/search-index/build",
101
104
  "docs-serve": "cd docs && npx serve",
102
105
  "docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
103
106
  },
107
+ "type": "commonjs",
104
108
  "main": "lib/index.js",
105
109
  "types": "lib/index.d.ts",
106
110
  "files": [
107
- "binding.gyp",
108
- "install/**",
109
- "lib/**",
110
- "src/**"
111
+ "install",
112
+ "lib",
113
+ "src/*.{cc,h,gyp}"
111
114
  ],
112
115
  "repository": {
113
116
  "type": "git",
114
- "url": "git://github.com/lovell/sharp"
117
+ "url": "git://github.com/lovell/sharp.git"
115
118
  },
116
119
  "keywords": [
117
120
  "jpeg",
@@ -134,57 +137,59 @@
134
137
  "dependencies": {
135
138
  "color": "^4.2.3",
136
139
  "detect-libc": "^2.0.2",
137
- "node-addon-api": "^6.1.0",
138
- "prebuild-install": "^7.1.1",
139
- "semver": "^7.5.4",
140
- "simple-get": "^4.0.1",
141
- "tar-fs": "^3.0.4",
142
- "tunnel-agent": "^0.6.0"
140
+ "semver": "^7.5.4"
141
+ },
142
+ "optionalDependencies": {
143
+ "@img/sharp-darwin-arm64": "0.33.0-alpha.10",
144
+ "@img/sharp-darwin-x64": "0.33.0-alpha.10",
145
+ "@img/sharp-libvips-darwin-arm64": "0.0.3",
146
+ "@img/sharp-libvips-darwin-x64": "0.0.3",
147
+ "@img/sharp-libvips-linux-arm": "0.0.3",
148
+ "@img/sharp-libvips-linux-arm64": "0.0.3",
149
+ "@img/sharp-libvips-linux-s390x": "0.0.3",
150
+ "@img/sharp-libvips-linux-x64": "0.0.3",
151
+ "@img/sharp-libvips-linuxmusl-arm64": "0.0.3",
152
+ "@img/sharp-libvips-linuxmusl-x64": "0.0.3",
153
+ "@img/sharp-linux-arm": "0.33.0-alpha.10",
154
+ "@img/sharp-linux-arm64": "0.33.0-alpha.10",
155
+ "@img/sharp-linux-s390x": "0.33.0-alpha.10",
156
+ "@img/sharp-linux-x64": "0.33.0-alpha.10",
157
+ "@img/sharp-linuxmusl-arm64": "0.33.0-alpha.10",
158
+ "@img/sharp-linuxmusl-x64": "0.33.0-alpha.10",
159
+ "@img/sharp-win32-ia32": "0.33.0-alpha.10",
160
+ "@img/sharp-win32-x64": "0.33.0-alpha.10"
143
161
  },
144
162
  "devDependencies": {
163
+ "@img/sharp-libvips-dev": "0.0.3",
164
+ "@img/sharp-libvips-win32-ia32": "0.0.3",
165
+ "@img/sharp-libvips-win32-x64": "0.0.3",
145
166
  "@types/node": "*",
146
167
  "async": "^3.2.4",
147
168
  "cc": "^3.0.1",
148
- "exif-reader": "^1.2.0",
169
+ "exif-reader": "^2.0.0",
149
170
  "extract-zip": "^2.0.1",
150
171
  "icc": "^3.0.0",
151
172
  "jsdoc-to-markdown": "^8.0.0",
152
173
  "license-checker": "^25.0.1",
153
174
  "mocha": "^10.2.0",
154
- "mock-fs": "^5.2.0",
175
+ "node-addon-api": "^7.0.0",
155
176
  "nyc": "^15.1.0",
156
- "prebuild": "lovell/prebuild#add-nodejs-20-drop-nodejs-10-and-12",
157
- "semistandard": "^16.0.1",
158
- "tsd": "^0.28.1"
177
+ "prebuild": "^12.1.0",
178
+ "semistandard": "^17.0.0",
179
+ "tar-fs": "^3.0.4",
180
+ "tsd": "^0.29.0"
159
181
  },
160
182
  "license": "Apache-2.0",
161
- "config": {
162
- "libvips": "8.14.4",
163
- "integrity": {
164
- "darwin-arm64v8": "sha512-jZt5+ZBQzdloop9z/XlOAy8jHxD+ZGt3J8YUm1g3njjjKmZ/RmM9r6QAeLLILe67ATHaaAtmCil37fDc400OrQ==",
165
- "darwin-x64": "sha512-Mhpr8n8CjrU+u5K9YLucmkCgwtJGexECLOZejPfqM8CiOMerowR0wJTuSt9WTOtb9qGOL/ndybfrymsw+YH8PA==",
166
- "linux-arm64v8": "sha512-k2PiOOv8amzS4m5jc4Vceozv8h041IoyHL/1s0Rj290jg3w6BUJL3V+TLwKUPM35i7rV5rm14gtnGZ7qKENdmA==",
167
- "linux-armv6": "sha512-CuPTo50owR8P+BCCcWk1tF4qB3XSAaHeaIzSanJM/v9zBZfUfMGI0OLv+ByyHCL3BE2CbGXaSXhuEVw2JQ08Sw==",
168
- "linux-armv7": "sha512-CvD6fMy9PkZk1m2UPTWDcFfcD4qFA3RALyAWIih8ftOY9ksI3Y4uz6c0ML+ixBl0hqQK3WEg6+ac5TGDjZbbYA==",
169
- "linux-x64": "sha512-vqoV61ka2hBYQ5582nQlyUcVPtItu927mng9RUU9nyO4Wt50z9nNT/pfcYEfF2jkBNW9JaiMaj6bENHgxA6mMg==",
170
- "linuxmusl-arm64v8": "sha512-iCyl0y/qxdvgGidsYn11R8d4TEcU92uYHtYI8FSHyUobZw/9i2y3189PUTQ/fw44oqaBzTR3p9NF2eP6aLT9gQ==",
171
- "linuxmusl-x64": "sha512-qj7IUqWUqCtxECpgNp4E1NcIbsNe1ujzBuJcnnQot7GZOuPUhI5N6ZUhozmh6LfbGFdBZpPc/JFh1eDZ0IEpbQ==",
172
- "win32-arm64v8": "sha512-VRi7fpE9Kb3xQGcNmPPTJnWGAEUMq+YOq9abpaIIB2r3Ax327/7wHS7o2ezD6zQKdxIX6gODC5io/hReIJ9Jnw==",
173
- "win32-ia32": "sha512-EnvtU7Q6+pjl5/Y1/UngCFDM2CSqpYWVDwY03ilUKSuqTeDKTJYyus0rJ+n6p4nmdjJlVdhYlkvpy8kkEAtDHg==",
174
- "win32-x64": "sha512-fCl/KQuSijVYC8hULWbff8Mfuh3vjjdz4j5p73VgdLP6aZUrHctbhBvEIe0aQ8HpmcGdBnATX5pXUQ4GDl3mwQ=="
175
- },
176
- "runtime": "napi",
177
- "target": 7
178
- },
179
183
  "engines": {
180
- "node": ">=14.15.0"
184
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
185
+ "libvips": ">=8.15.0"
181
186
  },
182
187
  "funding": {
183
188
  "url": "https://opencollective.com/libvips"
184
189
  },
185
190
  "binary": {
186
191
  "napi_versions": [
187
- 7
192
+ 9
188
193
  ]
189
194
  },
190
195
  "semistandard": {