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"
|
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 install --build-from-source"
|
||||||
- run: sudo docker exec sharp sh -c "npm test"
|
- 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"
|
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"npx prebuild --upload=$prebuild_upload\" || true"
|
||||||
linux-arm64-glibc-node-20:
|
linux-arm64-glibc-node-20:
|
||||||
resource_class: arm.medium
|
resource_class: arm.medium
|
||||||
@ -54,6 +60,12 @@ jobs:
|
|||||||
sudo docker cp . sharp:/mnt/sharp/.
|
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 install --build-from-source"
|
||||||
- run: sudo docker exec sharp sh -c "npm test"
|
- 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:
|
linux-arm64-musl-node-18:
|
||||||
resource_class: arm.medium
|
resource_class: arm.medium
|
||||||
machine:
|
machine:
|
||||||
@ -65,6 +77,12 @@ jobs:
|
|||||||
sudo docker exec sharp sh -c "apk add build-base git python3 font-noto --update-cache"
|
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 install --build-from-source"
|
||||||
- run: sudo docker exec sharp sh -c "npm test"
|
- 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"
|
- run: "[[ -n $CIRCLE_TAG ]] && sudo docker exec --env prebuild_upload sharp sh -c \"npx prebuild --upload=$prebuild_upload\" || true"
|
||||||
linux-arm64-musl-node-20:
|
linux-arm64-musl-node-20:
|
||||||
resource_class: arm.medium
|
resource_class: arm.medium
|
||||||
@ -79,3 +97,9 @@ jobs:
|
|||||||
sudo docker cp . sharp:/mnt/sharp/.
|
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 install --build-from-source"
|
||||||
- run: sudo docker exec sharp sh -c "npm test"
|
- 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. -->
|
<!-- Please place an [x] in the box to confirm. -->
|
||||||
|
|
||||||
- [ ] I have read the [documentation relating to installation](https://sharp.pixelplumbing.com/install).
|
- [ ] 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?
|
### 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.
|
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?
|
### 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
|
- os: macos-11
|
||||||
nodejs_arch: x64
|
nodejs_arch: x64
|
||||||
nodejs_version: "^18.17.0"
|
nodejs_version: "^18.17.0"
|
||||||
|
nodejs_version_major: 18
|
||||||
platform: darwin-x64
|
platform: darwin-x64
|
||||||
prebuild: true
|
prebuild: true
|
||||||
- os: macos-11
|
- os: macos-11
|
||||||
@ -98,13 +99,17 @@ jobs:
|
|||||||
architecture: ${{ matrix.nodejs_arch }}
|
architecture: ${{ matrix.nodejs_arch }}
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Fix working directory ownership
|
|
||||||
if: matrix.container
|
|
||||||
run: chown root.root .
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: npm install --build-from-source
|
run: npm install --build-from-source
|
||||||
- name: Test
|
- name: Test
|
||||||
run: npm 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
|
- name: Prebuild
|
||||||
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
|
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
|
||||||
env:
|
env:
|
||||||
@ -130,9 +135,13 @@ jobs:
|
|||||||
mkdir /opt/nodejs
|
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
|
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
|
export PATH=$PATH:/opt/nodejs/bin
|
||||||
chown root.root .
|
|
||||||
npm install --build-from-source
|
npm install --build-from-source
|
||||||
npx mocha --no-config --spec=test/unit/io.js
|
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
|
[[ -n $prebuild_upload ]] && npx prebuild || true
|
||||||
macstadium-runner:
|
macstadium-runner:
|
||||||
permissions:
|
permissions:
|
||||||
@ -167,6 +176,13 @@ jobs:
|
|||||||
run: npm install --build-from-source
|
run: npm install --build-from-source
|
||||||
- name: Test
|
- name: Test
|
||||||
run: npm 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
|
- name: Prebuild
|
||||||
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
|
if: matrix.prebuild && startsWith(github.ref, 'refs/tags/')
|
||||||
env:
|
env:
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,8 @@
|
|||||||
build
|
build
|
||||||
node_modules
|
node_modules
|
||||||
/coverage
|
/coverage
|
||||||
|
npm/*/*
|
||||||
|
!npm/*/package.json
|
||||||
test/bench/node_modules
|
test/bench/node_modules
|
||||||
test/fixtures/output*
|
test/fixtures/output*
|
||||||
test/fixtures/vips-properties.xml
|
test/fixtures/vips-properties.xml
|
||||||
@ -9,7 +11,6 @@ test/saliency/report.json
|
|||||||
test/saliency/Image*
|
test/saliency/Image*
|
||||||
test/saliency/[Uu]serData*
|
test/saliency/[Uu]serData*
|
||||||
!test/saliency/userData.js
|
!test/saliency/userData.js
|
||||||
vendor
|
|
||||||
.gitattributes
|
.gitattributes
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.nyc_output
|
.nyc_output
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"runtime": "napi",
|
"runtime": "napi",
|
||||||
"include-regex": "(sharp-.+\\.node|libvips-cpp\\.dll)",
|
"include-regex": "(sharp-.+\\.node|libvips-.+\\.dll|libglib-.+\\.dll|libgobject-.+\\.dll)",
|
||||||
"prerelease": true,
|
"prerelease": true,
|
||||||
"strip": 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': {
|
'variables': {
|
||||||
'vips_version': '<!(node -p "require(\'./lib/libvips\').minimumLibvipsVersion")',
|
'vips_version': '<!(node -p "require(\'./lib/libvips\').minimumLibvipsVersion")',
|
||||||
'platform_and_arch': '<!(node -p "require(\'./lib/platform\')()")',
|
'platform_and_arch': '<!(node -p "require(\'./lib/libvips\').buildPlatformArch()")',
|
||||||
'sharp_vendor_dir': './vendor/<(vips_version)/<(platform_and_arch)'
|
'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': [{
|
'targets': [{
|
||||||
'target_name': 'libvips-cpp',
|
'target_name': 'win-libvips-cpp',
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS == "win"', {
|
['OS == "win"', {
|
||||||
# Build libvips C++ binding for Windows due to MSVC std library ABI changes
|
# Build libvips C++ binding for Windows due to MSVC std library ABI changes
|
||||||
@ -15,19 +20,19 @@
|
|||||||
'_ALLOW_KEYWORD_MACROS'
|
'_ALLOW_KEYWORD_MACROS'
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'src/libvips/cplusplus/VConnection.cpp',
|
'<(sharp_libvips_cplusplus_dir)/VConnection.cpp',
|
||||||
'src/libvips/cplusplus/VError.cpp',
|
'<(sharp_libvips_cplusplus_dir)/VError.cpp',
|
||||||
'src/libvips/cplusplus/VImage.cpp',
|
'<(sharp_libvips_cplusplus_dir)/VImage.cpp',
|
||||||
'src/libvips/cplusplus/VInterpolate.cpp',
|
'<(sharp_libvips_cplusplus_dir)/VInterpolate.cpp',
|
||||||
'src/libvips/cplusplus/VRegion.cpp'
|
'<(sharp_libvips_cplusplus_dir)/VRegion.cpp'
|
||||||
],
|
],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'<(sharp_vendor_dir)/include',
|
'<(sharp_libvips_include_dir)',
|
||||||
'<(sharp_vendor_dir)/include/glib-2.0',
|
'<(sharp_libvips_include_dir)/glib-2.0',
|
||||||
'<(sharp_vendor_dir)/lib/glib-2.0/include'
|
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': ['<(sharp_vendor_dir)/lib'],
|
'library_dirs': ['<(sharp_libvips_lib_dir)'],
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'libvips.lib',
|
'libvips.lib',
|
||||||
'libglib-2.0.lib',
|
'libglib-2.0.lib',
|
||||||
@ -76,10 +81,9 @@
|
|||||||
],
|
],
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'<!(node -p "require(\'node-addon-api\').gyp")',
|
'<!(node -p "require(\'node-addon-api\').gyp")',
|
||||||
'libvips-cpp'
|
'win-libvips-cpp'
|
||||||
],
|
],
|
||||||
'variables': {
|
'variables': {
|
||||||
'runtime_link%': 'shared',
|
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS != "win"', {
|
['OS != "win"', {
|
||||||
'pkg_config_path': '<!(node -p "require(\'./lib/libvips\').pkgConfigPath()")',
|
'pkg_config_path': '<!(node -p "require(\'./lib/libvips\').pkgConfigPath()")',
|
||||||
@ -106,12 +110,8 @@
|
|||||||
['use_global_libvips == "true"', {
|
['use_global_libvips == "true"', {
|
||||||
# Use pkg-config for include and lib
|
# 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)'],
|
'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': [
|
'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"', {
|
['OS == "linux"', {
|
||||||
'defines': [
|
'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.
|
# 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
|
# Use pre-built libvips stored locally within node_modules
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'<(sharp_vendor_dir)/include',
|
'<(sharp_libvips_include_dir)',
|
||||||
'<(sharp_vendor_dir)/include/glib-2.0',
|
'<(sharp_libvips_include_dir)/glib-2.0',
|
||||||
'<(sharp_vendor_dir)/lib/glib-2.0/include'
|
'<(sharp_libvips_lib_dir)/glib-2.0/include'
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS == "win"', {
|
['OS == "win"', {
|
||||||
@ -133,7 +133,7 @@
|
|||||||
'_FILE_OFFSET_BITS=64'
|
'_FILE_OFFSET_BITS=64'
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': ['<(sharp_vendor_dir)/lib'],
|
'library_dirs': ['<(sharp_libvips_lib_dir)'],
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'libvips.lib',
|
'libvips.lib',
|
||||||
'libglib-2.0.lib',
|
'libglib-2.0.lib',
|
||||||
@ -143,7 +143,9 @@
|
|||||||
}],
|
}],
|
||||||
['OS == "mac"', {
|
['OS == "mac"', {
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': ['../<(sharp_vendor_dir)/lib'],
|
'library_dirs': [
|
||||||
|
'<(sharp_libvips_lib_dir)'
|
||||||
|
],
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'libvips-cpp.42.dylib'
|
'libvips-cpp.42.dylib'
|
||||||
]
|
]
|
||||||
@ -151,7 +153,9 @@
|
|||||||
'xcode_settings': {
|
'xcode_settings': {
|
||||||
'OTHER_LDFLAGS': [
|
'OTHER_LDFLAGS': [
|
||||||
# Ensure runtime linking is relative to sharp.node
|
# 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'
|
'_GLIBCXX_USE_CXX11_ABI=1'
|
||||||
],
|
],
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'library_dirs': ['../<(sharp_vendor_dir)/lib'],
|
'library_dirs': [
|
||||||
|
'<(sharp_libvips_lib_dir)'
|
||||||
|
],
|
||||||
'libraries': [
|
'libraries': [
|
||||||
'-l:libvips-cpp.so.42'
|
'-l:libvips-cpp.so.42'
|
||||||
],
|
],
|
||||||
'ldflags': [
|
'ldflags': [
|
||||||
# Ensure runtime linking is relative to sharp.node
|
# 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
|
yarn add sharp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm add sharp
|
||||||
|
```
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
* Node.js >= 18.17.0
|
* 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 x64 (>= 10.13)
|
||||||
* macOS ARM64
|
* macOS ARM64
|
||||||
* Linux x64 (glibc >= 2.17, musl >= 1.1.24, CPU with SSE4.2)
|
* Linux x64 (glibc >= 2.26, musl >= 1.2.2, CPU with SSE4.2)
|
||||||
* Linux ARM64 (glibc >= 2.17, musl >= 1.1.24)
|
* Linux ARM64 (glibc >= 2.26, musl >= 1.2.2)
|
||||||
|
* Linux ARM (glibc >= 2.28)
|
||||||
* Windows x64
|
* Windows x64
|
||||||
* Windows x86
|
* 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
|
This provides support for the
|
||||||
JPEG, PNG, WebP, AVIF (limited to 8-bit depth), TIFF, GIF and SVG (input) image formats.
|
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
|
## Custom libvips
|
||||||
|
|
||||||
To use a custom, globally-installed version of libvips instead of the provided binaries,
|
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`.
|
and that it can be located using `pkg-config --modversion vips-cpp`.
|
||||||
|
|
||||||
For help compiling libvips and its dependencies, please see
|
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:
|
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),
|
* a globally-installed libvips is detected (set the `SHARP_IGNORE_GLOBAL_LIBVIPS` environment variable to skip this), or
|
||||||
* prebuilt sharp binaries do not exist for the current platform, or
|
|
||||||
* when the `npm install --build-from-source` flag is used.
|
* when the `npm install --build-from-source` flag is used.
|
||||||
|
|
||||||
Building from source requires:
|
Building from source requires:
|
||||||
@ -131,83 +55,11 @@ Building from source requires:
|
|||||||
* C++11 compiler
|
* C++11 compiler
|
||||||
* [node-gyp](https://github.com/nodejs/node-gyp#installation) and its dependencies
|
* [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.
|
For cross-compiling, the `--platform`, `--arch` and `--libc` npm flags
|
||||||
|
(or the `npm_config_platform`, `npm_config_arch` and `npm_config_libc` environment variables)
|
||||||
### Prebuilt sharp binaries
|
can be used to configure the target environment.
|
||||||
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
## FreeBSD
|
## FreeBSD
|
||||||
|
|
||||||
@ -242,15 +94,18 @@ unaffected.
|
|||||||
|
|
||||||
The `node_modules` directory of the
|
The `node_modules` directory of the
|
||||||
[deployment package](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-package.html)
|
[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),
|
When building your deployment package on a machine that differs from the target architecture,
|
||||||
run the following additional command after `npm install`:
|
you will need to install either `@sharpen/sharp-linux-x64` or `@sharpen/sharp-linux-arm64` package.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install
|
npm install --force @sharpen/sharp-linux-x64
|
||||||
rm -rf node_modules/sharp
|
```
|
||||||
SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm install --arch=x64 --platform=linux --libc=glibc sharp
|
|
||||||
|
```sh
|
||||||
|
npm install --force @sharpen/sharp-linux-arm64
|
||||||
```
|
```
|
||||||
|
|
||||||
To get the best performance select the largest memory available.
|
To get the best performance select the largest memory available.
|
||||||
@ -302,7 +157,7 @@ custom:
|
|||||||
- sharp
|
- sharp
|
||||||
packagerOptions:
|
packagerOptions:
|
||||||
scripts:
|
scripts:
|
||||||
- npm install --arch=x64 --platform=linux sharp
|
- npm install --force @sharpen/sharp-linux-x64
|
||||||
```
|
```
|
||||||
|
|
||||||
## TypeScript
|
## TypeScript
|
||||||
@ -358,14 +213,7 @@ Module did not self-register
|
|||||||
|
|
||||||
### Canvas and Windows
|
### Canvas and Windows
|
||||||
|
|
||||||
The prebuilt binaries provided by `canvas` for Windows
|
If both `canvas` and `sharp` modules are used in the same Windows process, the following error may occur:
|
||||||
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:
|
|
||||||
```
|
```
|
||||||
The specified procedure could not be found.
|
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 stream = require('stream');
|
||||||
const is = require('./is');
|
const is = require('./is');
|
||||||
|
|
||||||
require('./libvips').hasVendoredLibvips();
|
|
||||||
require('./sharp');
|
require('./sharp');
|
||||||
|
|
||||||
// Use NODE_DEBUG=sharp to enable libvips warnings
|
// 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;
|
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 */
|
/** An Object containing the available interpolators and their proper values */
|
||||||
const interpolators: Interpolators;
|
const interpolators: Interpolators;
|
||||||
|
|
||||||
|
129
lib/libvips.js
129
lib/libvips.js
@ -3,53 +3,30 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const os = require('os');
|
|
||||||
const path = require('path');
|
|
||||||
const spawnSync = require('child_process').spawnSync;
|
const spawnSync = require('child_process').spawnSync;
|
||||||
const semverCoerce = require('semver/functions/coerce');
|
const semverCoerce = require('semver/functions/coerce');
|
||||||
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
|
||||||
|
const detectLibc = require('detect-libc');
|
||||||
|
|
||||||
const platform = require('./platform');
|
const { engines } = require('../package.json');
|
||||||
const { config } = require('../package.json');
|
|
||||||
|
|
||||||
const env = process.env;
|
const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || /* istanbul ignore next */
|
||||||
const minimumLibvipsVersionLabelled = env.npm_package_config_libvips || /* istanbul ignore next */
|
engines.libvips;
|
||||||
config.libvips;
|
|
||||||
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
|
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 = {
|
const spawnSyncOptions = {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
shell: true
|
shell: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const vendorPath = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platform());
|
const log = (item) => {
|
||||||
|
|
||||||
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) {
|
|
||||||
if (item instanceof Error) {
|
if (item instanceof Error) {
|
||||||
console.error(`sharp: Installation error: ${item.message}`);
|
console.error(`sharp: Installation error: ${item.message}`);
|
||||||
} else {
|
} 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 */
|
/* istanbul ignore next */
|
||||||
if (process.platform === 'darwin' && process.arch === 'x64') {
|
if (process.platform === 'darwin' && process.arch === 'x64') {
|
||||||
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
|
||||||
@ -66,12 +79,19 @@ const isRosetta = function () {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const globalLibvipsVersion = function () {
|
/* istanbul ignore next */
|
||||||
|
const gypRebuild = () =>
|
||||||
|
spawnSync('node-gyp rebuild', {
|
||||||
|
...spawnSyncOptions,
|
||||||
|
stdio: 'inherit'
|
||||||
|
}).status;
|
||||||
|
|
||||||
|
const globalLibvipsVersion = () => {
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
|
||||||
...spawnSyncOptions,
|
...spawnSyncOptions,
|
||||||
env: {
|
env: {
|
||||||
...env,
|
...process.env,
|
||||||
PKG_CONFIG_PATH: pkgConfigPath()
|
PKG_CONFIG_PATH: pkgConfigPath()
|
||||||
}
|
}
|
||||||
}).stdout;
|
}).stdout;
|
||||||
@ -82,17 +102,8 @@ const globalLibvipsVersion = function () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasVendoredLibvips = function () {
|
|
||||||
return fs.existsSync(vendorPath);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
const removeVendoredLibvips = function () {
|
const pkgConfigPath = () => {
|
||||||
fs.rmSync(vendorPath, { recursive: true, maxRetries: 3, force: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
/* istanbul ignore next */
|
|
||||||
const pkgConfigPath = function () {
|
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
const brewPkgConfigPath = spawnSync(
|
const brewPkgConfigPath = spawnSync(
|
||||||
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
|
||||||
@ -100,7 +111,7 @@ const pkgConfigPath = function () {
|
|||||||
).stdout || '';
|
).stdout || '';
|
||||||
return [
|
return [
|
||||||
brewPkgConfigPath.trim(),
|
brewPkgConfigPath.trim(),
|
||||||
env.PKG_CONFIG_PATH,
|
process.env.PKG_CONFIG_PATH,
|
||||||
'/usr/local/lib/pkgconfig',
|
'/usr/local/lib/pkgconfig',
|
||||||
'/usr/lib/pkgconfig',
|
'/usr/lib/pkgconfig',
|
||||||
'/usr/local/libdata/pkgconfig',
|
'/usr/local/libdata/pkgconfig',
|
||||||
@ -111,8 +122,9 @@ const pkgConfigPath = function () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const useGlobalLibvips = function () {
|
const useGlobalLibvips = () => {
|
||||||
if (Boolean(env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
|
||||||
|
log('Detected SHARP_IGNORE_GLOBAL_LIBVIPS, skipping search for globally-installed libvips');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
@ -127,14 +139,15 @@ const useGlobalLibvips = function () {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
minimumLibvipsVersion,
|
minimumLibvipsVersion,
|
||||||
minimumLibvipsVersionLabelled,
|
prebuiltPlatforms,
|
||||||
cachePath,
|
buildPlatformArch,
|
||||||
integrity,
|
buildSharpLibvipsIncludeDir,
|
||||||
|
buildSharpLibvipsCPlusPlusDir,
|
||||||
|
buildSharpLibvipsLibDir,
|
||||||
|
runtimePlatformArch,
|
||||||
log,
|
log,
|
||||||
|
gypRebuild,
|
||||||
globalLibvipsVersion,
|
globalLibvipsVersion,
|
||||||
hasVendoredLibvips,
|
|
||||||
removeVendoredLibvips,
|
|
||||||
pkgConfigPath,
|
pkgConfigPath,
|
||||||
useGlobalLibvips,
|
useGlobalLibvips
|
||||||
mkdirSync
|
|
||||||
};
|
};
|
||||||
|
@ -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';
|
'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 */
|
/* istanbul ignore next */
|
||||||
try {
|
try {
|
||||||
module.exports = require(`../build/Release/sharp-${platformAndArch}.node`);
|
// Check for local build
|
||||||
} catch (err) {
|
module.exports = require(`../build/Release/sharp-${runtimePlatform}.node`);
|
||||||
// Bail early if bindings aren't available
|
} catch (errLocal) {
|
||||||
const help = ['', 'Something went wrong installing the "sharp" module', '', err.message, '', 'Possible solutions:'];
|
try {
|
||||||
if (/dylib/.test(err.message) && /Incompatible library version/.test(err.message)) {
|
// Check for runtime package
|
||||||
help.push('- Update Homebrew: "brew update && brew upgrade vips"');
|
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 {
|
} else {
|
||||||
const [platform, arch] = platformAndArch.split('-');
|
help.push(`- The ${runtimePlatform} platform requires manual installation of libvips >= ${minimumLibvipsVersion}`);
|
||||||
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(
|
if (runtimePlatform.startsWith('linux') && /symbol not found/i.test(errPackage)) {
|
||||||
'- Install with verbose logging and look for errors: "npm install --ignore-scripts=false --foreground-scripts --verbose sharp"',
|
try {
|
||||||
`- Install for the current ${platformAndArch} runtime: "npm install --platform=${platform} --arch=${arch} sharp"`
|
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(
|
if (runtimePlatform.startsWith('darwin') && /Incompatible library version/.test(errLocal.message)) {
|
||||||
'- Consult the installation documentation: https://sharp.pixelplumbing.com/install'
|
help.push('- Update Homebrew: "brew update && brew upgrade vips"');
|
||||||
);
|
|
||||||
// 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 (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'));
|
throw new Error(help.join('\n'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,11 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const events = require('events');
|
const events = require('events');
|
||||||
const detectLibc = require('detect-libc');
|
const detectLibc = require('detect-libc');
|
||||||
|
|
||||||
const is = require('./is');
|
const is = require('./is');
|
||||||
const platformAndArch = require('./platform')();
|
const { runtimePlatformArch } = require('./libvips');
|
||||||
const sharp = require('./sharp');
|
const sharp = require('./sharp');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,25 +53,14 @@ let versions = {
|
|||||||
vips: sharp.libvipsVersion()
|
vips: sharp.libvipsVersion()
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
versions = require(`../vendor/${versions.vips}/${platformAndArch}/versions.json`);
|
versions = require(`@sharpen/sharp-${runtimePlatformArch()}/versions`);
|
||||||
} catch (_err) { /* ignore */ }
|
} catch (_) {
|
||||||
|
try {
|
||||||
|
versions = require(`@sharpen/sharp-libvips-${runtimePlatformArch()}/versions`);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
versions.sharp = require('../package.json').version;
|
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.
|
* 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.
|
* 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.format = format;
|
||||||
Sharp.interpolators = interpolators;
|
Sharp.interpolators = interpolators;
|
||||||
Sharp.versions = versions;
|
Sharp.versions = versions;
|
||||||
Sharp.vendor = vendor;
|
|
||||||
Sharp.queue = queue;
|
Sharp.queue = queue;
|
||||||
Sharp.block = block;
|
Sharp.block = block;
|
||||||
Sharp.unblock = unblock;
|
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",
|
"name": "sharp",
|
||||||
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
|
"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>",
|
"author": "Lovell Fuller <npm@lovell.info>",
|
||||||
"homepage": "https://github.com/lovell/sharp",
|
"homepage": "https://github.com/lovell/sharp",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@ -89,14 +89,16 @@
|
|||||||
"Lachlan Newman <lachnewman007@gmail.com>"
|
"Lachlan Newman <lachnewman007@gmail.com>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
|
"install": "node install/check",
|
||||||
"clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
|
"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": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types",
|
||||||
"test-lint": "semistandard && cpplint",
|
"test-lint": "semistandard && cpplint",
|
||||||
"test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha",
|
"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-leak": "./test/leak/leak.sh",
|
||||||
"test-types": "tsd",
|
"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-build": "node docs/build && node docs/search-index/build",
|
||||||
"docs-serve": "cd docs && npx serve",
|
"docs-serve": "cd docs && npx serve",
|
||||||
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
|
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
|
||||||
@ -111,7 +113,7 @@
|
|||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/lovell/sharp"
|
"url": "git://github.com/lovell/sharp.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"jpeg",
|
"jpeg",
|
||||||
@ -135,13 +137,30 @@
|
|||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
"detect-libc": "^2.0.2",
|
"detect-libc": "^2.0.2",
|
||||||
"node-addon-api": "^7.0.0",
|
"node-addon-api": "^7.0.0",
|
||||||
"prebuild-install": "^7.1.1",
|
"semver": "^7.5.4"
|
||||||
"semver": "^7.5.4",
|
},
|
||||||
"simple-get": "^4.0.1",
|
"optionalDependencies": {
|
||||||
"tar-fs": "^3.0.4",
|
"@sharpen/sharp-darwin-arm64": "0.0.1-alpha.1",
|
||||||
"tunnel-agent": "^0.6.0"
|
"@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": {
|
"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": "*",
|
"@types/node": "*",
|
||||||
"async": "^3.2.4",
|
"async": "^3.2.4",
|
||||||
"cc": "^3.0.1",
|
"cc": "^3.0.1",
|
||||||
@ -151,33 +170,16 @@
|
|||||||
"jsdoc-to-markdown": "^8.0.0",
|
"jsdoc-to-markdown": "^8.0.0",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
"mocha": "^10.2.0",
|
"mocha": "^10.2.0",
|
||||||
"mock-fs": "^5.2.0",
|
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"prebuild": "^12.1.0",
|
"prebuild": "^12.1.0",
|
||||||
"semistandard": "^16.0.1",
|
"semistandard": "^16.0.1",
|
||||||
|
"tar-fs": "^3.0.4",
|
||||||
"tsd": "^0.29.0"
|
"tsd": "^0.29.0"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.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": {
|
"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": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/libvips"
|
"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.format);
|
||||||
console.log(sharp.versions);
|
console.log(sharp.versions);
|
||||||
console.log(sharp.vendor.current);
|
|
||||||
console.log(sharp.vendor.installed.join(', '));
|
|
||||||
|
|
||||||
sharp.queue.on('change', (queueLength: number) => {
|
sharp.queue.on('change', (queueLength: number) => {
|
||||||
console.log(`Queue contains ${queueLength} task(s)`);
|
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 fs = require('fs');
|
||||||
const semver = require('semver');
|
const semver = require('semver');
|
||||||
const libvips = require('../../lib/libvips');
|
const libvips = require('../../lib/libvips');
|
||||||
const mockFS = require('mock-fs');
|
|
||||||
|
|
||||||
const originalPlatform = process.platform;
|
const originalPlatform = process.platform;
|
||||||
|
|
||||||
@ -59,10 +58,6 @@ describe('libvips binaries', function () {
|
|||||||
assert.strictEqual('string', typeof minimumLibvipsVersion);
|
assert.strictEqual('string', typeof minimumLibvipsVersion);
|
||||||
assert.notStrictEqual(null, semver.valid(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 () {
|
it('useGlobalLibvips can be ignored via an env var', function () {
|
||||||
process.env.SHARP_IGNORE_GLOBAL_LIBVIPS = 1;
|
process.env.SHARP_IGNORE_GLOBAL_LIBVIPS = 1;
|
||||||
|
|
||||||
@ -71,62 +66,48 @@ describe('libvips binaries', function () {
|
|||||||
|
|
||||||
delete process.env.SHARP_IGNORE_GLOBAL_LIBVIPS;
|
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);
|
describe('Build time platform detection', () => {
|
||||||
assert.strictEqual('_libvips', cachePath.substr(-8));
|
it('Can override platform with npm_config_platform and npm_config_libc', () => {
|
||||||
assert.strictEqual(true, fs.existsSync(cachePath));
|
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 () {
|
describe('Build time directories', () => {
|
||||||
it('reads value from environment variable', function () {
|
it('sharp-libvips include', () => {
|
||||||
const prev = process.env.npm_package_config_integrity_platform_arch;
|
const dir = libvips.buildSharpLibvipsIncludeDir();
|
||||||
process.env.npm_package_config_integrity_platform_arch = 'sha512-test';
|
assert.strictEqual(fs.statSync(dir).isDirectory(), true);
|
||||||
|
|
||||||
const integrity = libvips.integrity('platform-arch');
|
|
||||||
assert.strictEqual('sha512-test', integrity);
|
|
||||||
|
|
||||||
process.env.npm_package_config_integrity_platform_arch = prev;
|
|
||||||
});
|
});
|
||||||
it('reads value from package.json', function () {
|
it('sharp-libvips cplusplus', () => {
|
||||||
const prev = process.env.npm_package_config_integrity_linux_x64;
|
const dir = libvips.buildSharpLibvipsCPlusPlusDir();
|
||||||
delete process.env.npm_package_config_integrity_linux_x64;
|
assert.strictEqual(fs.statSync(dir).isDirectory(), true);
|
||||||
|
});
|
||||||
const integrity = libvips.integrity('linux-x64');
|
it('sharp-libvips lib', () => {
|
||||||
assert.strictEqual('sha512-', integrity.substr(0, 7));
|
const dir = libvips.buildSharpLibvipsLibDir();
|
||||||
|
assert.strictEqual(fs.statSync(dir).isDirectory(), true);
|
||||||
process.env.npm_package_config_integrity_linux_x64 = prev;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('safe directory creation', function () {
|
describe('Runtime detection', () => {
|
||||||
before(function () {
|
it('platform', () => {
|
||||||
mockFS({
|
const [platform] = libvips.runtimePlatformArch().split('-');
|
||||||
exampleDirA: {
|
assert.strict(['darwin', 'linux', 'linuxmusl', 'win32'].includes(platform));
|
||||||
exampleDirB: {
|
|
||||||
exampleFile: 'Example test file'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
it('arch', () => {
|
||||||
after(function () { mockFS.restore(); });
|
const [, arch] = libvips.runtimePlatformArch().split('-');
|
||||||
|
assert.strict(['arm', 'arm64', 'ia32', 'x64'].includes(arch));
|
||||||
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));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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', () => {
|
describe('Block', () => {
|
||||||
it('Can block a named operation', () => {
|
it('Can block a named operation', () => {
|
||||||
sharp.block({ operation: ['test'] });
|
sharp.block({ operation: ['test'] });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user