sharp 0.33.5 → 0.35.0
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/README.md +12 -18
- package/dist/channel.cjs +177 -0
- package/{lib/channel.js → dist/channel.mjs} +11 -8
- package/dist/colour.cjs +195 -0
- package/{lib/colour.js → dist/colour.mjs} +38 -23
- package/dist/composite.cjs +213 -0
- package/{lib/composite.js → dist/composite.mjs} +14 -11
- package/{lib/constructor.js → dist/constructor.cjs} +102 -43
- package/dist/constructor.mjs +511 -0
- package/dist/index.cjs +25 -0
- package/dist/index.mjs +25 -0
- package/dist/input.cjs +814 -0
- package/{lib/input.js → dist/input.mjs} +224 -68
- package/{lib/is.js → dist/is.cjs} +19 -45
- package/dist/is.mjs +143 -0
- package/{lib/libvips.js → dist/libvips.cjs} +52 -43
- package/dist/libvips.mjs +212 -0
- package/dist/operation.cjs +987 -0
- package/{lib/operation.js → dist/operation.mjs} +108 -79
- package/{lib/output.js → dist/output.cjs} +243 -36
- package/dist/output.mjs +1794 -0
- package/dist/resize.cjs +613 -0
- package/{lib/resize.js → dist/resize.mjs} +38 -12
- package/dist/sharp.cjs +164 -0
- package/dist/sharp.mjs +164 -0
- package/{lib/utility.js → dist/utility.cjs} +23 -24
- package/dist/utility.mjs +295 -0
- package/install/build.js +38 -0
- package/lib/index.d.ts +347 -125
- package/package.json +75 -84
- package/src/binding.gyp +49 -26
- package/src/common.cc +203 -111
- package/src/common.h +68 -40
- package/src/metadata.cc +106 -22
- package/src/metadata.h +15 -5
- package/src/operations.cc +62 -21
- package/src/operations.h +15 -3
- package/src/pipeline.cc +374 -183
- package/src/pipeline.h +34 -7
- package/src/sharp.cc +11 -8
- package/src/stats.cc +16 -13
- package/src/stats.h +6 -3
- package/src/utilities.cc +32 -12
- package/src/utilities.h +5 -2
- package/install/check.js +0 -41
- package/lib/index.js +0 -16
- package/lib/sharp.js +0 -114
package/dist/is.mjs
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Is this value defined and not null?
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
const defined = (val) => typeof val !== 'undefined' && val !== null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Is this value an object?
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
const object = (val) => typeof val === 'object';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Is this value a plain object?
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
const plainObject = (val) => Object.prototype.toString.call(val) === '[object Object]';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Is this value a function?
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
const fn = (val) => typeof val === 'function';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Is this value a boolean?
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
const bool = (val) => typeof val === 'boolean';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Is this value a Buffer object?
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
const buffer = (val) => val instanceof Buffer;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Is this value a typed array object?. E.g. Uint8Array or Uint8ClampedArray?
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
const typedArray = (val) => {
|
|
47
|
+
if (defined(val)) {
|
|
48
|
+
switch (val.constructor) {
|
|
49
|
+
case Uint8Array:
|
|
50
|
+
case Uint8ClampedArray:
|
|
51
|
+
case Int8Array:
|
|
52
|
+
case Uint16Array:
|
|
53
|
+
case Int16Array:
|
|
54
|
+
case Uint32Array:
|
|
55
|
+
case Int32Array:
|
|
56
|
+
case Float32Array:
|
|
57
|
+
case Float64Array:
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return false;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Is this value an ArrayBuffer object?
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
const arrayBuffer = (val) => val instanceof ArrayBuffer;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Is this value a non-empty string?
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
const string = (val) => typeof val === 'string' && val.length > 0;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Is this value a real number?
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
const number = (val) => typeof val === 'number' && !Number.isNaN(val);
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Is this value an integer?
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
const integer = (val) => Number.isInteger(val);
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Is this value within an inclusive given range?
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
const inRange = (val, min, max) => val >= min && val <= max;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Is this value within the elements of an array?
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
const inArray = (val, list) => list.includes(val);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Create an Error with a message relating to an invalid parameter.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} name - parameter name.
|
|
105
|
+
* @param {string} expected - description of the type/value/range expected.
|
|
106
|
+
* @param {*} actual - the value received.
|
|
107
|
+
* @returns {Error} Containing the formatted message.
|
|
108
|
+
* @private
|
|
109
|
+
*/
|
|
110
|
+
const invalidParameterError = (name, expected, actual) => new Error(
|
|
111
|
+
`Expected ${expected} for ${name} but received ${actual} of type ${typeof actual}`
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Ensures an Error from C++ contains a JS stack.
|
|
116
|
+
*
|
|
117
|
+
* @param {Error} native - Error with message from C++.
|
|
118
|
+
* @param {Error} context - Error with stack from JS.
|
|
119
|
+
* @returns {Error} Error with message and stack.
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
const nativeError = (native, context) => {
|
|
123
|
+
context.message = native.message;
|
|
124
|
+
return context;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export default {
|
|
128
|
+
defined,
|
|
129
|
+
object,
|
|
130
|
+
plainObject,
|
|
131
|
+
fn,
|
|
132
|
+
bool,
|
|
133
|
+
buffer,
|
|
134
|
+
typedArray,
|
|
135
|
+
arrayBuffer,
|
|
136
|
+
string,
|
|
137
|
+
number,
|
|
138
|
+
integer,
|
|
139
|
+
inRange,
|
|
140
|
+
inArray,
|
|
141
|
+
invalidParameterError,
|
|
142
|
+
nativeError
|
|
143
|
+
};
|
|
@@ -1,26 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
5
|
|
|
6
6
|
const { spawnSync } = require('node:child_process');
|
|
7
7
|
const { createHash } = require('node:crypto');
|
|
8
|
-
const
|
|
9
|
-
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
|
10
|
-
const semverSatisfies = require('semver/functions/satisfies');
|
|
8
|
+
const semver = require('semver');
|
|
11
9
|
const detectLibc = require('detect-libc');
|
|
10
|
+
const pkg = require('../package.json');
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
config.libvips;
|
|
17
|
-
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
|
12
|
+
/* node:coverage ignore next */
|
|
13
|
+
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || pkg.config.libvips;
|
|
14
|
+
const minimumLibvipsVersion = semver.coerce(minimumLibvipsVersionLabelled).version;
|
|
18
15
|
|
|
19
16
|
const prebuiltPlatforms = [
|
|
20
17
|
'darwin-arm64', 'darwin-x64',
|
|
21
|
-
'
|
|
18
|
+
'freebsd-arm64', 'freebsd-x64',
|
|
19
|
+
'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-riscv64', 'linux-s390x', 'linux-wasm32', 'linux-x64',
|
|
22
20
|
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
23
|
-
'win32-ia32', 'win32-x64'
|
|
21
|
+
'win32-arm64', 'win32-ia32', 'win32-x64'
|
|
24
22
|
];
|
|
25
23
|
|
|
26
24
|
const spawnSyncOptions = {
|
|
@@ -36,17 +34,16 @@ const log = (item) => {
|
|
|
36
34
|
}
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
/*
|
|
37
|
+
/* node:coverage disable */
|
|
38
|
+
|
|
40
39
|
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
|
41
40
|
|
|
42
41
|
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
|
43
42
|
|
|
44
|
-
/* istanbul ignore next */
|
|
45
43
|
const buildPlatformArch = () => {
|
|
46
44
|
if (isEmscripten()) {
|
|
47
45
|
return 'wasm32';
|
|
48
46
|
}
|
|
49
|
-
/* eslint camelcase: ["error", { allow: ["^npm_config_"] }] */
|
|
50
47
|
const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env;
|
|
51
48
|
const libc = typeof npm_config_libc === 'string' ? npm_config_libc : runtimeLibc();
|
|
52
49
|
return `${npm_config_platform || process.platform}${libc}-${npm_config_arch || process.arch}`;
|
|
@@ -60,7 +57,6 @@ const buildSharpLibvipsIncludeDir = () => {
|
|
|
60
57
|
return require('@img/sharp-libvips-dev/include');
|
|
61
58
|
} catch {}
|
|
62
59
|
}
|
|
63
|
-
/* istanbul ignore next */
|
|
64
60
|
return '';
|
|
65
61
|
};
|
|
66
62
|
|
|
@@ -68,7 +64,6 @@ const buildSharpLibvipsCPlusPlusDir = () => {
|
|
|
68
64
|
try {
|
|
69
65
|
return require('@img/sharp-libvips-dev/cplusplus');
|
|
70
66
|
} catch {}
|
|
71
|
-
/* istanbul ignore next */
|
|
72
67
|
return '';
|
|
73
68
|
};
|
|
74
69
|
|
|
@@ -80,27 +75,23 @@ const buildSharpLibvipsLibDir = () => {
|
|
|
80
75
|
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
81
76
|
} catch {}
|
|
82
77
|
}
|
|
83
|
-
/* istanbul ignore next */
|
|
84
78
|
return '';
|
|
85
79
|
};
|
|
86
80
|
|
|
87
81
|
const isUnsupportedNodeRuntime = () => {
|
|
88
|
-
/* istanbul ignore next */
|
|
89
82
|
if (process.release?.name === 'node' && process.versions) {
|
|
90
|
-
if (!
|
|
91
|
-
return { found: process.versions.node, expected: engines.node };
|
|
83
|
+
if (!semver.satisfies(process.versions.node, pkg.engines.node)) {
|
|
84
|
+
return { found: process.versions.node, expected: pkg.engines.node };
|
|
92
85
|
}
|
|
93
86
|
}
|
|
94
87
|
};
|
|
95
88
|
|
|
96
|
-
/* istanbul ignore next */
|
|
97
89
|
const isEmscripten = () => {
|
|
98
90
|
const { CC } = process.env;
|
|
99
|
-
return Boolean(CC
|
|
91
|
+
return Boolean(CC?.endsWith('/emcc'));
|
|
100
92
|
};
|
|
101
93
|
|
|
102
94
|
const isRosetta = () => {
|
|
103
|
-
/* istanbul ignore next */
|
|
104
95
|
if (process.platform === 'darwin' && process.arch === 'x64') {
|
|
105
96
|
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
|
106
97
|
return (translated || '').trim() === 'sysctl.proc_translated: 1';
|
|
@@ -108,18 +99,23 @@ const isRosetta = () => {
|
|
|
108
99
|
return false;
|
|
109
100
|
};
|
|
110
101
|
|
|
102
|
+
/* node:coverage enable */
|
|
103
|
+
|
|
111
104
|
const sha512 = (s) => createHash('sha512').update(s).digest('hex');
|
|
112
105
|
|
|
113
106
|
const yarnLocator = () => {
|
|
114
107
|
try {
|
|
115
108
|
const identHash = sha512(`imgsharp-libvips-${buildPlatformArch()}`);
|
|
116
|
-
const npmVersion =
|
|
109
|
+
const npmVersion = semver.coerce(pkg.optionalDependencies[`@img/sharp-libvips-${buildPlatformArch()}`], {
|
|
110
|
+
includePrerelease: true
|
|
111
|
+
}).version;
|
|
117
112
|
return sha512(`${identHash}npm:${npmVersion}`).slice(0, 10);
|
|
118
113
|
} catch {}
|
|
119
114
|
return '';
|
|
120
115
|
};
|
|
121
116
|
|
|
122
|
-
/*
|
|
117
|
+
/* node:coverage disable */
|
|
118
|
+
|
|
123
119
|
const spawnRebuild = () =>
|
|
124
120
|
spawnSync(`node-gyp rebuild --directory=src ${isEmscripten() ? '--nodedir=emscripten' : ''}`, {
|
|
125
121
|
...spawnSyncOptions,
|
|
@@ -135,27 +131,40 @@ const globalLibvipsVersion = () => {
|
|
|
135
131
|
PKG_CONFIG_PATH: pkgConfigPath()
|
|
136
132
|
}
|
|
137
133
|
}).stdout;
|
|
138
|
-
/* istanbul ignore next */
|
|
139
134
|
return (globalLibvipsVersion || '').trim();
|
|
140
135
|
} else {
|
|
141
136
|
return '';
|
|
142
137
|
}
|
|
143
138
|
};
|
|
144
139
|
|
|
145
|
-
|
|
140
|
+
const getBrewPkgConfigPath = () => {
|
|
141
|
+
try {
|
|
142
|
+
const brewPrefix = (spawnSync('brew', ['--prefix'], { encoding: 'utf8' }).stdout || '').trim();
|
|
143
|
+
if (brewPrefix) {
|
|
144
|
+
return `${brewPrefix}/lib/pkgconfig`;
|
|
145
|
+
}
|
|
146
|
+
} catch (_err) {}
|
|
147
|
+
return undefined;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const getPkgConfigPath = () => {
|
|
151
|
+
try {
|
|
152
|
+
const pkgConfigPath = (spawnSync('pkg-config', ['--variable', 'pc_path', 'pkg-config'], { encoding: 'utf8' }).stdout || '').trim();
|
|
153
|
+
if (pkgConfigPath) {
|
|
154
|
+
return pkgConfigPath;
|
|
155
|
+
}
|
|
156
|
+
} catch (_err) {}
|
|
157
|
+
return undefined;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/* node:coverage enable */
|
|
161
|
+
|
|
146
162
|
const pkgConfigPath = () => {
|
|
147
163
|
if (process.platform !== 'win32') {
|
|
148
|
-
const brewPkgConfigPath = spawnSync(
|
|
149
|
-
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
|
150
|
-
spawnSyncOptions
|
|
151
|
-
).stdout || '';
|
|
152
164
|
return [
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
'/usr/lib/pkgconfig',
|
|
157
|
-
'/usr/local/libdata/pkgconfig',
|
|
158
|
-
'/usr/libdata/pkgconfig'
|
|
165
|
+
getBrewPkgConfigPath(),
|
|
166
|
+
getPkgConfigPath(),
|
|
167
|
+
process.env.PKG_CONFIG_PATH
|
|
159
168
|
].filter(Boolean).join(':');
|
|
160
169
|
} else {
|
|
161
170
|
return '';
|
|
@@ -176,13 +185,13 @@ const useGlobalLibvips = (logger) => {
|
|
|
176
185
|
if (Boolean(process.env.SHARP_FORCE_GLOBAL_LIBVIPS) === true) {
|
|
177
186
|
return skipSearch(true, 'SHARP_FORCE_GLOBAL_LIBVIPS', logger);
|
|
178
187
|
}
|
|
179
|
-
/*
|
|
188
|
+
/* node:coverage ignore next 3 */
|
|
180
189
|
if (isRosetta()) {
|
|
181
190
|
return skipSearch(false, 'Rosetta', logger);
|
|
182
191
|
}
|
|
183
192
|
const globalVipsVersion = globalLibvipsVersion();
|
|
184
|
-
|
|
185
|
-
|
|
193
|
+
/* node:coverage ignore next */
|
|
194
|
+
return !!globalVipsVersion && semver.gte(globalVipsVersion, minimumLibvipsVersion);
|
|
186
195
|
};
|
|
187
196
|
|
|
188
197
|
module.exports = {
|
package/dist/libvips.mjs
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
Copyright 2013 Lovell Fuller and others.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
8
|
+
import semver from 'semver';
|
|
9
|
+
import detectLibc from 'detect-libc';
|
|
10
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
11
|
+
|
|
12
|
+
/* node:coverage ignore next */
|
|
13
|
+
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || pkg.config.libvips;
|
|
14
|
+
const minimumLibvipsVersion = semver.coerce(minimumLibvipsVersionLabelled).version;
|
|
15
|
+
|
|
16
|
+
const prebuiltPlatforms = [
|
|
17
|
+
'darwin-arm64', 'darwin-x64',
|
|
18
|
+
'freebsd-arm64', 'freebsd-x64',
|
|
19
|
+
'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-riscv64', 'linux-s390x', 'linux-wasm32', 'linux-x64',
|
|
20
|
+
'linuxmusl-arm64', 'linuxmusl-x64',
|
|
21
|
+
'win32-arm64', 'win32-ia32', 'win32-x64'
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const spawnSyncOptions = {
|
|
25
|
+
encoding: 'utf8',
|
|
26
|
+
shell: true
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const log = (item) => {
|
|
30
|
+
if (item instanceof Error) {
|
|
31
|
+
console.error(`sharp: Installation error: ${item.message}`);
|
|
32
|
+
} else {
|
|
33
|
+
console.log(`sharp: ${item}`);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/* node:coverage disable */
|
|
38
|
+
|
|
39
|
+
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
|
40
|
+
|
|
41
|
+
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
|
42
|
+
|
|
43
|
+
const buildPlatformArch = () => {
|
|
44
|
+
if (isEmscripten()) {
|
|
45
|
+
return 'wasm32';
|
|
46
|
+
}
|
|
47
|
+
const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env;
|
|
48
|
+
const libc = typeof npm_config_libc === 'string' ? npm_config_libc : runtimeLibc();
|
|
49
|
+
return `${npm_config_platform || process.platform}${libc}-${npm_config_arch || process.arch}`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const buildSharpLibvipsIncludeDir = () => {
|
|
53
|
+
try {
|
|
54
|
+
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/include`);
|
|
55
|
+
} catch {
|
|
56
|
+
try {
|
|
57
|
+
return require('@img/sharp-libvips-dev/include');
|
|
58
|
+
} catch {}
|
|
59
|
+
}
|
|
60
|
+
return '';
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const buildSharpLibvipsCPlusPlusDir = () => {
|
|
64
|
+
try {
|
|
65
|
+
return require('@img/sharp-libvips-dev/cplusplus');
|
|
66
|
+
} catch {}
|
|
67
|
+
return '';
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const buildSharpLibvipsLibDir = () => {
|
|
71
|
+
try {
|
|
72
|
+
return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/lib`);
|
|
73
|
+
} catch {
|
|
74
|
+
try {
|
|
75
|
+
return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`);
|
|
76
|
+
} catch {}
|
|
77
|
+
}
|
|
78
|
+
return '';
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const isUnsupportedNodeRuntime = () => {
|
|
82
|
+
if (process.release?.name === 'node' && process.versions) {
|
|
83
|
+
if (!semver.satisfies(process.versions.node, pkg.engines.node)) {
|
|
84
|
+
return { found: process.versions.node, expected: pkg.engines.node };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const isEmscripten = () => {
|
|
90
|
+
const { CC } = process.env;
|
|
91
|
+
return Boolean(CC?.endsWith('/emcc'));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const isRosetta = () => {
|
|
95
|
+
if (process.platform === 'darwin' && process.arch === 'x64') {
|
|
96
|
+
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
|
97
|
+
return (translated || '').trim() === 'sysctl.proc_translated: 1';
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/* node:coverage enable */
|
|
103
|
+
|
|
104
|
+
const sha512 = (s) => createHash('sha512').update(s).digest('hex');
|
|
105
|
+
|
|
106
|
+
const yarnLocator = () => {
|
|
107
|
+
try {
|
|
108
|
+
const identHash = sha512(`imgsharp-libvips-${buildPlatformArch()}`);
|
|
109
|
+
const npmVersion = semver.coerce(pkg.optionalDependencies[`@img/sharp-libvips-${buildPlatformArch()}`], {
|
|
110
|
+
includePrerelease: true
|
|
111
|
+
}).version;
|
|
112
|
+
return sha512(`${identHash}npm:${npmVersion}`).slice(0, 10);
|
|
113
|
+
} catch {}
|
|
114
|
+
return '';
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/* node:coverage disable */
|
|
118
|
+
|
|
119
|
+
const spawnRebuild = () =>
|
|
120
|
+
spawnSync(`node-gyp rebuild --directory=src ${isEmscripten() ? '--nodedir=emscripten' : ''}`, {
|
|
121
|
+
...spawnSyncOptions,
|
|
122
|
+
stdio: 'inherit'
|
|
123
|
+
}).status;
|
|
124
|
+
|
|
125
|
+
const globalLibvipsVersion = () => {
|
|
126
|
+
if (process.platform !== 'win32') {
|
|
127
|
+
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
|
128
|
+
...spawnSyncOptions,
|
|
129
|
+
env: {
|
|
130
|
+
...process.env,
|
|
131
|
+
PKG_CONFIG_PATH: pkgConfigPath()
|
|
132
|
+
}
|
|
133
|
+
}).stdout;
|
|
134
|
+
return (globalLibvipsVersion || '').trim();
|
|
135
|
+
} else {
|
|
136
|
+
return '';
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const getBrewPkgConfigPath = () => {
|
|
141
|
+
try {
|
|
142
|
+
const brewPrefix = (spawnSync('brew', ['--prefix'], { encoding: 'utf8' }).stdout || '').trim();
|
|
143
|
+
if (brewPrefix) {
|
|
144
|
+
return `${brewPrefix}/lib/pkgconfig`;
|
|
145
|
+
}
|
|
146
|
+
} catch (_err) {}
|
|
147
|
+
return undefined;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const getPkgConfigPath = () => {
|
|
151
|
+
try {
|
|
152
|
+
const pkgConfigPath = (spawnSync('pkg-config', ['--variable', 'pc_path', 'pkg-config'], { encoding: 'utf8' }).stdout || '').trim();
|
|
153
|
+
if (pkgConfigPath) {
|
|
154
|
+
return pkgConfigPath;
|
|
155
|
+
}
|
|
156
|
+
} catch (_err) {}
|
|
157
|
+
return undefined;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/* node:coverage enable */
|
|
161
|
+
|
|
162
|
+
const pkgConfigPath = () => {
|
|
163
|
+
if (process.platform !== 'win32') {
|
|
164
|
+
return [
|
|
165
|
+
getBrewPkgConfigPath(),
|
|
166
|
+
getPkgConfigPath(),
|
|
167
|
+
process.env.PKG_CONFIG_PATH
|
|
168
|
+
].filter(Boolean).join(':');
|
|
169
|
+
} else {
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const skipSearch = (status, reason, logger) => {
|
|
175
|
+
if (logger) {
|
|
176
|
+
logger(`Detected ${reason}, skipping search for globally-installed libvips`);
|
|
177
|
+
}
|
|
178
|
+
return status;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const useGlobalLibvips = (logger) => {
|
|
182
|
+
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
|
183
|
+
return skipSearch(false, 'SHARP_IGNORE_GLOBAL_LIBVIPS', logger);
|
|
184
|
+
}
|
|
185
|
+
if (Boolean(process.env.SHARP_FORCE_GLOBAL_LIBVIPS) === true) {
|
|
186
|
+
return skipSearch(true, 'SHARP_FORCE_GLOBAL_LIBVIPS', logger);
|
|
187
|
+
}
|
|
188
|
+
/* node:coverage ignore next 3 */
|
|
189
|
+
if (isRosetta()) {
|
|
190
|
+
return skipSearch(false, 'Rosetta', logger);
|
|
191
|
+
}
|
|
192
|
+
const globalVipsVersion = globalLibvipsVersion();
|
|
193
|
+
/* node:coverage ignore next */
|
|
194
|
+
return !!globalVipsVersion && semver.gte(globalVipsVersion, minimumLibvipsVersion);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export default {
|
|
198
|
+
minimumLibvipsVersion,
|
|
199
|
+
prebuiltPlatforms,
|
|
200
|
+
buildPlatformArch,
|
|
201
|
+
buildSharpLibvipsIncludeDir,
|
|
202
|
+
buildSharpLibvipsCPlusPlusDir,
|
|
203
|
+
buildSharpLibvipsLibDir,
|
|
204
|
+
isUnsupportedNodeRuntime,
|
|
205
|
+
runtimePlatformArch,
|
|
206
|
+
log,
|
|
207
|
+
yarnLocator,
|
|
208
|
+
spawnRebuild,
|
|
209
|
+
globalLibvipsVersion,
|
|
210
|
+
pkgConfigPath,
|
|
211
|
+
useGlobalLibvips
|
|
212
|
+
};
|