mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Distribute prebuilt binaries via the npm registry #3750
- Remove all custom download logic for prebuilt binaries - Add scripts to populate package contents - Specify minimum versions of common package managers - Remove sharp.vendor runtime API as no-longer relevant - Update installation docs and issue templates
This commit is contained in:
parent
0f8bb9196e
commit
aabbe1fa08
@ -36,6 +36,12 @@ jobs:
|
||||
sudo docker exec sharp sh -c "apt-get update && apt-get install -y nodejs"
|
||||
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
|
||||
- run: sudo docker exec sharp sh -c "npm test"
|
||||
- run: |
|
||||
sudo docker exec sharp sh -c "npm run package-from-local-build"
|
||||
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@sharpen/sharp-linux-arm64=file:./npm/linux-arm64\""
|
||||
sudo docker exec sharp sh -c "npm run clean"
|
||||
sudo docker exec sharp sh -c "npm install --ignore-scripts"
|
||||
sudo docker exec sharp sh -c "npm test"
|
||||
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"npx prebuild --upload=$prebuild_upload\" || true"
|
||||
linux-arm64-glibc-node-20:
|
||||
resource_class: arm.medium
|
||||
@ -54,6 +60,12 @@ jobs:
|
||||
sudo docker cp . sharp:/mnt/sharp/.
|
||||
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
|
||||
- run: sudo docker exec sharp sh -c "npm test"
|
||||
- run: |
|
||||
sudo docker exec sharp sh -c "npm run package-from-local-build"
|
||||
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@sharpen/sharp-linux-arm64=file:./npm/linux-arm64\""
|
||||
sudo docker exec sharp sh -c "npm run clean"
|
||||
sudo docker exec sharp sh -c "npm install --ignore-scripts"
|
||||
sudo docker exec sharp sh -c "npm test"
|
||||
linux-arm64-musl-node-18:
|
||||
resource_class: arm.medium
|
||||
machine:
|
||||
@ -65,6 +77,12 @@ jobs:
|
||||
sudo docker exec sharp sh -c "apk add build-base git python3 font-noto --update-cache"
|
||||
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
|
||||
- run: sudo docker exec sharp sh -c "npm test"
|
||||
- run: |
|
||||
sudo docker exec sharp sh -c "npm run package-from-local-build"
|
||||
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@sharpen/sharp-linuxmusl-arm64=file:./npm/linuxmusl-arm64\""
|
||||
sudo docker exec sharp sh -c "npm run clean"
|
||||
sudo docker exec sharp sh -c "npm install --ignore-scripts"
|
||||
sudo docker exec sharp sh -c "npm test"
|
||||
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"npx prebuild --upload=$prebuild_upload\" || true"
|
||||
linux-arm64-musl-node-20:
|
||||
resource_class: arm.medium
|
||||
@ -79,3 +97,9 @@ jobs:
|
||||
sudo docker cp . sharp:/mnt/sharp/.
|
||||
- run: sudo docker exec sharp sh -c "npm install --build-from-source"
|
||||
- run: sudo docker exec sharp sh -c "npm test"
|
||||
- run: |
|
||||
sudo docker exec sharp sh -c "npm run package-from-local-build"
|
||||
sudo docker exec sharp sh -c "npm pkg set \"optionalDependencies.@sharpen/sharp-linuxmusl-arm64=file:./npm/linuxmusl-arm64\""
|
||||
sudo docker exec sharp sh -c "npm run clean"
|
||||
sudo docker exec sharp sh -c "npm install --ignore-scripts"
|
||||
sudo docker exec sharp sh -c "npm test"
|
||||
|
21
.github/ISSUE_TEMPLATE/installation.md
vendored
21
.github/ISSUE_TEMPLATE/installation.md
vendored
@ -12,7 +12,6 @@ labels: installation
|
||||
<!-- Please place an [x] in the box to confirm. -->
|
||||
|
||||
- [ ] I have read the [documentation relating to installation](https://sharp.pixelplumbing.com/install).
|
||||
- [ ] I have ensured that the architecture and platform of Node.js used for `npm install` is the same as the architecture and platform of Node.js used at runtime.
|
||||
|
||||
### Are you using the latest version of sharp?
|
||||
|
||||
@ -24,13 +23,25 @@ If you cannot confirm this, please upgrade to the latest version and try again b
|
||||
|
||||
If you are using another package which depends on a version of `sharp` that is not the latest, please open an issue against that package instead.
|
||||
|
||||
### Is this a problem with filesystem permissions?
|
||||
### Are you using a supported runtime?
|
||||
|
||||
If you are using npm v6 or earlier and installing as a `root` or `sudo` user, have you tried with the `npm install --unsafe-perm` flag?
|
||||
<!-- Please place an [x] in the relevant box to confirm. -->
|
||||
|
||||
If you are using npm v7 or later, does the user running `npm install` own the directory it is run in?
|
||||
- [ ] I am using Node.js 18 with a version >= 18.17.0
|
||||
- [ ] I am using Node.js 20 with a version >= 20.3.0
|
||||
- [ ] I am using Node.js 21 or later
|
||||
|
||||
If you are using the `ignore-scripts` feature of `npm`, have you tried with the `npm install --ignore-scripts=false` flag?
|
||||
If you cannot confirm any of these, please upgrade to the latest version and try again before opening an issue.
|
||||
|
||||
### Are you using a supported package manager?
|
||||
|
||||
<!-- Please place an [x] in the relevant box to confirm. -->
|
||||
|
||||
- [ ] I am using npm >= 9.6.5
|
||||
- [ ] I am using yarn >= 3.2.0
|
||||
- [ ] I am using pnpm >= 7.1.0
|
||||
|
||||
If you cannot confirm any of these, please upgrade to the latest version and try again before opening an issue.
|
||||
|
||||
### What is the complete output of running `npm install --verbose --foreground-scripts sharp` in an empty directory?
|
||||
|
||||
|
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
@ -37,6 +37,7 @@ jobs:
|
||||
- os: macos-11
|
||||
nodejs_arch: x64
|
||||
nodejs_version: "^18.17.0"
|
||||
nodejs_version_major: 18
|
||||
platform: darwin-x64
|
||||
prebuild: true
|
||||
- os: macos-11
|
||||
@ -98,13 +99,17 @@ jobs:
|
||||
architecture: ${{ matrix.nodejs_arch }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Fix working directory ownership
|
||||
if: matrix.container
|
||||
run: chown root.root .
|
||||
- name: Install
|
||||
run: npm install --build-from-source
|
||||
- name: Test
|
||||
run: npm test
|
||||
- name: Test packaging
|
||||
run: |
|
||||
npm run package-from-local-build
|
||||
npm pkg set "optionalDependencies.@sharpen/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}"
|
||||
npm run clean
|
||||
npm install --ignore-scripts
|
||||
npm test
|
||||
- name: Prebuild
|
||||
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
@ -130,9 +135,13 @@ jobs:
|
||||
mkdir /opt/nodejs
|
||||
curl --silent https://unofficial-builds.nodejs.org/download/release/v${nodejs_version}/node-v${nodejs_version}-linux-armv6l.tar.xz | tar xJC /opt/nodejs --strip-components=1
|
||||
export PATH=$PATH:/opt/nodejs/bin
|
||||
chown root.root .
|
||||
npm install --build-from-source
|
||||
npx mocha --no-config --spec=test/unit/io.js
|
||||
npm run package-from-local-build
|
||||
npm pkg set "optionalDependencies.@sharpen/sharp-linux-arm=file:./npm/linux-arm"
|
||||
npm run clean
|
||||
npm install --ignore-scripts
|
||||
npx mocha --no-config --spec=test/unit/io.js
|
||||
[[ -n $prebuild_upload ]] && npx prebuild || true
|
||||
macstadium-runner:
|
||||
permissions:
|
||||
@ -167,6 +176,13 @@ jobs:
|
||||
run: npm install --build-from-source
|
||||
- name: Test
|
||||
run: npm test
|
||||
- name: Test packaging
|
||||
run: |
|
||||
npm run package-from-local-build
|
||||
npm pkg set "optionalDependencies.@sharpen/sharp-${{ matrix.platform }}=file:./npm/${{ matrix.platform }}"
|
||||
npm run clean
|
||||
npm install --ignore-scripts
|
||||
npm test
|
||||
- name: Prebuild
|
||||
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,8 @@
|
||||
build
|
||||
node_modules
|
||||
/coverage
|
||||
npm/*/*
|
||||
!npm/*/package.json
|
||||
test/bench/node_modules
|
||||
test/fixtures/output*
|
||||
test/fixtures/vips-properties.xml
|
||||
@ -9,7 +11,6 @@ test/saliency/report.json
|
||||
test/saliency/Image*
|
||||
test/saliency/[Uu]serData*
|
||||
!test/saliency/userData.js
|
||||
vendor
|
||||
.gitattributes
|
||||
.DS_Store
|
||||
.nyc_output
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"runtime": "napi",
|
||||
"include-regex": "(sharp-.+\\.node|libvips-cpp\\.dll)",
|
||||
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll|libglib-.+\\.dll|libgobject-.+\\.dll)",
|
||||
"prerelease": true,
|
||||
"strip": true
|
||||
}
|
||||
|
82
binding.gyp
82
binding.gyp
@ -1,11 +1,16 @@
|
||||
# Copyright 2013 Lovell Fuller and others.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
{
|
||||
'variables': {
|
||||
'vips_version': '<!(node -p "require(\'./lib/libvips\').minimumLibvipsVersion")',
|
||||
'platform_and_arch': '<!(node -p "require(\'./lib/platform\')()")',
|
||||
'sharp_vendor_dir': './vendor/<(vips_version)/<(platform_and_arch)'
|
||||
'platform_and_arch': '<!(node -p "require(\'./lib/libvips\').buildPlatformArch()")',
|
||||
'sharp_libvips_include_dir': '<!(node -p "require(\'./lib/libvips\').buildSharpLibvipsIncludeDir()")',
|
||||
'sharp_libvips_cplusplus_dir': '<!(node -p "require(\'./lib/libvips\').buildSharpLibvipsCPlusPlusDir()")',
|
||||
'sharp_libvips_lib_dir': '<!(node -p "require(\'./lib/libvips\').buildSharpLibvipsLibDir()")'
|
||||
},
|
||||
'targets': [{
|
||||
'target_name': 'libvips-cpp',
|
||||
'target_name': 'win-libvips-cpp',
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
# Build libvips C++ binding for Windows due to MSVC std library ABI changes
|
||||
@ -15,19 +20,19 @@
|
||||
'_ALLOW_KEYWORD_MACROS'
|
||||
],
|
||||
'sources': [
|
||||
'src/libvips/cplusplus/VConnection.cpp',
|
||||
'src/libvips/cplusplus/VError.cpp',
|
||||
'src/libvips/cplusplus/VImage.cpp',
|
||||
'src/libvips/cplusplus/VInterpolate.cpp',
|
||||
'src/libvips/cplusplus/VRegion.cpp'
|
||||
'<(sharp_libvips_cplusplus_dir)/VConnection.cpp',
|
||||
'<(sharp_libvips_cplusplus_dir)/VError.cpp',
|
||||
'<(sharp_libvips_cplusplus_dir)/VImage.cpp',
|
||||
'<(sharp_libvips_cplusplus_dir)/VInterpolate.cpp',
|
||||
'<(sharp_libvips_cplusplus_dir)/VRegion.cpp'
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(sharp_vendor_dir)/include',
|
||||
'<(sharp_vendor_dir)/include/glib-2.0',
|
||||
'<(sharp_vendor_dir)/lib/glib-2.0/include'
|
||||
'<(sharp_libvips_include_dir)',
|
||||
'<(sharp_libvips_include_dir)/glib-2.0',
|
||||
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
||||
],
|
||||
'link_settings': {
|
||||
'library_dirs': ['<(sharp_vendor_dir)/lib'],
|
||||
'library_dirs': ['<(sharp_libvips_lib_dir)'],
|
||||
'libraries': [
|
||||
'libvips.lib',
|
||||
'libglib-2.0.lib',
|
||||
@ -76,10 +81,9 @@
|
||||
],
|
||||
'dependencies': [
|
||||
'<!(node -p "require(\'node-addon-api\').gyp")',
|
||||
'libvips-cpp'
|
||||
'win-libvips-cpp'
|
||||
],
|
||||
'variables': {
|
||||
'runtime_link%': 'shared',
|
||||
'conditions': [
|
||||
['OS != "win"', {
|
||||
'pkg_config_path': '<!(node -p "require(\'./lib/libvips\').pkgConfigPath()")',
|
||||
@ -106,12 +110,8 @@
|
||||
['use_global_libvips == "true"', {
|
||||
# Use pkg-config for include and lib
|
||||
'include_dirs': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --cflags-only-I vips-cpp vips glib-2.0 | sed s\/-I//g)'],
|
||||
'libraries': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --libs vips-cpp)'],
|
||||
'conditions': [
|
||||
['runtime_link == "static"', {
|
||||
'libraries': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --libs --static vips-cpp)']
|
||||
}, {
|
||||
'libraries': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --libs vips-cpp)']
|
||||
}],
|
||||
['OS == "linux"', {
|
||||
'defines': [
|
||||
# Inspect libvips-cpp.so to determine which C++11 ABI version was used and set _GLIBCXX_USE_CXX11_ABI accordingly. This is quite horrible.
|
||||
@ -122,9 +122,9 @@
|
||||
}, {
|
||||
# Use pre-built libvips stored locally within node_modules
|
||||
'include_dirs': [
|
||||
'<(sharp_vendor_dir)/include',
|
||||
'<(sharp_vendor_dir)/include/glib-2.0',
|
||||
'<(sharp_vendor_dir)/lib/glib-2.0/include'
|
||||
'<(sharp_libvips_include_dir)',
|
||||
'<(sharp_libvips_include_dir)/glib-2.0',
|
||||
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
||||
],
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
@ -133,7 +133,7 @@
|
||||
'_FILE_OFFSET_BITS=64'
|
||||
],
|
||||
'link_settings': {
|
||||
'library_dirs': ['<(sharp_vendor_dir)/lib'],
|
||||
'library_dirs': ['<(sharp_libvips_lib_dir)'],
|
||||
'libraries': [
|
||||
'libvips.lib',
|
||||
'libglib-2.0.lib',
|
||||
@ -143,7 +143,9 @@
|
||||
}],
|
||||
['OS == "mac"', {
|
||||
'link_settings': {
|
||||
'library_dirs': ['../<(sharp_vendor_dir)/lib'],
|
||||
'library_dirs': [
|
||||
'<(sharp_libvips_lib_dir)'
|
||||
],
|
||||
'libraries': [
|
||||
'libvips-cpp.42.dylib'
|
||||
]
|
||||
@ -151,7 +153,9 @@
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [
|
||||
# Ensure runtime linking is relative to sharp.node
|
||||
'-Wl,-rpath,\'@loader_path/../../<(sharp_vendor_dir)/lib\''
|
||||
'-Wl,-rpath,\'@loader_path/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
||||
'-Wl,-rpath,\'@loader_path/../../node_modules/@sharpen/sharp-libvips-<(platform_and_arch)/lib\'',
|
||||
'-Wl,-rpath,\'@loader_path/../../../node_modules/@sharpen/sharp-libvips-<(platform_and_arch)/lib\''
|
||||
]
|
||||
}
|
||||
}],
|
||||
@ -160,13 +164,19 @@
|
||||
'_GLIBCXX_USE_CXX11_ABI=1'
|
||||
],
|
||||
'link_settings': {
|
||||
'library_dirs': ['../<(sharp_vendor_dir)/lib'],
|
||||
'library_dirs': [
|
||||
'<(sharp_libvips_lib_dir)'
|
||||
],
|
||||
'libraries': [
|
||||
'-l:libvips-cpp.so.42'
|
||||
],
|
||||
'ldflags': [
|
||||
# Ensure runtime linking is relative to sharp.node
|
||||
'-Wl,-s -Wl,--disable-new-dtags -Wl,-rpath=\'$$ORIGIN/../../<(sharp_vendor_dir)/lib\''
|
||||
'-Wl,-s',
|
||||
'-Wl,--disable-new-dtags',
|
||||
'-Wl,-rpath=\'$$ORIGIN/../../sharp-libvips-<(platform_and_arch)/lib\'',
|
||||
'-Wl,-rpath=\'$$ORIGIN/../../node_modules/@sharpen/sharp-libvips-<(platform_and_arch)/lib\'',
|
||||
'-Wl,-rpath=\'$$ORIGIN/../../../node_modules/@sharpen/sharp-libvips-<(platform_and_arch)/lib\''
|
||||
]
|
||||
}
|
||||
}]
|
||||
@ -232,5 +242,23 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
}, {
|
||||
'target_name': 'win-copy-dlls',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'sharp-<(platform_and_arch)'
|
||||
],
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
'copies': [{
|
||||
'destination': 'build/Release',
|
||||
'files': [
|
||||
'<(sharp_libvips_lib_dir)/libvips-42.dll',
|
||||
'<(sharp_libvips_lib_dir)/libglib-2.0-0.dll',
|
||||
'<(sharp_libvips_lib_dir)/libgobject-2.0-0.dll'
|
||||
]
|
||||
}]
|
||||
}]
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
200
docs/install.md
200
docs/install.md
@ -8,6 +8,10 @@ npm install sharp
|
||||
yarn add sharp
|
||||
```
|
||||
|
||||
```sh
|
||||
pnpm add sharp
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Node.js >= 18.17.0
|
||||
@ -18,98 +22,19 @@ Ready-compiled sharp and libvips binaries are provided for use on the most commo
|
||||
|
||||
* macOS x64 (>= 10.13)
|
||||
* macOS ARM64
|
||||
* Linux x64 (glibc >= 2.17, musl >= 1.1.24, CPU with SSE4.2)
|
||||
* Linux ARM64 (glibc >= 2.17, musl >= 1.1.24)
|
||||
* Linux x64 (glibc >= 2.26, musl >= 1.2.2, CPU with SSE4.2)
|
||||
* Linux ARM64 (glibc >= 2.26, musl >= 1.2.2)
|
||||
* Linux ARM (glibc >= 2.28)
|
||||
* Windows x64
|
||||
* Windows x86
|
||||
|
||||
A ~7MB tarball containing libvips and its most commonly used dependencies
|
||||
is downloaded via HTTPS, verified via Subresource Integrity
|
||||
and decompressed into `node_modules/sharp/vendor` during `npm install`.
|
||||
|
||||
This provides support for the
|
||||
JPEG, PNG, WebP, AVIF (limited to 8-bit depth), TIFF, GIF and SVG (input) image formats.
|
||||
|
||||
The following platforms have prebuilt libvips but not sharp:
|
||||
|
||||
* Linux ARMv7 (glibc >= 2.28)
|
||||
* Linux ARMv6 (glibc >= 2.28)
|
||||
* Windows ARM64
|
||||
|
||||
The following platforms require compilation of both libvips and sharp from source:
|
||||
|
||||
* Linux x86
|
||||
* Linux ARMv7 (glibc <= 2.27, musl)
|
||||
* Linux ARMv6 (glibc <= 2.27, musl)
|
||||
* Linux PowerPC
|
||||
* FreeBSD
|
||||
* OpenBSD
|
||||
|
||||
## Common problems
|
||||
|
||||
The architecture and platform of Node.js used for `npm install`
|
||||
must be the same as the architecture and platform of Node.js used at runtime.
|
||||
See the [cross-platform](#cross-platform) section if this is not the case.
|
||||
|
||||
When using npm v6 or earlier, the `npm install --unsafe-perm` flag must be used when installing as `root` or a `sudo` user.
|
||||
|
||||
When using npm v7 or later, the user running `npm install` must own the directory it is run in.
|
||||
|
||||
The `npm install --ignore-scripts=false` flag must be used when `npm` has been configured to ignore installation scripts.
|
||||
|
||||
Check the output of running `npm install --verbose --foreground-scripts sharp` for useful error messages.
|
||||
|
||||
## Apple M1
|
||||
|
||||
Prebuilt sharp and libvips binaries have been provided for macOS on ARM64 since sharp v0.29.0.
|
||||
|
||||
## Cross-platform
|
||||
|
||||
At `npm install` time, prebuilt binaries are automatically selected for the
|
||||
current OS platform and CPU architecture, where available.
|
||||
|
||||
The target platform and/or architecture can be manually selected using the following flags.
|
||||
|
||||
```sh
|
||||
npm install --platform=... --arch=... --arm-version=... sharp
|
||||
```
|
||||
|
||||
* `--platform`: one of `linux`, `darwin` or `win32`.
|
||||
* `--arch`: one of `x64`, `ia32`, `arm` or `arm64`.
|
||||
* `--arm-version`: one of `6`, `7` or `8` (`arm` defaults to `6`, `arm64` defaults to `8`).
|
||||
* `--libc`: one of `glibc` or `musl`. This option only works with platform `linux`, defaults to `glibc`
|
||||
* `--sharp-install-force`: skip version compatibility and Subresource Integrity checks.
|
||||
|
||||
These values can also be set via environment variables,
|
||||
`npm_config_platform`, `npm_config_arch`, `npm_config_arm_version`, `npm_config_libc`
|
||||
and `SHARP_INSTALL_FORCE` respectively.
|
||||
|
||||
For example, if the target machine has a 64-bit ARM CPU and is running Alpine Linux,
|
||||
use the following flags:
|
||||
|
||||
```sh
|
||||
npm install --arch=arm64 --platform=linux --libc=musl sharp
|
||||
```
|
||||
|
||||
If the current machine is Alpine Linux and the target machine is Debian Linux on x64 cpu,
|
||||
use the following flags:
|
||||
|
||||
```sh
|
||||
npm install --arch=x64 --platform=linux --libc=glibc sharp
|
||||
```
|
||||
|
||||
Multiple platforms and architectures can be supported within the same installation tree.
|
||||
The following example for macOS installs x64 binaries then adds (via a rebuild) arm64 binaries:
|
||||
|
||||
```sh
|
||||
npm install --platform=darwin --arch=x64 sharp
|
||||
npm rebuild --platform=darwin --arch=arm64 sharp
|
||||
```
|
||||
|
||||
## Custom libvips
|
||||
|
||||
To use a custom, globally-installed version of libvips instead of the provided binaries,
|
||||
make sure it is at least the version listed under `config.libvips` in the `package.json` file
|
||||
make sure it is at least the version listed under `engines.libvips` in the `package.json` file
|
||||
and that it can be located using `pkg-config --modversion vips-cpp`.
|
||||
|
||||
For help compiling libvips and its dependencies, please see
|
||||
@ -122,8 +47,7 @@ and on macOS when running Node.js under Rosetta.
|
||||
|
||||
This module will be compiled from source at `npm install` time when:
|
||||
|
||||
* a globally-installed libvips is detected (set the `SHARP_IGNORE_GLOBAL_LIBVIPS` environment variable to skip this),
|
||||
* prebuilt sharp binaries do not exist for the current platform, or
|
||||
* a globally-installed libvips is detected (set the `SHARP_IGNORE_GLOBAL_LIBVIPS` environment variable to skip this), or
|
||||
* when the `npm install --build-from-source` flag is used.
|
||||
|
||||
Building from source requires:
|
||||
@ -131,83 +55,11 @@ Building from source requires:
|
||||
* C++11 compiler
|
||||
* [node-gyp](https://github.com/nodejs/node-gyp#installation) and its dependencies
|
||||
|
||||
## Custom prebuilt binaries
|
||||
If `node-gyp` cannot be found, try adding it to `devDependencies`.
|
||||
|
||||
This is an advanced approach that most people will not require.
|
||||
|
||||
### Prebuilt sharp binaries
|
||||
|
||||
To install the prebuilt sharp binaries from a custom URL,
|
||||
set the `sharp_binary_host` npm config option
|
||||
or the `npm_config_sharp_binary_host` environment variable.
|
||||
|
||||
To install the prebuilt sharp binaries from a directory on the local filesystem,
|
||||
set the `sharp_local_prebuilds` npm config option
|
||||
or the `npm_config_sharp_local_prebuilds` environment variable.
|
||||
|
||||
URL example:
|
||||
if `sharp_binary_host` is set to `https://hostname/path`
|
||||
and the sharp version is `1.2.3` then the resultant URL will be
|
||||
`https://hostname/path/v1.2.3/sharp-v1.2.3-napi-v5-platform-arch.tar.gz`.
|
||||
|
||||
Filename example:
|
||||
if `sharp_local_prebuilds` is set to `/path`
|
||||
and the sharp version is `1.2.3` then the resultant filename will be
|
||||
`/path/sharp-v1.2.3-napi-v5-platform-arch.tar.gz`.
|
||||
|
||||
### Prebuilt libvips binaries
|
||||
|
||||
To install the prebuilt libvips binaries from a custom URL,
|
||||
set the `sharp_libvips_binary_host` npm config option
|
||||
or the `npm_config_sharp_libvips_binary_host` environment variable.
|
||||
|
||||
To install the prebuilt libvips binaries from a directory on the local filesystem,
|
||||
set the `sharp_libvips_local_prebuilds` npm config option
|
||||
or the `npm_config_sharp_libvips_local_prebuilds` environment variable.
|
||||
|
||||
The version subpath and filename are appended to these.
|
||||
|
||||
URL example:
|
||||
if `sharp_libvips_binary_host` is set to `https://hostname/path`
|
||||
and the libvips version is `4.5.6` then the resultant URL will be
|
||||
`https://hostname/path/v4.5.6/libvips-4.5.6-platform-arch.tar.br`.
|
||||
|
||||
Filename example:
|
||||
if `sharp_libvips_local_prebuilds` is set to `/path`
|
||||
and the libvips version is `4.5.6` then the resultant filename will be
|
||||
`/path/v4.5.6/libvips-4.5.6-platform-arch.tar.br`.
|
||||
|
||||
See the Chinese mirror below for a further example.
|
||||
|
||||
If these binaries are modified, new integrity hashes can be provided
|
||||
at install time via `npm_package_config_integrity_platform_arch`
|
||||
environment variables, for example set
|
||||
`npm_package_config_integrity_linux_x64` to `sha512-abc...`.
|
||||
|
||||
The integrity hash of a file can be generated via:
|
||||
```sh
|
||||
sha512sum libvips-x.y.z-platform-arch.tar.br | cut -f1 -d' ' | xxd -r -p | base64 -w 0
|
||||
```
|
||||
|
||||
## Chinese mirror
|
||||
|
||||
A mirror site based in China, provided by Alibaba, contains binaries for both sharp and libvips.
|
||||
|
||||
To use this either set the following configuration:
|
||||
|
||||
```sh
|
||||
npm config set sharp_binary_host "https://npmmirror.com/mirrors/sharp"
|
||||
npm config set sharp_libvips_binary_host "https://npmmirror.com/mirrors/sharp-libvips"
|
||||
npm install sharp
|
||||
```
|
||||
|
||||
or set the following environment variables:
|
||||
|
||||
```sh
|
||||
npm_config_sharp_binary_host="https://npmmirror.com/mirrors/sharp" \
|
||||
npm_config_sharp_libvips_binary_host="https://npmmirror.com/mirrors/sharp-libvips" \
|
||||
npm install sharp
|
||||
```
|
||||
For cross-compiling, the `--platform`, `--arch` and `--libc` npm flags
|
||||
(or the `npm_config_platform`, `npm_config_arch` and `npm_config_libc` environment variables)
|
||||
can be used to configure the target environment.
|
||||
|
||||
## FreeBSD
|
||||
|
||||
@ -242,15 +94,18 @@ unaffected.
|
||||
|
||||
The `node_modules` directory of the
|
||||
[deployment package](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-package.html)
|
||||
must include binaries for the Linux x64 platform.
|
||||
must include binaries for either the linux-x64 or linux-arm64 platforms
|
||||
depending on the chosen architecture.
|
||||
|
||||
When building your deployment package on machines other than Linux x64 (glibc),
|
||||
run the following additional command after `npm install`:
|
||||
When building your deployment package on a machine that differs from the target architecture,
|
||||
you will need to install either `@sharpen/sharp-linux-x64` or `@sharpen/sharp-linux-arm64` package.
|
||||
|
||||
```sh
|
||||
npm install
|
||||
rm -rf node_modules/sharp
|
||||
SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm install --arch=x64 --platform=linux --libc=glibc sharp
|
||||
npm install --force @sharpen/sharp-linux-x64
|
||||
```
|
||||
|
||||
```sh
|
||||
npm install --force @sharpen/sharp-linux-arm64
|
||||
```
|
||||
|
||||
To get the best performance select the largest memory available.
|
||||
@ -302,7 +157,7 @@ custom:
|
||||
- sharp
|
||||
packagerOptions:
|
||||
scripts:
|
||||
- npm install --arch=x64 --platform=linux sharp
|
||||
- npm install --force @sharpen/sharp-linux-x64
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
@ -358,14 +213,7 @@ Module did not self-register
|
||||
|
||||
### Canvas and Windows
|
||||
|
||||
The prebuilt binaries provided by `canvas` for Windows
|
||||
from v2.7.0 onwards depend on the Visual C++ Runtime (MSVCRT).
|
||||
These conflict with the binaries provided by sharp,
|
||||
which depend on the more modern Universal C Runtime (UCRT).
|
||||
|
||||
See [Automattic/node-canvas#2155](https://github.com/Automattic/node-canvas/issues/2155).
|
||||
|
||||
If both modules are used in the same Windows process, the following error will occur:
|
||||
If both `canvas` and `sharp` modules are used in the same Windows process, the following error may occur:
|
||||
```
|
||||
The specified procedure could not be found.
|
||||
```
|
||||
|
@ -1,14 +0,0 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const libvips = require('../lib/libvips');
|
||||
|
||||
try {
|
||||
if (!(libvips.useGlobalLibvips() || libvips.hasVendoredLibvips())) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
} catch (err) {
|
||||
process.exitCode = 1;
|
||||
}
|
27
install/check.js
Normal file
27
install/check.js
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const { useGlobalLibvips, globalLibvipsVersion, log, gypRebuild } = require('../lib/libvips');
|
||||
|
||||
const buildFromSource = (msg) => {
|
||||
log(msg);
|
||||
log('Attempting to build from source via node-gyp');
|
||||
try {
|
||||
require('node-gyp');
|
||||
} catch (err) {
|
||||
log('You might need to install node-gyp');
|
||||
log('See https://sharp.pixelplumbing.com/install#building-from-source');
|
||||
}
|
||||
const status = gypRebuild();
|
||||
if (status !== 0) {
|
||||
process.exit(status);
|
||||
}
|
||||
};
|
||||
|
||||
if (process.env.npm_config_build_from_source) {
|
||||
buildFromSource('Detected --build-from-source flag');
|
||||
} else if (useGlobalLibvips()) {
|
||||
buildFromSource(`Detected globally-installed libvips v${globalLibvipsVersion()}`);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const libvips = require('../lib/libvips');
|
||||
const platform = require('../lib/platform');
|
||||
|
||||
const minimumLibvipsVersion = libvips.minimumLibvipsVersion;
|
||||
|
||||
const platformAndArch = platform();
|
||||
|
||||
if (platformAndArch.startsWith('win32')) {
|
||||
const buildReleaseDir = path.join(__dirname, '..', 'build', 'Release');
|
||||
libvips.log(`Creating ${buildReleaseDir}`);
|
||||
try {
|
||||
libvips.mkdirSync(buildReleaseDir);
|
||||
} catch (err) {}
|
||||
const vendorLibDir = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platformAndArch, 'lib');
|
||||
libvips.log(`Copying DLLs from ${vendorLibDir} to ${buildReleaseDir}`);
|
||||
try {
|
||||
fs
|
||||
.readdirSync(vendorLibDir)
|
||||
.filter(function (filename) {
|
||||
return /\.dll$/.test(filename);
|
||||
})
|
||||
.forEach(function (filename) {
|
||||
fs.copyFileSync(
|
||||
path.join(vendorLibDir, filename),
|
||||
path.join(buildReleaseDir, filename)
|
||||
);
|
||||
});
|
||||
} catch (err) {
|
||||
libvips.log(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
@ -1,222 +0,0 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const stream = require('stream');
|
||||
const zlib = require('zlib');
|
||||
const { createHash } = require('crypto');
|
||||
|
||||
const detectLibc = require('detect-libc');
|
||||
const semverCoerce = require('semver/functions/coerce');
|
||||
const semverLessThan = require('semver/functions/lt');
|
||||
const semverSatisfies = require('semver/functions/satisfies');
|
||||
const simpleGet = require('simple-get');
|
||||
const tarFs = require('tar-fs');
|
||||
|
||||
const agent = require('../lib/agent');
|
||||
const libvips = require('../lib/libvips');
|
||||
const platform = require('../lib/platform');
|
||||
|
||||
const minimumGlibcVersionByArch = {
|
||||
arm: '2.28',
|
||||
arm64: '2.17',
|
||||
x64: '2.17'
|
||||
};
|
||||
|
||||
const hasSharpPrebuild = [
|
||||
'darwin-x64',
|
||||
'darwin-arm64',
|
||||
'linux-arm64',
|
||||
'linux-x64',
|
||||
'linuxmusl-x64',
|
||||
'linuxmusl-arm64',
|
||||
'win32-ia32',
|
||||
'win32-x64'
|
||||
];
|
||||
|
||||
const { minimumLibvipsVersion, minimumLibvipsVersionLabelled } = libvips;
|
||||
const localLibvipsDir = process.env.npm_config_sharp_libvips_local_prebuilds || '';
|
||||
const distHost = process.env.npm_config_sharp_libvips_binary_host || 'https://github.com/lovell/sharp-libvips/releases/download';
|
||||
const distBaseUrl = process.env.npm_config_sharp_dist_base_url || process.env.SHARP_DIST_BASE_URL || `${distHost}/v${minimumLibvipsVersionLabelled}/`;
|
||||
const installationForced = !!(process.env.npm_config_sharp_install_force || process.env.SHARP_INSTALL_FORCE);
|
||||
|
||||
const fail = function (err) {
|
||||
libvips.log(err);
|
||||
if (err.code === 'EACCES') {
|
||||
libvips.log('Are you trying to install as a root or sudo user?');
|
||||
libvips.log('- For npm <= v6, try again with the "--unsafe-perm" flag');
|
||||
libvips.log('- For npm >= v8, the user must own the directory "npm install" is run in');
|
||||
}
|
||||
libvips.log('Please see https://sharp.pixelplumbing.com/install for required dependencies');
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
const handleError = function (err) {
|
||||
if (installationForced) {
|
||||
libvips.log(`Installation warning: ${err.message}`);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
const verifyIntegrity = function (platformAndArch) {
|
||||
const expected = libvips.integrity(platformAndArch);
|
||||
if (installationForced || !expected) {
|
||||
libvips.log(`Integrity check skipped for ${platformAndArch}`);
|
||||
return new stream.PassThrough();
|
||||
}
|
||||
const hash = createHash('sha512');
|
||||
return new stream.Transform({
|
||||
transform: function (chunk, _encoding, done) {
|
||||
hash.update(chunk);
|
||||
done(null, chunk);
|
||||
},
|
||||
flush: function (done) {
|
||||
const digest = `sha512-${hash.digest('base64')}`;
|
||||
if (expected !== digest) {
|
||||
try {
|
||||
libvips.removeVendoredLibvips();
|
||||
} catch (err) {
|
||||
libvips.log(err.message);
|
||||
}
|
||||
libvips.log(`Integrity expected: ${expected}`);
|
||||
libvips.log(`Integrity received: ${digest}`);
|
||||
done(new Error(`Integrity check failed for ${platformAndArch}`));
|
||||
} else {
|
||||
libvips.log(`Integrity check passed for ${platformAndArch}`);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const extractTarball = function (tarPath, platformAndArch) {
|
||||
const versionedVendorPath = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platformAndArch);
|
||||
libvips.mkdirSync(versionedVendorPath);
|
||||
|
||||
const ignoreVendorInclude = hasSharpPrebuild.includes(platformAndArch) && !process.env.npm_config_build_from_source;
|
||||
const ignore = function (name) {
|
||||
return ignoreVendorInclude && name.includes('include/');
|
||||
};
|
||||
|
||||
stream.pipeline(
|
||||
fs.createReadStream(tarPath),
|
||||
verifyIntegrity(platformAndArch),
|
||||
new zlib.BrotliDecompress(),
|
||||
tarFs.extract(versionedVendorPath, { ignore }),
|
||||
function (err) {
|
||||
if (err) {
|
||||
if (/unexpected end of file/.test(err.message)) {
|
||||
fail(new Error(`Please delete ${tarPath} as it is not a valid tarball`));
|
||||
}
|
||||
fail(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
try {
|
||||
const useGlobalLibvips = libvips.useGlobalLibvips();
|
||||
|
||||
if (useGlobalLibvips) {
|
||||
const globalLibvipsVersion = libvips.globalLibvipsVersion();
|
||||
libvips.log(`Detected globally-installed libvips v${globalLibvipsVersion}`);
|
||||
libvips.log('Building from source via node-gyp');
|
||||
process.exit(1);
|
||||
} else if (libvips.hasVendoredLibvips()) {
|
||||
libvips.log(`Using existing vendored libvips v${minimumLibvipsVersion}`);
|
||||
} else {
|
||||
// Is this arch/platform supported?
|
||||
const arch = process.env.npm_config_arch || process.arch;
|
||||
const platformAndArch = platform();
|
||||
if (arch === 'ia32' && !platformAndArch.startsWith('win32')) {
|
||||
throw new Error(`Intel Architecture 32-bit systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
}
|
||||
if (platformAndArch === 'freebsd-x64' || platformAndArch === 'openbsd-x64' || platformAndArch === 'sunos-x64') {
|
||||
throw new Error(`BSD/SunOS systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
}
|
||||
// Linux libc version check
|
||||
const libcVersionRaw = detectLibc.versionSync();
|
||||
if (libcVersionRaw) {
|
||||
const libcFamily = detectLibc.familySync();
|
||||
const libcVersion = semverCoerce(libcVersionRaw).version;
|
||||
if (libcFamily === detectLibc.GLIBC && minimumGlibcVersionByArch[arch]) {
|
||||
if (semverLessThan(libcVersion, semverCoerce(minimumGlibcVersionByArch[arch]).version)) {
|
||||
handleError(new Error(`Use with glibc ${libcVersionRaw} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
|
||||
}
|
||||
}
|
||||
if (libcFamily === detectLibc.MUSL) {
|
||||
if (semverLessThan(libcVersion, '1.1.24')) {
|
||||
handleError(new Error(`Use with musl ${libcVersionRaw} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Node.js minimum version check
|
||||
const supportedNodeVersion = process.env.npm_package_engines_node || require('../package.json').engines.node;
|
||||
if (!semverSatisfies(process.versions.node, supportedNodeVersion)) {
|
||||
handleError(new Error(`Expected Node.js version ${supportedNodeVersion} but found ${process.versions.node}`));
|
||||
}
|
||||
// Download to per-process temporary file
|
||||
const tarFilename = ['libvips', minimumLibvipsVersionLabelled, platformAndArch].join('-') + '.tar.br';
|
||||
const tarPathCache = path.join(libvips.cachePath(), tarFilename);
|
||||
if (fs.existsSync(tarPathCache)) {
|
||||
libvips.log(`Using cached ${tarPathCache}`);
|
||||
extractTarball(tarPathCache, platformAndArch);
|
||||
} else if (localLibvipsDir) {
|
||||
// If localLibvipsDir is given try to use binaries from local directory
|
||||
const tarPathLocal = path.join(path.resolve(localLibvipsDir), `v${minimumLibvipsVersionLabelled}`, tarFilename);
|
||||
libvips.log(`Using local libvips from ${tarPathLocal}`);
|
||||
extractTarball(tarPathLocal, platformAndArch);
|
||||
} else {
|
||||
const url = distBaseUrl + tarFilename;
|
||||
libvips.log(`Downloading ${url}`);
|
||||
simpleGet({ url: url, agent: agent(libvips.log) }, function (err, response) {
|
||||
if (err) {
|
||||
fail(err);
|
||||
} else if (response.statusCode === 404) {
|
||||
fail(new Error(`Prebuilt libvips ${minimumLibvipsVersion} binaries are not yet available for ${platformAndArch}`));
|
||||
} else if (response.statusCode !== 200) {
|
||||
fail(new Error(`Status ${response.statusCode} ${response.statusMessage}`));
|
||||
} else {
|
||||
const tarPathTemp = path.join(os.tmpdir(), `${process.pid}-${tarFilename}`);
|
||||
const tmpFileStream = fs.createWriteStream(tarPathTemp);
|
||||
response
|
||||
.on('error', function (err) {
|
||||
tmpFileStream.destroy(err);
|
||||
})
|
||||
.on('close', function () {
|
||||
if (!response.complete) {
|
||||
tmpFileStream.destroy(new Error('Download incomplete (connection was terminated)'));
|
||||
}
|
||||
})
|
||||
.pipe(tmpFileStream);
|
||||
tmpFileStream
|
||||
.on('error', function (err) {
|
||||
// Clean up temporary file
|
||||
try {
|
||||
fs.unlinkSync(tarPathTemp);
|
||||
} catch (e) {}
|
||||
fail(err);
|
||||
})
|
||||
.on('close', function () {
|
||||
try {
|
||||
// Attempt to rename
|
||||
fs.renameSync(tarPathTemp, tarPathCache);
|
||||
} catch (err) {
|
||||
// Fall back to copy and unlink
|
||||
fs.copyFileSync(tarPathTemp, tarPathCache);
|
||||
fs.unlinkSync(tarPathTemp);
|
||||
}
|
||||
extractTarball(tarPathCache, platformAndArch);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
fail(err);
|
||||
}
|
44
lib/agent.js
44
lib/agent.js
@ -1,44 +0,0 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const url = require('url');
|
||||
const tunnelAgent = require('tunnel-agent');
|
||||
|
||||
const is = require('./is');
|
||||
|
||||
const proxies = [
|
||||
'HTTPS_PROXY',
|
||||
'https_proxy',
|
||||
'HTTP_PROXY',
|
||||
'http_proxy',
|
||||
'npm_config_https_proxy',
|
||||
'npm_config_proxy'
|
||||
];
|
||||
|
||||
function env (key) {
|
||||
return process.env[key];
|
||||
}
|
||||
|
||||
module.exports = function (log) {
|
||||
try {
|
||||
const proxy = new url.URL(proxies.map(env).find(is.string));
|
||||
const tunnel = proxy.protocol === 'https:'
|
||||
? tunnelAgent.httpsOverHttps
|
||||
: tunnelAgent.httpsOverHttp;
|
||||
const proxyAuth = proxy.username && proxy.password
|
||||
? `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`
|
||||
: null;
|
||||
log(`Via proxy ${proxy.protocol}//${proxy.hostname}:${proxy.port} ${proxyAuth ? 'with' : 'no'} credentials`);
|
||||
return tunnel({
|
||||
proxy: {
|
||||
port: Number(proxy.port),
|
||||
host: proxy.hostname,
|
||||
proxyAuth
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
@ -7,7 +7,6 @@ const util = require('util');
|
||||
const stream = require('stream');
|
||||
const is = require('./is');
|
||||
|
||||
require('./libvips').hasVendoredLibvips();
|
||||
require('./sharp');
|
||||
|
||||
// Use NODE_DEBUG=sharp to enable libvips warnings
|
||||
|
6
lib/index.d.ts
vendored
6
lib/index.d.ts
vendored
@ -91,12 +91,6 @@ declare namespace sharp {
|
||||
zlib?: string | undefined;
|
||||
};
|
||||
|
||||
/** An Object containing the platform and architecture of the current and installed vendored binaries. */
|
||||
const vendor: {
|
||||
current: string;
|
||||
installed: string[];
|
||||
};
|
||||
|
||||
/** An Object containing the available interpolators and their proper values */
|
||||
const interpolators: Interpolators;
|
||||
|
||||
|
129
lib/libvips.js
129
lib/libvips.js
@ -3,53 +3,30 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const spawnSync = require('child_process').spawnSync;
|
||||
const semverCoerce = require('semver/functions/coerce');
|
||||
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
||||
const detectLibc = require('detect-libc');
|
||||
|
||||
const platform = require('./platform');
|
||||
const { config } = require('../package.json');
|
||||
const { engines } = require('../package.json');
|
||||
|
||||
const env = process.env;
|
||||
const minimumLibvipsVersionLabelled = env.npm_package_config_libvips || /* istanbul ignore next */
|
||||
config.libvips;
|
||||
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || /* istanbul ignore next */
|
||||
engines.libvips;
|
||||
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
||||
|
||||
const prebuiltPlatforms = [
|
||||
'darwin-arm64', 'darwin-x64',
|
||||
'linux-arm', 'linux-arm64', 'linux-x64',
|
||||
'linuxmusl-arm64', 'linuxmusl-x64',
|
||||
'win32-ia32', 'win32-x64'
|
||||
];
|
||||
|
||||
const spawnSyncOptions = {
|
||||
encoding: 'utf8',
|
||||
shell: true
|
||||
};
|
||||
|
||||
const vendorPath = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platform());
|
||||
|
||||
const mkdirSync = function (dirPath) {
|
||||
try {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
} catch (err) {
|
||||
/* istanbul ignore next */
|
||||
if (err.code !== 'EEXIST') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const cachePath = function () {
|
||||
const npmCachePath = env.npm_config_cache || /* istanbul ignore next */
|
||||
(env.APPDATA ? path.join(env.APPDATA, 'npm-cache') : path.join(os.homedir(), '.npm'));
|
||||
mkdirSync(npmCachePath);
|
||||
const libvipsCachePath = path.join(npmCachePath, '_libvips');
|
||||
mkdirSync(libvipsCachePath);
|
||||
return libvipsCachePath;
|
||||
};
|
||||
|
||||
const integrity = function (platformAndArch) {
|
||||
return env[`npm_package_config_integrity_${platformAndArch.replace('-', '_')}`] || config.integrity[platformAndArch];
|
||||
};
|
||||
|
||||
const log = function (item) {
|
||||
const log = (item) => {
|
||||
if (item instanceof Error) {
|
||||
console.error(`sharp: Installation error: ${item.message}`);
|
||||
} else {
|
||||
@ -57,7 +34,43 @@ const log = function (item) {
|
||||
}
|
||||
};
|
||||
|
||||
const isRosetta = function () {
|
||||
/* istanbul ignore next */
|
||||
const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '';
|
||||
|
||||
const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`;
|
||||
|
||||
/* istanbul ignore next */
|
||||
const buildPlatformArch = () => {
|
||||
/* eslint camelcase: ["error", { allow: ["^npm_config_"] }] */
|
||||
const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env;
|
||||
return `${npm_config_platform || process.platform}${npm_config_libc || runtimeLibc()}-${npm_config_arch || process.arch}`;
|
||||
};
|
||||
|
||||
const buildSharpLibvipsIncludeDir = () => {
|
||||
try {
|
||||
return require('@sharpen/sharp-libvips-dev/include');
|
||||
} catch {}
|
||||
/* istanbul ignore next */
|
||||
return '';
|
||||
};
|
||||
|
||||
const buildSharpLibvipsCPlusPlusDir = () => {
|
||||
try {
|
||||
return require('@sharpen/sharp-libvips-dev/cplusplus');
|
||||
} catch {}
|
||||
/* istanbul ignore next */
|
||||
return '';
|
||||
};
|
||||
|
||||
const buildSharpLibvipsLibDir = () => {
|
||||
try {
|
||||
return require(`@sharpen/sharp-libvips-${buildPlatformArch()}/lib`);
|
||||
} catch {}
|
||||
/* istanbul ignore next */
|
||||
return '';
|
||||
};
|
||||
|
||||
const isRosetta = () => {
|
||||
/* istanbul ignore next */
|
||||
if (process.platform === 'darwin' && process.arch === 'x64') {
|
||||
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
||||
@ -66,12 +79,19 @@ const isRosetta = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
const globalLibvipsVersion = function () {
|
||||
/* istanbul ignore next */
|
||||
const gypRebuild = () =>
|
||||
spawnSync('node-gyp rebuild', {
|
||||
...spawnSyncOptions,
|
||||
stdio: 'inherit'
|
||||
}).status;
|
||||
|
||||
const globalLibvipsVersion = () => {
|
||||
if (process.platform !== 'win32') {
|
||||
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
||||
...spawnSyncOptions,
|
||||
env: {
|
||||
...env,
|
||||
...process.env,
|
||||
PKG_CONFIG_PATH: pkgConfigPath()
|
||||
}
|
||||
}).stdout;
|
||||
@ -82,17 +102,8 @@ const globalLibvipsVersion = function () {
|
||||
}
|
||||
};
|
||||
|
||||
const hasVendoredLibvips = function () {
|
||||
return fs.existsSync(vendorPath);
|
||||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
const removeVendoredLibvips = function () {
|
||||
fs.rmSync(vendorPath, { recursive: true, maxRetries: 3, force: true });
|
||||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
const pkgConfigPath = function () {
|
||||
const pkgConfigPath = () => {
|
||||
if (process.platform !== 'win32') {
|
||||
const brewPkgConfigPath = spawnSync(
|
||||
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
||||
@ -100,7 +111,7 @@ const pkgConfigPath = function () {
|
||||
).stdout || '';
|
||||
return [
|
||||
brewPkgConfigPath.trim(),
|
||||
env.PKG_CONFIG_PATH,
|
||||
process.env.PKG_CONFIG_PATH,
|
||||
'/usr/local/lib/pkgconfig',
|
||||
'/usr/lib/pkgconfig',
|
||||
'/usr/local/libdata/pkgconfig',
|
||||
@ -111,8 +122,9 @@ const pkgConfigPath = function () {
|
||||
}
|
||||
};
|
||||
|
||||
const useGlobalLibvips = function () {
|
||||
if (Boolean(env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
||||
const useGlobalLibvips = () => {
|
||||
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
||||
log('Detected SHARP_IGNORE_GLOBAL_LIBVIPS, skipping search for globally-installed libvips');
|
||||
return false;
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
@ -127,14 +139,15 @@ const useGlobalLibvips = function () {
|
||||
|
||||
module.exports = {
|
||||
minimumLibvipsVersion,
|
||||
minimumLibvipsVersionLabelled,
|
||||
cachePath,
|
||||
integrity,
|
||||
prebuiltPlatforms,
|
||||
buildPlatformArch,
|
||||
buildSharpLibvipsIncludeDir,
|
||||
buildSharpLibvipsCPlusPlusDir,
|
||||
buildSharpLibvipsLibDir,
|
||||
runtimePlatformArch,
|
||||
log,
|
||||
gypRebuild,
|
||||
globalLibvipsVersion,
|
||||
hasVendoredLibvips,
|
||||
removeVendoredLibvips,
|
||||
pkgConfigPath,
|
||||
useGlobalLibvips,
|
||||
mkdirSync
|
||||
useGlobalLibvips
|
||||
};
|
||||
|
@ -1,30 +0,0 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const detectLibc = require('detect-libc');
|
||||
|
||||
const env = process.env;
|
||||
|
||||
module.exports = function () {
|
||||
const arch = env.npm_config_arch || process.arch;
|
||||
const platform = env.npm_config_platform || process.platform;
|
||||
const libc = process.env.npm_config_libc ||
|
||||
/* istanbul ignore next */
|
||||
(detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '');
|
||||
const libcId = platform !== 'linux' || libc === detectLibc.GLIBC ? '' : libc;
|
||||
|
||||
const platformId = [`${platform}${libcId}`];
|
||||
|
||||
if (arch === 'arm') {
|
||||
const fallback = process.versions.electron ? '7' : '6';
|
||||
platformId.push(`armv${env.npm_config_arm_version || process.config.variables.arm_version || fallback}`);
|
||||
} else if (arch === 'arm64') {
|
||||
platformId.push(`arm64v${env.npm_config_arm_version || '8'}`);
|
||||
} else {
|
||||
platformId.push(arch);
|
||||
}
|
||||
|
||||
return platformId.join('-');
|
||||
};
|
68
lib/sharp.js
68
lib/sharp.js
@ -3,36 +3,58 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const platformAndArch = require('./platform')();
|
||||
// Inspects the runtime environment and exports the relevant sharp.node binary
|
||||
|
||||
const { familySync, versionSync } = require('detect-libc');
|
||||
|
||||
const { runtimePlatformArch, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips');
|
||||
const runtimePlatform = runtimePlatformArch();
|
||||
|
||||
/* istanbul ignore next */
|
||||
try {
|
||||
module.exports = require(`../build/Release/sharp-${platformAndArch}.node`);
|
||||
} catch (err) {
|
||||
// Bail early if bindings aren't available
|
||||
const help = ['', 'Something went wrong installing the "sharp" module', '', err.message, '', 'Possible solutions:'];
|
||||
if (/dylib/.test(err.message) && /Incompatible library version/.test(err.message)) {
|
||||
help.push('- Update Homebrew: "brew update && brew upgrade vips"');
|
||||
// Check for local build
|
||||
module.exports = require(`../build/Release/sharp-${runtimePlatform}.node`);
|
||||
} catch (errLocal) {
|
||||
try {
|
||||
// Check for runtime package
|
||||
module.exports = require(`@sharpen/sharp-${runtimePlatform}/sharp.node`);
|
||||
} catch (errPackage) {
|
||||
const help = ['Could not load the "sharp" module at runtime'];
|
||||
if (errLocal.code !== 'MODULE_NOT_FOUND') {
|
||||
help.push(`${errLocal.code}: ${errLocal.message}`);
|
||||
}
|
||||
if (errPackage.code !== 'MODULE_NOT_FOUND') {
|
||||
help.push(`${errPackage.code}: ${errPackage.message}`);
|
||||
}
|
||||
help.push('Possible solutions:');
|
||||
// Common error messages
|
||||
if (prebuiltPlatforms.includes(runtimePlatform)) {
|
||||
help.push(`- Add an explicit dependency for the runtime platform: "npm install --force @sharpen/sharp-${runtimePlatform}"`);
|
||||
} else {
|
||||
const [platform, arch] = platformAndArch.split('-');
|
||||
if (platform === 'linux' && /Module did not self-register/.test(err.message)) {
|
||||
help.push('- Using worker threads? See https://sharp.pixelplumbing.com/install#worker-threads');
|
||||
help.push(`- The ${runtimePlatform} platform requires manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||
}
|
||||
help.push(
|
||||
'- Install with verbose logging and look for errors: "npm install --ignore-scripts=false --foreground-scripts --verbose sharp"',
|
||||
`- Install for the current ${platformAndArch} runtime: "npm install --platform=${platform} --arch=${arch} sharp"`
|
||||
);
|
||||
if (runtimePlatform.startsWith('linux') && /symbol not found/i.test(errPackage)) {
|
||||
try {
|
||||
const { engines } = require(`@sharpen/sharp-libvips-${runtimePlatform}/package`);
|
||||
const libcFound = `${familySync()} ${versionSync()}`;
|
||||
const libcRequires = `${engines.musl ? 'musl' : 'glibc'} ${engines.musl || engines.glibc}`;
|
||||
help.push(`- Update your OS: found ${libcFound}, requires ${libcRequires}`);
|
||||
} catch (errEngines) {}
|
||||
}
|
||||
help.push(
|
||||
'- Consult the installation documentation: https://sharp.pixelplumbing.com/install'
|
||||
);
|
||||
// Check loaded
|
||||
if (process.platform === 'win32' || /symbol/.test(err.message)) {
|
||||
const loadedModule = Object.keys(require.cache).find((i) => /[\\/]build[\\/]Release[\\/]sharp(.*)\.node$/.test(i));
|
||||
if (loadedModule) {
|
||||
const [, loadedPackage] = loadedModule.match(/node_modules[\\/]([^\\/]+)[\\/]/);
|
||||
help.push(`- Ensure the version of sharp aligns with the ${loadedPackage} package: "npm ls sharp"`);
|
||||
if (runtimePlatform.startsWith('darwin') && /Incompatible library version/.test(errLocal.message)) {
|
||||
help.push('- Update Homebrew: "brew update && brew upgrade vips"');
|
||||
}
|
||||
if (errPackage.code === 'ERR_DLOPEN_DISABLED') {
|
||||
help.push('- Run Node.js without using the --no-addons flag');
|
||||
}
|
||||
// Link to installation docs
|
||||
if (runtimePlatform.startsWith('linux') && /Module did not self-register/.test(errLocal.message + errPackage.message)) {
|
||||
help.push('- Using worker threads on Linux? See https://sharp.pixelplumbing.com/install#worker-threads');
|
||||
} else if (runtimePlatform.startsWith('win32') && /The specified procedure could not be found/.test(errPackage.message)) {
|
||||
help.push('- Using the canvas package on Windows? See https://sharp.pixelplumbing.com/install#canvas-and-windows');
|
||||
} else {
|
||||
help.push('- Consult the installation documentation: https://sharp.pixelplumbing.com/install');
|
||||
}
|
||||
throw new Error(help.join('\n'));
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,11 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const events = require('events');
|
||||
const detectLibc = require('detect-libc');
|
||||
|
||||
const is = require('./is');
|
||||
const platformAndArch = require('./platform')();
|
||||
const { runtimePlatformArch } = require('./libvips');
|
||||
const sharp = require('./sharp');
|
||||
|
||||
/**
|
||||
@ -55,25 +53,14 @@ let versions = {
|
||||
vips: sharp.libvipsVersion()
|
||||
};
|
||||
try {
|
||||
versions = require(`../vendor/${versions.vips}/${platformAndArch}/versions.json`);
|
||||
} catch (_err) { /* ignore */ }
|
||||
versions = require(`@sharpen/sharp-${runtimePlatformArch()}/versions`);
|
||||
} catch (_) {
|
||||
try {
|
||||
versions = require(`@sharpen/sharp-libvips-${runtimePlatformArch()}/versions`);
|
||||
} catch (_) {}
|
||||
}
|
||||
versions.sharp = require('../package.json').version;
|
||||
|
||||
/**
|
||||
* An Object containing the platform and architecture
|
||||
* of the current and installed vendored binaries.
|
||||
* @member
|
||||
* @example
|
||||
* console.log(sharp.vendor);
|
||||
*/
|
||||
const vendor = {
|
||||
current: platformAndArch,
|
||||
installed: []
|
||||
};
|
||||
try {
|
||||
vendor.installed = fs.readdirSync(path.join(__dirname, `../vendor/${versions.vips}`));
|
||||
} catch (_err) { /* ignore */ }
|
||||
|
||||
/**
|
||||
* Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
|
||||
* Existing entries in the cache will be trimmed after any change in limits.
|
||||
@ -280,7 +267,6 @@ module.exports = function (Sharp) {
|
||||
Sharp.format = format;
|
||||
Sharp.interpolators = interpolators;
|
||||
Sharp.versions = versions;
|
||||
Sharp.vendor = vendor;
|
||||
Sharp.queue = queue;
|
||||
Sharp.block = block;
|
||||
Sharp.unblock = unblock;
|
||||
|
42
npm/darwin-arm64/package.json
Normal file
42
npm/darwin-arm64/package.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-darwin-arm64",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with macOS ARM64",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/darwin-arm64"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-darwin-arm64": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-darwin-arm64.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0",
|
||||
"glibc": ">=2.26"
|
||||
},
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"cpu": [
|
||||
"arm64"
|
||||
]
|
||||
}
|
39
npm/darwin-x64/package.json
Normal file
39
npm/darwin-x64/package.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-darwin-x64",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with macOS x64",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/darwin-x64"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-darwin-x64": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-darwin-x64.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0",
|
||||
"glibc": ">=2.26"
|
||||
},
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"cpu": [
|
||||
"x64"
|
||||
]
|
||||
}
|
51
npm/from-github-release.js
Normal file
51
npm/from-github-release.js
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
// Populate contents of all packages with the current GitHub release
|
||||
|
||||
const { writeFile, copyFile } = require('node:fs/promises');
|
||||
const path = require('node:path');
|
||||
const { Readable } = require('node:stream');
|
||||
const { pipeline } = require('node:stream/promises');
|
||||
const { createGunzip } = require('node:zlib');
|
||||
const { extract } = require('tar-fs');
|
||||
|
||||
const { workspaces } = require('./package.json');
|
||||
const { version } = require('../package.json');
|
||||
|
||||
const mapTarballEntry = (header) => {
|
||||
header.name = path.basename(header.name);
|
||||
return header;
|
||||
};
|
||||
|
||||
workspaces.map(async platform => {
|
||||
const url = `https://github.com/lovell/sharp/releases/download/v${version}/sharp-v${version}-napi-v7-${platform}.tar.gz`;
|
||||
const dir = path.join(__dirname, platform);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
console.log(`Skipping ${platform}: ${response.statusText}`);
|
||||
return;
|
||||
}
|
||||
// Extract prebuild tarball
|
||||
await pipeline(
|
||||
Readable.fromWeb(response.body),
|
||||
createGunzip(),
|
||||
extract(path.join(dir, 'lib'), { map: mapTarballEntry })
|
||||
);
|
||||
// Generate README
|
||||
const { name, description } = require(`./${platform}/package.json`);
|
||||
await writeFile(path.join(dir, 'README.md'), `# ${name}\n${description}`);
|
||||
// Copy Apache-2.0 LICENSE
|
||||
await copyFile(path.join(__dirname, '..', 'LICENSE'), path.join(dir, 'LICENSE'));
|
||||
// Copy Windows-specific files
|
||||
if (platform.startsWith('win32-')) {
|
||||
const sharpLibvipsDir = path.join(require(`@sharpen/sharp-libvips-${platform}/lib`), '..');
|
||||
await Promise.all(
|
||||
['versions.json', 'THIRD-PARTY-NOTICES.md'].map(
|
||||
filename => copyFile(path.join(sharpLibvipsDir, filename), path.join(dir, filename))
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
26
npm/from-local-build.js
Normal file
26
npm/from-local-build.js
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
// Populate contents of a single npm/sharpen-sharp-<build-platform> package
|
||||
// with the local/CI build directory for local/CI prebuild testing
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const { buildPlatformArch } = require('../lib/libvips');
|
||||
const platform = buildPlatformArch();
|
||||
const dest = path.join(__dirname, platform);
|
||||
|
||||
// Use same config as prebuild to copy binary files
|
||||
const release = path.join(__dirname, '..', 'build', 'Release');
|
||||
const prebuildrc = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '.prebuildrc'), 'utf8'));
|
||||
const include = new RegExp(prebuildrc['include-regex'], 'i');
|
||||
fs.cpSync(release, path.join(dest, 'lib'), {
|
||||
recursive: true,
|
||||
filter: (file) => {
|
||||
const name = path.basename(file);
|
||||
return name === 'Release' || include.test(name);
|
||||
}
|
||||
});
|
45
npm/linux-arm/package.json
Normal file
45
npm/linux-arm/package.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-linux-arm",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) ARM (32-bit)",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/linux-arm"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-linux-arm": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-linux-arm.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0",
|
||||
"glibc": ">=2.28"
|
||||
},
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"cpu": [
|
||||
"arm"
|
||||
]
|
||||
}
|
45
npm/linux-arm64/package.json
Normal file
45
npm/linux-arm64/package.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-linux-arm64",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) ARM64",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/linux-arm64"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-linux-arm64": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-linux-arm64.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0",
|
||||
"glibc": ">=2.26"
|
||||
},
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"cpu": [
|
||||
"arm64"
|
||||
]
|
||||
}
|
45
npm/linux-x64/package.json
Normal file
45
npm/linux-x64/package.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-linux-x64",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with Linux (glibc) x64",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/linux-x64"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-linux-x64": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-linux-x64.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0",
|
||||
"glibc": ">=2.26"
|
||||
},
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"cpu": [
|
||||
"x64"
|
||||
]
|
||||
}
|
45
npm/linuxmusl-arm64/package.json
Normal file
45
npm/linuxmusl-arm64/package.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-linuxmusl-arm64",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with Linux (musl) ARM64",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/linuxmusl-arm64"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-linuxmusl-arm64": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-linuxmusl-arm64.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0",
|
||||
"musl": ">=1.2.2"
|
||||
},
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"cpu": [
|
||||
"arm64"
|
||||
]
|
||||
}
|
45
npm/linuxmusl-x64/package.json
Normal file
45
npm/linuxmusl-x64/package.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-linuxmusl-x64",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with Linux (musl) x64",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/linuxmusl-x64"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-linuxmusl-x64": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-linuxmusl-x64.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0",
|
||||
"musl": ">=1.2.2"
|
||||
},
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"cpu": [
|
||||
"x64"
|
||||
]
|
||||
}
|
16
npm/package.json
Normal file
16
npm/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "@sharpen/sharp",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"private": "true",
|
||||
"workspaces": [
|
||||
"darwin-x64",
|
||||
"darwin-arm64",
|
||||
"linux-arm",
|
||||
"linux-arm64",
|
||||
"linuxmusl-arm64",
|
||||
"linuxmusl-x64",
|
||||
"linux-x64",
|
||||
"win32-ia32",
|
||||
"win32-x64"
|
||||
]
|
||||
}
|
41
npm/win32-ia32/package.json
Normal file
41
npm/win32-ia32/package.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-win32-ia32",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with Windows x86 (32-bit)",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/win32-ia32"
|
||||
},
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-win32-ia32": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-win32-ia32.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0"
|
||||
},
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"cpu": [
|
||||
"ia32"
|
||||
]
|
||||
}
|
41
npm/win32-x64/package.json
Normal file
41
npm/win32-x64/package.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@sharpen/sharp-win32-x64",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"description": "Prebuilt sharp for use with Windows x64",
|
||||
"homepage": "https://sharp.pixelplumbing.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lovell/sharp.git",
|
||||
"directory": "npm/win32-x64"
|
||||
},
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"preferUnplugged": true,
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-libvips-win32-x64": "0.0.1-alpha.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
"./sharp.node": "./lib/sharp-win32-x64.node",
|
||||
"./package": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"yarn": ">=3.2.0",
|
||||
"pnpm": ">=7.1.0"
|
||||
},
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"cpu": [
|
||||
"x64"
|
||||
]
|
||||
}
|
62
package.json
62
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "sharp",
|
||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
||||
"version": "0.32.6",
|
||||
"version": "0.33.0-alpha.1",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://github.com/lovell/sharp",
|
||||
"contributors": [
|
||||
@ -89,14 +89,16 @@
|
||||
"Lachlan Newman <lachnewman007@gmail.com>"
|
||||
],
|
||||
"scripts": {
|
||||
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
|
||||
"clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
|
||||
"install": "node install/check",
|
||||
"clean": "rm -rf build/ .nyc_output/ coverage/ test/fixtures/output.*",
|
||||
"test": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types",
|
||||
"test-lint": "semistandard && cpplint",
|
||||
"test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha",
|
||||
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
|
||||
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;LGPL-3.0-or-later;MIT\"",
|
||||
"test-leak": "./test/leak/leak.sh",
|
||||
"test-types": "tsd",
|
||||
"package-from-local-build": "node npm/from-local-build",
|
||||
"package-from-github-release": "node npm/from-github-release",
|
||||
"docs-build": "node docs/build && node docs/search-index/build",
|
||||
"docs-serve": "cd docs && npx serve",
|
||||
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
|
||||
@ -111,7 +113,7 @@
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/lovell/sharp"
|
||||
"url": "git://github.com/lovell/sharp.git"
|
||||
},
|
||||
"keywords": [
|
||||
"jpeg",
|
||||
@ -135,13 +137,30 @@
|
||||
"color": "^4.2.3",
|
||||
"detect-libc": "^2.0.2",
|
||||
"node-addon-api": "^7.0.0",
|
||||
"prebuild-install": "^7.1.1",
|
||||
"semver": "^7.5.4",
|
||||
"simple-get": "^4.0.1",
|
||||
"tar-fs": "^3.0.4",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@sharpen/sharp-darwin-arm64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-darwin-x64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-linux-arm": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-linux-arm64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-linux-x64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-linuxmusl-arm64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-linuxmusl-x64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-win32-ia32": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-win32-x64": "0.0.1-alpha.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sharpen/sharp-libvips-darwin-arm64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-darwin-x64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-dev": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-linux-arm": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-linux-arm64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-linux-x64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-linuxmusl-arm64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-linuxmusl-x64": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-win32-ia32": "0.0.1-alpha.1",
|
||||
"@sharpen/sharp-libvips-win32-x64": "0.0.1-alpha.1",
|
||||
"@types/node": "*",
|
||||
"async": "^3.2.4",
|
||||
"cc": "^3.0.1",
|
||||
@ -151,33 +170,16 @@
|
||||
"jsdoc-to-markdown": "^8.0.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"mocha": "^10.2.0",
|
||||
"mock-fs": "^5.2.0",
|
||||
"nyc": "^15.1.0",
|
||||
"prebuild": "^12.1.0",
|
||||
"semistandard": "^16.0.1",
|
||||
"tar-fs": "^3.0.4",
|
||||
"tsd": "^0.29.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"config": {
|
||||
"libvips": "8.14.5",
|
||||
"integrity": {
|
||||
"darwin-arm64v8": "sha512-1QZzICfCJd4wAO0P6qmYI5e5VFMt9iCE4QgefI8VMMbdSzjIXA9L/ARN6pkMQPZ3h20Y9RtJ2W1skgCsvCIccw==",
|
||||
"darwin-x64": "sha512-sMIKMYXsdU9FlIfztj6Kt/SfHlhlDpP0Ups7ftVFqwjaszmYmpI9y/d/q3mLb4jrzuSiSUEislSWCwBnW7MPTw==",
|
||||
"linux-arm64v8": "sha512-CD8owELzkDumaom+O3jJ8fKamILAQdj+//KK/VNcHK3sngUcFpdjx36C8okwbux9sml/T7GTB/gzpvReDrAejQ==",
|
||||
"linux-armv6": "sha512-wk6IPHatDFVWKJy7lI1TJezHGHPQut1wF2bwx256KlZwXUQU3fcVcMpV1zxXjgLFewHq2+uhyMkoSGBPahWzlA==",
|
||||
"linux-armv7": "sha512-HEZC9KYtkmBK5rUR2MqBhrVarnQVZ/TwLUeLkKq0XuoM2pc/eXI6N0Fh5NGEFwdXI2XE8g1ySf+OYS6DDi+xCQ==",
|
||||
"linux-x64": "sha512-SlFWrITSW5XVUkaFPQOySAaSGXnhkGJCj8X2wGYYta9hk5piZldQyMp4zwy0z6UeRu1qKTKtZvmq28W3Gnh9xA==",
|
||||
"linuxmusl-arm64v8": "sha512-ga9iX7WUva3sG/VsKkOD318InLlCfPIztvzCZKZ2/+izQXRbQi8VoXWMHgEN4KHACv45FTl7mJ/8CRqUzhS8wQ==",
|
||||
"linuxmusl-x64": "sha512-yeaHnpfee1hrZLok2l4eFceHzlfq8gN3QOu0R4Mh8iMK5O5vAUu97bdtxeZZeJJvHw8tfh2/msGi0qysxKN8bw==",
|
||||
"win32-arm64v8": "sha512-kR91hy9w1+GEXK56hLh51+hBCBo7T+ijM4Slkmvb/2PsYZySq5H7s61n99iDYl6kTJP2y9sW5Xcvm3uuXDaDgg==",
|
||||
"win32-ia32": "sha512-HrnofEbzHNpHJ0vVnjsTj5yfgVdcqdWshXuwFO2zc8xlEjA83BvXZ0lVj9MxPxkxJ2ta+/UlLr+CFzc5bOceMw==",
|
||||
"win32-x64": "sha512-BwKckinJZ0Fu/EcunqiLPwOLEBWp4xf8GV7nvmVuKKz5f6B+GxoA2k9aa2wueqv4r4RJVgV/aWXZWFKOIjre/Q=="
|
||||
},
|
||||
"runtime": "napi",
|
||||
"target": 9
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"libvips": ">=8.14.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
|
@ -1,151 +0,0 @@
|
||||
/* Object part of the VSource and VTarget class
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 1991-2001 The National Gallery
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
#include <vips/debug.h>
|
||||
|
||||
/*
|
||||
#define VIPS_DEBUG
|
||||
#define VIPS_DEBUG_VERBOSE
|
||||
*/
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
|
||||
VSource
|
||||
VSource::new_from_descriptor( int descriptor )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_descriptor( descriptor )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_file( const char *filename )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_file( filename )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_blob( VipsBlob *blob )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_blob( blob )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_memory( const void *data,
|
||||
size_t size )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_memory( data, size )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_options( const char *options )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_options( options )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VTarget
|
||||
VTarget::new_to_descriptor( int descriptor )
|
||||
{
|
||||
VipsTarget *output;
|
||||
|
||||
if( !(output = vips_target_new_to_descriptor( descriptor )) )
|
||||
throw VError();
|
||||
|
||||
VTarget out( output );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VTarget
|
||||
VTarget::new_to_file( const char *filename )
|
||||
{
|
||||
VipsTarget *output;
|
||||
|
||||
if( !(output = vips_target_new_to_file( filename )) )
|
||||
throw VError();
|
||||
|
||||
VTarget out( output );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VTarget
|
||||
VTarget::new_to_memory()
|
||||
{
|
||||
VipsTarget *output;
|
||||
|
||||
if( !(output = vips_target_new_to_memory()) )
|
||||
throw VError();
|
||||
|
||||
VTarget out( output );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VIPS_NAMESPACE_END
|
@ -1,49 +0,0 @@
|
||||
// Code for error type
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 1991-2001 The National Gallery
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
|
||||
std::ostream &operator<<( std::ostream &file, const VError &err )
|
||||
{
|
||||
err.ostream_print( file );
|
||||
return( file );
|
||||
}
|
||||
|
||||
void VError::ostream_print( std::ostream &file ) const
|
||||
{
|
||||
file << _what;
|
||||
}
|
||||
|
||||
VIPS_NAMESPACE_END
|
File diff suppressed because it is too large
Load Diff
@ -1,62 +0,0 @@
|
||||
/* Object part of VInterpolate class
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 1991-2001 The National Gallery
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
#include <vips/debug.h>
|
||||
|
||||
/*
|
||||
#define VIPS_DEBUG
|
||||
#define VIPS_DEBUG_VERBOSE
|
||||
*/
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
|
||||
VInterpolate
|
||||
VInterpolate::new_from_name( const char *name, VOption *options )
|
||||
{
|
||||
VipsInterpolate *interp;
|
||||
|
||||
if( !(interp = vips_interpolate_new( name )) ) {
|
||||
delete options;
|
||||
throw VError();
|
||||
}
|
||||
delete options;
|
||||
|
||||
VInterpolate out( interp );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VIPS_NAMESPACE_END
|
@ -1,27 +0,0 @@
|
||||
// Object part of VRegion class
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
#include <vips/debug.h>
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
|
||||
VRegion
|
||||
VRegion::new_from_image( VImage image )
|
||||
{
|
||||
VipsRegion *region;
|
||||
|
||||
if( !(region = vips_region_new( image.get_image() )) ) {
|
||||
throw VError();
|
||||
}
|
||||
|
||||
VRegion out( region );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VIPS_NAMESPACE_END
|
File diff suppressed because it is too large
Load Diff
@ -73,8 +73,6 @@ readableStream.pipe(transformer).pipe(writableStream);
|
||||
|
||||
console.log(sharp.format);
|
||||
console.log(sharp.versions);
|
||||
console.log(sharp.vendor.current);
|
||||
console.log(sharp.vendor.installed.join(', '));
|
||||
|
||||
sharp.queue.on('change', (queueLength: number) => {
|
||||
console.log(`Queue contains ${queueLength} task(s)`);
|
||||
|
@ -1,52 +0,0 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const agent = require('../../lib/agent');
|
||||
|
||||
describe('HTTP agent', function () {
|
||||
it('Without proxy', function () {
|
||||
assert.strictEqual(null, agent());
|
||||
});
|
||||
|
||||
it('HTTPS proxy with auth from HTTPS_PROXY', function () {
|
||||
process.env.HTTPS_PROXY = 'https://user:pass@secure:123';
|
||||
let logMsg = '';
|
||||
const proxy = agent(msg => { logMsg = msg; });
|
||||
delete process.env.HTTPS_PROXY;
|
||||
assert.strictEqual('object', typeof proxy);
|
||||
assert.strictEqual('secure', proxy.options.proxy.host);
|
||||
assert.strictEqual(123, proxy.options.proxy.port);
|
||||
assert.strictEqual('user:pass', proxy.options.proxy.proxyAuth);
|
||||
assert.strictEqual(443, proxy.defaultPort);
|
||||
assert.strictEqual(logMsg, 'Via proxy https://secure:123 with credentials');
|
||||
});
|
||||
|
||||
it('HTTPS proxy with auth from HTTPS_PROXY using credentials containing special characters', function () {
|
||||
process.env.HTTPS_PROXY = 'https://user,:pass=@secure:789';
|
||||
let logMsg = '';
|
||||
const proxy = agent(msg => { logMsg = msg; });
|
||||
delete process.env.HTTPS_PROXY;
|
||||
assert.strictEqual('object', typeof proxy);
|
||||
assert.strictEqual('secure', proxy.options.proxy.host);
|
||||
assert.strictEqual(789, proxy.options.proxy.port);
|
||||
assert.strictEqual('user,:pass=', proxy.options.proxy.proxyAuth);
|
||||
assert.strictEqual(443, proxy.defaultPort);
|
||||
assert.strictEqual(logMsg, 'Via proxy https://secure:789 with credentials');
|
||||
});
|
||||
|
||||
it('HTTP proxy without auth from npm_config_proxy', function () {
|
||||
process.env.npm_config_proxy = 'http://plaintext:456';
|
||||
let logMsg = '';
|
||||
const proxy = agent(msg => { logMsg = msg; });
|
||||
delete process.env.npm_config_proxy;
|
||||
assert.strictEqual('object', typeof proxy);
|
||||
assert.strictEqual('plaintext', proxy.options.proxy.host);
|
||||
assert.strictEqual(456, proxy.options.proxy.port);
|
||||
assert.strictEqual(null, proxy.options.proxy.proxyAuth);
|
||||
assert.strictEqual(443, proxy.defaultPort);
|
||||
assert.strictEqual(logMsg, 'Via proxy http://plaintext:456 no credentials');
|
||||
});
|
||||
});
|
@ -7,7 +7,6 @@ const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const semver = require('semver');
|
||||
const libvips = require('../../lib/libvips');
|
||||
const mockFS = require('mock-fs');
|
||||
|
||||
const originalPlatform = process.platform;
|
||||
|
||||
@ -59,10 +58,6 @@ describe('libvips binaries', function () {
|
||||
assert.strictEqual('string', typeof minimumLibvipsVersion);
|
||||
assert.notStrictEqual(null, semver.valid(minimumLibvipsVersion));
|
||||
});
|
||||
it('hasVendoredLibvips returns a boolean', function () {
|
||||
const hasVendoredLibvips = libvips.hasVendoredLibvips();
|
||||
assert.strictEqual('boolean', typeof hasVendoredLibvips);
|
||||
});
|
||||
it('useGlobalLibvips can be ignored via an env var', function () {
|
||||
process.env.SHARP_IGNORE_GLOBAL_LIBVIPS = 1;
|
||||
|
||||
@ -71,62 +66,48 @@ describe('libvips binaries', function () {
|
||||
|
||||
delete process.env.SHARP_IGNORE_GLOBAL_LIBVIPS;
|
||||
});
|
||||
it('cachePath returns a valid path ending with _libvips', function () {
|
||||
const cachePath = libvips.cachePath();
|
||||
assert.strictEqual('string', typeof cachePath);
|
||||
assert.strictEqual('_libvips', cachePath.substr(-8));
|
||||
assert.strictEqual(true, fs.existsSync(cachePath));
|
||||
});
|
||||
|
||||
describe('Build time platform detection', () => {
|
||||
it('Can override platform with npm_config_platform and npm_config_libc', () => {
|
||||
process.env.npm_config_platform = 'testplatform';
|
||||
process.env.npm_config_libc = 'testlibc';
|
||||
const [platform] = libvips.buildPlatformArch().split('-');
|
||||
assert.strictEqual(platform, 'testplatformtestlibc');
|
||||
delete process.env.npm_config_platform;
|
||||
delete process.env.npm_config_libc;
|
||||
});
|
||||
it('Can override arch with npm_config_arch', () => {
|
||||
process.env.npm_config_arch = 'test';
|
||||
const [, arch] = libvips.buildPlatformArch().split('-');
|
||||
assert.strictEqual(arch, 'test');
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
});
|
||||
|
||||
describe('integrity', function () {
|
||||
it('reads value from environment variable', function () {
|
||||
const prev = process.env.npm_package_config_integrity_platform_arch;
|
||||
process.env.npm_package_config_integrity_platform_arch = 'sha512-test';
|
||||
|
||||
const integrity = libvips.integrity('platform-arch');
|
||||
assert.strictEqual('sha512-test', integrity);
|
||||
|
||||
process.env.npm_package_config_integrity_platform_arch = prev;
|
||||
describe('Build time directories', () => {
|
||||
it('sharp-libvips include', () => {
|
||||
const dir = libvips.buildSharpLibvipsIncludeDir();
|
||||
assert.strictEqual(fs.statSync(dir).isDirectory(), true);
|
||||
});
|
||||
it('reads value from package.json', function () {
|
||||
const prev = process.env.npm_package_config_integrity_linux_x64;
|
||||
delete process.env.npm_package_config_integrity_linux_x64;
|
||||
|
||||
const integrity = libvips.integrity('linux-x64');
|
||||
assert.strictEqual('sha512-', integrity.substr(0, 7));
|
||||
|
||||
process.env.npm_package_config_integrity_linux_x64 = prev;
|
||||
it('sharp-libvips cplusplus', () => {
|
||||
const dir = libvips.buildSharpLibvipsCPlusPlusDir();
|
||||
assert.strictEqual(fs.statSync(dir).isDirectory(), true);
|
||||
});
|
||||
it('sharp-libvips lib', () => {
|
||||
const dir = libvips.buildSharpLibvipsLibDir();
|
||||
assert.strictEqual(fs.statSync(dir).isDirectory(), true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('safe directory creation', function () {
|
||||
before(function () {
|
||||
mockFS({
|
||||
exampleDirA: {
|
||||
exampleDirB: {
|
||||
exampleFile: 'Example test file'
|
||||
}
|
||||
}
|
||||
describe('Runtime detection', () => {
|
||||
it('platform', () => {
|
||||
const [platform] = libvips.runtimePlatformArch().split('-');
|
||||
assert.strict(['darwin', 'linux', 'linuxmusl', 'win32'].includes(platform));
|
||||
});
|
||||
});
|
||||
after(function () { mockFS.restore(); });
|
||||
|
||||
it('mkdirSync creates a directory', function () {
|
||||
const dirPath = 'createdDir';
|
||||
|
||||
libvips.mkdirSync(dirPath);
|
||||
assert.strictEqual(true, fs.existsSync(dirPath));
|
||||
});
|
||||
it('mkdirSync does not throw error or overwrite an existing dir', function () {
|
||||
const dirPath = 'exampleDirA';
|
||||
const nestedDirPath = 'exampleDirA/exampleDirB';
|
||||
assert.strictEqual(true, fs.existsSync(dirPath));
|
||||
|
||||
libvips.mkdirSync(dirPath);
|
||||
|
||||
assert.strictEqual(true, fs.existsSync(dirPath));
|
||||
assert.strictEqual(true, fs.existsSync(nestedDirPath));
|
||||
it('arch', () => {
|
||||
const [, arch] = libvips.runtimePlatformArch().split('-');
|
||||
assert.strict(['arm', 'arm64', 'ia32', 'x64'].includes(arch));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,91 +0,0 @@
|
||||
// Copyright 2013 Lovell Fuller and others.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const platform = require('../../lib/platform');
|
||||
|
||||
describe('Platform-detection', function () {
|
||||
it('Can override arch with npm_config_arch', function () {
|
||||
process.env.npm_config_arch = 'test';
|
||||
assert.strictEqual('test', platform().split('-')[1]);
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
|
||||
it('Can override platform with npm_config_platform', function () {
|
||||
process.env.npm_config_platform = 'test';
|
||||
assert.strictEqual('test', platform().split('-')[0]);
|
||||
delete process.env.npm_config_platform;
|
||||
});
|
||||
|
||||
it('Can override ARM version via --arm-version', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
process.env.npm_config_arm_version = 'test';
|
||||
assert.strictEqual('armvtest', platform().split('-')[1]);
|
||||
delete process.env.npm_config_arm_version;
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
|
||||
it('Can override ARM64 version via --arm-version', function () {
|
||||
process.env.npm_config_arch = 'arm64';
|
||||
process.env.npm_config_arm_version = 'test';
|
||||
assert.strictEqual('arm64vtest', platform().split('-')[1]);
|
||||
delete process.env.npm_config_arm_version;
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
|
||||
if (process.config.variables.arm_version) {
|
||||
it('Can detect ARM version via process.config', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
assert.strictEqual(`armv${process.config.variables.arm_version}`, platform().split('-')[1]);
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
}
|
||||
|
||||
if (!process.config.variables.arm_version) {
|
||||
it('Defaults to ARMv6 for 32-bit', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
assert.strictEqual('armv6', platform().split('-')[1]);
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
}
|
||||
|
||||
it('Defaults to ARMv8 for 64-bit', function () {
|
||||
process.env.npm_config_arch = 'arm64';
|
||||
assert.strictEqual('arm64v8', platform().split('-')[1]);
|
||||
delete process.env.npm_config_arch;
|
||||
});
|
||||
|
||||
it('Can ensure version ARMv7 if electron version is present', function () {
|
||||
process.env.npm_config_arch = 'arm';
|
||||
process.versions.electron = 'test';
|
||||
assert.strictEqual('armv7', platform().split('-')[1]);
|
||||
delete process.env.npm_config_arch;
|
||||
delete process.versions.electron;
|
||||
});
|
||||
|
||||
it('Can override libc if platform is linux', function () {
|
||||
process.env.npm_config_platform = 'linux';
|
||||
process.env.npm_config_libc = 'test';
|
||||
assert.strictEqual('linuxtest', platform().split('-')[0]);
|
||||
delete process.env.npm_config_platform;
|
||||
delete process.env.npm_config_libc;
|
||||
});
|
||||
|
||||
it('Handles libc value "glibc" as default linux', function () {
|
||||
process.env.npm_config_platform = 'linux';
|
||||
process.env.npm_config_libc = 'glibc';
|
||||
assert.strictEqual('linux', platform().split('-')[0]);
|
||||
delete process.env.npm_config_platform;
|
||||
delete process.env.npm_config_libc;
|
||||
});
|
||||
|
||||
it('Discards libc value on non-linux platform', function () {
|
||||
process.env.npm_config_platform = 'win32';
|
||||
process.env.npm_config_libc = 'gnuwin32';
|
||||
assert.strictEqual('win32', platform().split('-')[0]);
|
||||
delete process.env.npm_config_platform;
|
||||
delete process.env.npm_config_libc;
|
||||
});
|
||||
});
|
@ -146,14 +146,6 @@ describe('Utilities', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Vendor', function () {
|
||||
it('Contains expected attributes', function () {
|
||||
assert.strictEqual('object', typeof sharp.vendor);
|
||||
assert.strictEqual('string', typeof sharp.vendor.current);
|
||||
assert.strictEqual(true, Array.isArray(sharp.vendor.installed));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Block', () => {
|
||||
it('Can block a named operation', () => {
|
||||
sharp.block({ operation: ['test'] });
|
||||
|
Loading…
x
Reference in New Issue
Block a user