From 30859f4bd00adffd7b42aefe415e6869f73ca719 Mon Sep 17 00:00:00 2001 From: suyanhanx Date: Mon, 20 Mar 2023 20:11:03 +0800 Subject: [PATCH 1/4] fix(bindings/nodejs): publish sub-package name Signed-off-by: suyanhanx --- .github/workflows/bindings_nodejs.yml | 5 +- bindings/nodejs/.gitignore | 2 - bindings/nodejs/generated.js | 274 ++++++++++++++++++ bindings/nodejs/npm/darwin-x64/package.json | 2 +- .../nodejs/npm/linux-x64-gnu/package.json | 2 +- .../nodejs/npm/win32-x64-msvc/package.json | 2 +- bindings/nodejs/package.json | 5 +- licenserc.toml | 3 - 8 files changed, 282 insertions(+), 13 deletions(-) create mode 100644 bindings/nodejs/generated.js diff --git a/.github/workflows/bindings_nodejs.yml b/.github/workflows/bindings_nodejs.yml index 09e395881f0..af080a3ab9b 100644 --- a/.github/workflows/bindings_nodejs.yml +++ b/.github/workflows/bindings_nodejs.yml @@ -132,10 +132,7 @@ jobs: - uses: actions/upload-artifact@v3 with: name: bindings-windows - path: | - bindings/nodejs/*.node - bindings/nodejs/index.d.ts - bindings/nodejs/generated*.* + path: bindings/nodejs/*.node - name: Test bindings run: yarn test diff --git a/bindings/nodejs/.gitignore b/bindings/nodejs/.gitignore index c3b1f289a8e..12017c53952 100644 --- a/bindings/nodejs/.gitignore +++ b/bindings/nodejs/.gitignore @@ -191,5 +191,3 @@ Cargo.lock !.yarn/patches *.node docs/ - -generated*.* diff --git a/bindings/nodejs/generated.js b/bindings/nodejs/generated.js new file mode 100644 index 00000000000..c3c427b3f83 --- /dev/null +++ b/bindings/nodejs/generated.js @@ -0,0 +1,274 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const { existsSync, readFileSync } = require('fs') +const { join } = require('path') + +const { platform, arch } = process + +let nativeBinding = null +let localFileExisted = false +let loadError = null + +function isMusl() { + // For Node 10 + if (!process.report || typeof process.report.getReport !== 'function') { + try { + const lddPath = require('child_process').execSync('which ldd').toString().trim(); + return readFileSync(lddPath, 'utf8').includes('musl') + } catch (e) { + return true + } + } else { + const { glibcVersionRuntime } = process.report.getReport().header + return !glibcVersionRuntime + } +} + +switch (platform) { + case 'android': + switch (arch) { + case 'arm64': + localFileExisted = existsSync(join(__dirname, 'opendal.android-arm64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.android-arm64.node') + } else { + nativeBinding = require('@opendal/lib-android-arm64') + } + } catch (e) { + loadError = e + } + break + case 'arm': + localFileExisted = existsSync(join(__dirname, 'opendal.android-arm-eabi.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.android-arm-eabi.node') + } else { + nativeBinding = require('@opendal/lib-android-arm-eabi') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Android ${arch}`) + } + break + case 'win32': + switch (arch) { + case 'x64': + localFileExisted = existsSync( + join(__dirname, 'opendal.win32-x64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.win32-x64-msvc.node') + } else { + nativeBinding = require('@opendal/lib-win32-x64-msvc') + } + } catch (e) { + loadError = e + } + break + case 'ia32': + localFileExisted = existsSync( + join(__dirname, 'opendal.win32-ia32-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.win32-ia32-msvc.node') + } else { + nativeBinding = require('@opendal/lib-win32-ia32-msvc') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'opendal.win32-arm64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.win32-arm64-msvc.node') + } else { + nativeBinding = require('@opendal/lib-win32-arm64-msvc') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Windows: ${arch}`) + } + break + case 'darwin': + localFileExisted = existsSync(join(__dirname, 'opendal.darwin-universal.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.darwin-universal.node') + } else { + nativeBinding = require('@opendal/lib-darwin-universal') + } + break + } catch {} + switch (arch) { + case 'x64': + localFileExisted = existsSync(join(__dirname, 'opendal.darwin-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.darwin-x64.node') + } else { + nativeBinding = require('@opendal/lib-darwin-x64') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'opendal.darwin-arm64.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.darwin-arm64.node') + } else { + nativeBinding = require('@opendal/lib-darwin-arm64') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on macOS: ${arch}`) + } + break + case 'freebsd': + if (arch !== 'x64') { + throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) + } + localFileExisted = existsSync(join(__dirname, 'opendal.freebsd-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.freebsd-x64.node') + } else { + nativeBinding = require('@opendal/lib-freebsd-x64') + } + } catch (e) { + loadError = e + } + break + case 'linux': + switch (arch) { + case 'x64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-x64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-x64-musl.node') + } else { + nativeBinding = require('@opendal/lib-linux-x64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-x64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-x64-gnu.node') + } else { + nativeBinding = require('@opendal/lib-linux-x64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-arm64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-arm64-musl.node') + } else { + nativeBinding = require('@opendal/lib-linux-arm64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-arm64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-arm64-gnu.node') + } else { + nativeBinding = require('@opendal/lib-linux-arm64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm': + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-arm-gnueabihf.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-arm-gnueabihf.node') + } else { + nativeBinding = require('@opendal/lib-linux-arm-gnueabihf') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Linux: ${arch}`) + } + break + default: + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) +} + +if (!nativeBinding) { + if (loadError) { + throw loadError + } + throw new Error(`Failed to load native binding`) +} + +const { Operator, Entry, Metadata, Lister, BlockingLister } = nativeBinding + +module.exports.Operator = Operator +module.exports.Entry = Entry +module.exports.Metadata = Metadata +module.exports.Lister = Lister +module.exports.BlockingLister = BlockingLister diff --git a/bindings/nodejs/npm/darwin-x64/package.json b/bindings/nodejs/npm/darwin-x64/package.json index ef53f1a7ed5..a9c95dcb678 100644 --- a/bindings/nodejs/npm/darwin-x64/package.json +++ b/bindings/nodejs/npm/darwin-x64/package.json @@ -15,4 +15,4 @@ "engines": { "node": ">= 10" } -} +} \ No newline at end of file diff --git a/bindings/nodejs/npm/linux-x64-gnu/package.json b/bindings/nodejs/npm/linux-x64-gnu/package.json index 0b9917ca8ae..77268539b82 100644 --- a/bindings/nodejs/npm/linux-x64-gnu/package.json +++ b/bindings/nodejs/npm/linux-x64-gnu/package.json @@ -18,4 +18,4 @@ "libc": [ "glibc" ] -} +} \ No newline at end of file diff --git a/bindings/nodejs/npm/win32-x64-msvc/package.json b/bindings/nodejs/npm/win32-x64-msvc/package.json index d1403b91b9c..1769271bca2 100644 --- a/bindings/nodejs/npm/win32-x64-msvc/package.json +++ b/bindings/nodejs/npm/win32-x64-msvc/package.json @@ -15,4 +15,4 @@ "engines": { "node": ">= 10" } -} +} \ No newline at end of file diff --git a/bindings/nodejs/package.json b/bindings/nodejs/package.json index 43ddba389ea..3471bf2a742 100644 --- a/bindings/nodejs/package.json +++ b/bindings/nodejs/package.json @@ -8,7 +8,10 @@ "description": "Open Data Access Layer: Access data freely, painlessly, and efficiently", "repository": "git@github.com/apache/incubator-opendal.git", "napi": { - "name": "opendal" + "name": "opendal", + "package": { + "name": "@opendal/lib" + } }, "keywords": [ "api", diff --git a/licenserc.toml b/licenserc.toml index 2428610ff4d..bbd10e576b9 100644 --- a/licenserc.toml +++ b/licenserc.toml @@ -25,9 +25,6 @@ excludes = [ # Python binding related files "**/venv/**", - # Nodejs binding related files - "bindings/nodejs/generated*.*", - # Website generated files "website/build", "website/.docusaurus", From bc822282d8ed8b14983b68f83c51d2f2d41e162e Mon Sep 17 00:00:00 2001 From: suyanhanx Date: Mon, 20 Mar 2023 20:11:03 +0800 Subject: [PATCH 2/4] fix(bindings/nodejs): publish sub-package name Signed-off-by: suyanhanx --- .github/workflows/bindings_nodejs.yml | 7 +- bindings/nodejs/.gitignore | 2 - bindings/nodejs/generated.js | 274 ++++++++++++++++++++++++++ bindings/nodejs/package.json | 13 +- licenserc.toml | 3 - 5 files changed, 286 insertions(+), 13 deletions(-) create mode 100644 bindings/nodejs/generated.js diff --git a/.github/workflows/bindings_nodejs.yml b/.github/workflows/bindings_nodejs.yml index 09e395881f0..f0fc78ba13f 100644 --- a/.github/workflows/bindings_nodejs.yml +++ b/.github/workflows/bindings_nodejs.yml @@ -132,10 +132,7 @@ jobs: - uses: actions/upload-artifact@v3 with: name: bindings-windows - path: | - bindings/nodejs/*.node - bindings/nodejs/index.d.ts - bindings/nodejs/generated*.* + path: bindings/nodejs/*.node - name: Test bindings run: yarn test @@ -211,7 +208,7 @@ jobs: - name: Publish run: | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - npm publish --access public + npm publish env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/bindings/nodejs/.gitignore b/bindings/nodejs/.gitignore index c3b1f289a8e..12017c53952 100644 --- a/bindings/nodejs/.gitignore +++ b/bindings/nodejs/.gitignore @@ -191,5 +191,3 @@ Cargo.lock !.yarn/patches *.node docs/ - -generated*.* diff --git a/bindings/nodejs/generated.js b/bindings/nodejs/generated.js new file mode 100644 index 00000000000..c3c427b3f83 --- /dev/null +++ b/bindings/nodejs/generated.js @@ -0,0 +1,274 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const { existsSync, readFileSync } = require('fs') +const { join } = require('path') + +const { platform, arch } = process + +let nativeBinding = null +let localFileExisted = false +let loadError = null + +function isMusl() { + // For Node 10 + if (!process.report || typeof process.report.getReport !== 'function') { + try { + const lddPath = require('child_process').execSync('which ldd').toString().trim(); + return readFileSync(lddPath, 'utf8').includes('musl') + } catch (e) { + return true + } + } else { + const { glibcVersionRuntime } = process.report.getReport().header + return !glibcVersionRuntime + } +} + +switch (platform) { + case 'android': + switch (arch) { + case 'arm64': + localFileExisted = existsSync(join(__dirname, 'opendal.android-arm64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.android-arm64.node') + } else { + nativeBinding = require('@opendal/lib-android-arm64') + } + } catch (e) { + loadError = e + } + break + case 'arm': + localFileExisted = existsSync(join(__dirname, 'opendal.android-arm-eabi.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.android-arm-eabi.node') + } else { + nativeBinding = require('@opendal/lib-android-arm-eabi') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Android ${arch}`) + } + break + case 'win32': + switch (arch) { + case 'x64': + localFileExisted = existsSync( + join(__dirname, 'opendal.win32-x64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.win32-x64-msvc.node') + } else { + nativeBinding = require('@opendal/lib-win32-x64-msvc') + } + } catch (e) { + loadError = e + } + break + case 'ia32': + localFileExisted = existsSync( + join(__dirname, 'opendal.win32-ia32-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.win32-ia32-msvc.node') + } else { + nativeBinding = require('@opendal/lib-win32-ia32-msvc') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'opendal.win32-arm64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.win32-arm64-msvc.node') + } else { + nativeBinding = require('@opendal/lib-win32-arm64-msvc') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Windows: ${arch}`) + } + break + case 'darwin': + localFileExisted = existsSync(join(__dirname, 'opendal.darwin-universal.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.darwin-universal.node') + } else { + nativeBinding = require('@opendal/lib-darwin-universal') + } + break + } catch {} + switch (arch) { + case 'x64': + localFileExisted = existsSync(join(__dirname, 'opendal.darwin-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.darwin-x64.node') + } else { + nativeBinding = require('@opendal/lib-darwin-x64') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'opendal.darwin-arm64.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.darwin-arm64.node') + } else { + nativeBinding = require('@opendal/lib-darwin-arm64') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on macOS: ${arch}`) + } + break + case 'freebsd': + if (arch !== 'x64') { + throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) + } + localFileExisted = existsSync(join(__dirname, 'opendal.freebsd-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.freebsd-x64.node') + } else { + nativeBinding = require('@opendal/lib-freebsd-x64') + } + } catch (e) { + loadError = e + } + break + case 'linux': + switch (arch) { + case 'x64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-x64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-x64-musl.node') + } else { + nativeBinding = require('@opendal/lib-linux-x64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-x64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-x64-gnu.node') + } else { + nativeBinding = require('@opendal/lib-linux-x64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-arm64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-arm64-musl.node') + } else { + nativeBinding = require('@opendal/lib-linux-arm64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-arm64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-arm64-gnu.node') + } else { + nativeBinding = require('@opendal/lib-linux-arm64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm': + localFileExisted = existsSync( + join(__dirname, 'opendal.linux-arm-gnueabihf.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./opendal.linux-arm-gnueabihf.node') + } else { + nativeBinding = require('@opendal/lib-linux-arm-gnueabihf') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Linux: ${arch}`) + } + break + default: + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) +} + +if (!nativeBinding) { + if (loadError) { + throw loadError + } + throw new Error(`Failed to load native binding`) +} + +const { Operator, Entry, Metadata, Lister, BlockingLister } = nativeBinding + +module.exports.Operator = Operator +module.exports.Entry = Entry +module.exports.Metadata = Metadata +module.exports.Lister = Lister +module.exports.BlockingLister = BlockingLister diff --git a/bindings/nodejs/package.json b/bindings/nodejs/package.json index 43ddba389ea..675c6b809e6 100644 --- a/bindings/nodejs/package.json +++ b/bindings/nodejs/package.json @@ -8,7 +8,10 @@ "description": "Open Data Access Layer: Access data freely, painlessly, and efficiently", "repository": "git@github.com/apache/incubator-opendal.git", "napi": { - "name": "opendal" + "name": "opendal", + "package": { + "name": "@opendal/lib" + } }, "keywords": [ "api", @@ -46,8 +49,8 @@ }, "scripts": { "artifacts": "napi artifacts", - "build": "napi build --platform --release --js generated.js --js-package-name @opendal/lib", - "build:debug": "napi build --platform --js generated.js --js-package-name @opendal/lib", + "build": "napi build --platform --release --js generated.js", + "build:debug": "napi build --platform --js generated.js", "docs": "typedoc", "format": "prettier --write .", "prepublishOnly": "napi prepublish -t npm", @@ -69,6 +72,10 @@ } ] }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, "packageManager": "yarn@3.4.1+sha224.cca891d4a8671d4898aba3426674bb734dbbf88cef82dd4dacd71c9f", "resolutions": { "@napi-rs/cli@^2.14.8": "patch:@napi-rs/cli@npm%3A2.14.8#./.yarn/patches/@napi-rs-cli-npm-2.14.8-71492d0ade.patch" diff --git a/licenserc.toml b/licenserc.toml index 2428610ff4d..bbd10e576b9 100644 --- a/licenserc.toml +++ b/licenserc.toml @@ -25,9 +25,6 @@ excludes = [ # Python binding related files "**/venv/**", - # Nodejs binding related files - "bindings/nodejs/generated*.*", - # Website generated files "website/build", "website/.docusaurus", From 7fc54b54c90fae69a6f1923114f280decd544b5b Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Mon, 20 Mar 2023 20:47:17 +0800 Subject: [PATCH 3/4] Setup rust toolchain for nodejs test Signed-off-by: Xuanwo --- .github/workflows/bindings_nodejs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/bindings_nodejs.yml b/.github/workflows/bindings_nodejs.yml index af080a3ab9b..c88400a9b66 100644 --- a/.github/workflows/bindings_nodejs.yml +++ b/.github/workflows/bindings_nodejs.yml @@ -51,6 +51,8 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Setup Rust toolchain + uses: ./.github/actions/setup - name: Setup node uses: actions/setup-node@v3 with: From 22488b55d2ae42eb04be28939df567850086578b Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Mon, 20 Mar 2023 20:49:33 +0800 Subject: [PATCH 4/4] Fix eol Signed-off-by: Xuanwo --- bindings/nodejs/npm/darwin-x64/package.json | 2 +- bindings/nodejs/npm/linux-x64-gnu/package.json | 2 +- bindings/nodejs/npm/win32-x64-msvc/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/nodejs/npm/darwin-x64/package.json b/bindings/nodejs/npm/darwin-x64/package.json index a9c95dcb678..ef53f1a7ed5 100644 --- a/bindings/nodejs/npm/darwin-x64/package.json +++ b/bindings/nodejs/npm/darwin-x64/package.json @@ -15,4 +15,4 @@ "engines": { "node": ">= 10" } -} \ No newline at end of file +} diff --git a/bindings/nodejs/npm/linux-x64-gnu/package.json b/bindings/nodejs/npm/linux-x64-gnu/package.json index 77268539b82..0b9917ca8ae 100644 --- a/bindings/nodejs/npm/linux-x64-gnu/package.json +++ b/bindings/nodejs/npm/linux-x64-gnu/package.json @@ -18,4 +18,4 @@ "libc": [ "glibc" ] -} \ No newline at end of file +} diff --git a/bindings/nodejs/npm/win32-x64-msvc/package.json b/bindings/nodejs/npm/win32-x64-msvc/package.json index 1769271bca2..d1403b91b9c 100644 --- a/bindings/nodejs/npm/win32-x64-msvc/package.json +++ b/bindings/nodejs/npm/win32-x64-msvc/package.json @@ -15,4 +15,4 @@ "engines": { "node": ">= 10" } -} \ No newline at end of file +}