couchbase 4.2.4 → 4.2.5-dev.2

Sign up to get free protection for your applications and to get access to all the features.
package/CMakeLists.txt CHANGED
@@ -1,9 +1,108 @@
1
1
  cmake_minimum_required(VERSION 3.17)
2
2
  cmake_policy(SET CMP0042 NEW)
3
3
  cmake_policy(SET CMP0048 NEW)
4
+ include(FetchContent)
4
5
  set(CMAKE_CXX_STANDARD 17)
5
6
  set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
6
7
 
8
+ function(download_nodejs_headers)
9
+ message("Finding Node.js headers SHA for version: ${NODE_RUNTIMEVERSION}")
10
+ file(DOWNLOAD
11
+ https://nodejs.org/dist/v${NODE_RUNTIMEVERSION}/SHASUMS256.txt
12
+ "${CMAKE_CURRENT_BINARY_DIR}/SHASUM256.txt"
13
+ TLS_VERIFY ON)
14
+
15
+ file(READ "${CMAKE_CURRENT_BINARY_DIR}/SHASUM256.txt" HASH_FILE_CONTENT)
16
+ set(REGEX_CHECK "node-v${NODE_RUNTIMEVERSION}-headers.tar.gz")
17
+ string(REPLACE "\n" ";" HASH_FILE_CONTENT ${HASH_FILE_CONTENT})
18
+ FOREACH(HASH ${HASH_FILE_CONTENT})
19
+ string(FIND ${HASH} ${REGEX_CHECK} FOUND_FILE)
20
+ if("${FOUND_FILE}" GREATER_EQUAL "0")
21
+ string(REGEX MATCH
22
+ "^[0-9a-f]+"
23
+ CB_NODE_VERSION_SHA256
24
+ ${HASH})
25
+ break()
26
+ endif()
27
+ ENDFOREACH()
28
+
29
+ if(NOT CB_NODE_VERSION_SHA256)
30
+ message(FATAL_ERROR "Failed to extract expected hash from node shasum file.")
31
+ else()
32
+ message("Using SHA=${CB_NODE_VERSION_SHA256}")
33
+ endif()
34
+ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24.0")
35
+ # see https://cmake.org/cmake/help/latest/policy/CMP0135.html
36
+ # and Externalproject_add - DOWNLOAD_EXTRACT_TIMESTAMP
37
+ FetchContent_Declare(
38
+ nodejs_headers
39
+ URL https://nodejs.org/dist/v${NODE_RUNTIMEVERSION}/node-v${NODE_RUNTIMEVERSION}-headers.tar.gz
40
+ URL_HASH SHA256=${CB_NODE_VERSION_SHA256}
41
+ DOWNLOAD_EXTRACT_TIMESTAMP FALSE
42
+ )
43
+ else()
44
+ FetchContent_Declare(
45
+ nodejs_headers
46
+ URL https://nodejs.org/dist/v${NODE_RUNTIMEVERSION}/node-v${NODE_RUNTIMEVERSION}-headers.tar.gz
47
+ URL_HASH SHA256=${CB_NODE_VERSION_SHA256}
48
+ )
49
+ endif()
50
+
51
+ message("Downloading Node.js ${NODE_RUNTIMEVERSION} headers...")
52
+ FetchContent_MakeAvailable(nodejs_headers)
53
+ message("Downloaded Node.js ${NODE_RUNTIMEVERSION} headers to ${nodejs_headers_SOURCE_DIR}")
54
+ set(NODEJS_INC_DIR "${nodejs_headers_SOURCE_DIR}/include/node" PARENT_SCOPE)
55
+ endfunction()
56
+
57
+ function(download_nodejs_win_lib)
58
+ if(NODE_RUNTIME STREQUAL "electron")
59
+ set(NODE_LIB_URL "https://artifacts.electronjs.org/headers/dist/v${NODE_RUNTIMEVERSION}")
60
+ if(NODE_ARCH STREQUAL "x64")
61
+ set(NODE_LIB_URL "${NODE_LIB_URL}/x64")
62
+ endif()
63
+ else()
64
+ set(NODE_LIB_URL "https://nodejs.org/dist/v${NODE_RUNTIMEVERSION}")
65
+ if(NODE_ARCH STREQUAL "x64")
66
+ set(NODE_LIB_URL "${NODE_LIB_URL}/win-x64")
67
+ else()
68
+ set(NODE_LIB_URL "${NODE_LIB_URL}/win-x86")
69
+ endif()
70
+ endif()
71
+ set(NODE_LIB_URL "${NODE_LIB_URL}/node.lib")
72
+
73
+ FetchContent_Declare(
74
+ nodejs_win_lib
75
+ URL ${NODE_LIB_URL}
76
+ DOWNLOAD_NO_EXTRACT TRUE
77
+ )
78
+
79
+ message("Downloading ${NODE_RUNTIME} v${NODE_RUNTIMEVERSION} win lib...")
80
+ FetchContent_MakeAvailable(nodejs_win_lib)
81
+ message("Downloaded ${NODE_RUNTIME} v${NODE_RUNTIMEVERSION} win lib to ${nodejs_win_lib_SOURCE_DIR}")
82
+ set(NODEJS_LIB "${nodejs_win_lib_SOURCE_DIR}/node.lib" PARENT_SCOPE)
83
+ endfunction()
84
+
85
+ # cmake-js >= v7.0 no longer downloads the full Node.js Windows lib and utilizes the https://github.com/nodejs/node-api-headers
86
+ # project to build the lib. Since we rely on OpenSSL we need to pull in more than just the node-api headers, so lets download
87
+ # the node.lib ourselves.
88
+ if(WIN32 AND CMAKE_JS_VERSION VERSION_GREATER_EQUAL "7.0.0")
89
+ SET(NODEJS_LIB "")
90
+ download_nodejs_win_lib()
91
+ else()
92
+ SET(NODEJS_LIB "${CMAKE_JS_LIB}")
93
+ endif()
94
+
95
+ if(CMAKE_JS_VERSION VERSION_GREATER_EQUAL "7.0.0")
96
+ set(NODEJS_INC_DIR "")
97
+ download_nodejs_headers()
98
+ set(NODEJS_INC_DIR "${NODEJS_INC_DIR};${CMAKE_JS_INC}")
99
+ else()
100
+ set(NODEJS_INC_DIR "${CMAKE_JS_INC}")
101
+ endif()
102
+
103
+ message(STATUS "NODEJS_INC_DIR=${NODEJS_INC_DIR}")
104
+ message(STATUS "NODEJS_LIB=${NODEJS_LIB}")
105
+
7
106
  # Set up some build requirements for Windows.
8
107
  set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
9
108
  if(WIN32)
@@ -13,12 +112,12 @@ endif()
13
112
 
14
113
  # We need to import this globally in order for OpenSSL to be available
15
114
  # to our dependant libraries such as couchbase-cxx-client.
16
- include_directories(${CMAKE_JS_INC})
115
+ include_directories(${NODEJS_INC_DIR})
17
116
 
18
117
  set(COUCHBASE_CXX_CLIENT_BUILD_TESTS OFF CACHE BOOL "" FORCE)
19
118
  set(COUCHBASE_CXX_CLIENT_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
20
119
  set(COUCHBASE_CXX_CLIENT_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
21
- set(COUCHBASE_CXX_CLIENT_POST_LINKED_OPENSSL ON CACHE BOOL "" FORCE)
120
+ set(COUCHBASE_CXX_CLIENT_POST_LINKED_OPENSSL ON CACHE BOOL "")
22
121
  set(COUCHBASE_CXX_CLIENT_STATIC_STDLIB ON CACHE BOOL "" FORCE)
23
122
  add_subdirectory(deps/couchbase-cxx-client)
24
123
 
@@ -28,20 +127,46 @@ file(GLOB SOURCE_FILES "src/*.cpp")
28
127
  add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
29
128
 
30
129
  add_definitions(-DNAPI_VERSION=6)
31
- target_include_directories(${PROJECT_NAME}
32
- PRIVATE ${CMAKE_JS_INC}
33
- "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api"
34
- "deps/couchbase-cxx-client/include"
35
- "deps/couchbase-cxx-client/third_party/asio/asio/include")
130
+ if(CMAKE_JS_VERSION VERSION_GREATER_EQUAL "7.0.0")
131
+ target_include_directories(${PROJECT_NAME}
132
+ PRIVATE ${NODEJS_INC_DIR}
133
+ "deps/couchbase-cxx-client/include"
134
+ "deps/couchbase-cxx-client/third_party/asio/asio/include")
135
+ else()
136
+ execute_process(COMMAND node -p "require('node-addon-api').include"
137
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
138
+ OUTPUT_VARIABLE NODE_ADDON_API_DIR
139
+ )
140
+ string(REPLACE "\n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
141
+ string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
142
+
143
+ target_include_directories(${PROJECT_NAME}
144
+ PRIVATE ${NODEJS_INC_DIR}
145
+ ${NODE_ADDON_API_DIR}
146
+ "deps/couchbase-cxx-client/include"
147
+ "deps/couchbase-cxx-client/third_party/asio/asio/include")
148
+ endif()
36
149
  set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
37
150
 
38
151
  target_link_libraries(${PROJECT_NAME}
39
- ${CMAKE_JS_LIB}
152
+ ${NODEJS_LIB}
40
153
  couchbase_cxx_client
41
154
  )
42
155
 
43
- # Workaround a bug in cmake-js with removal of used references:
44
- # https://github.com/cmake-js/cmake-js/issues/205
45
- if(MSVC)
156
+ if(MSVC)
157
+ # Workaround a bug in cmake-js with removal of used references:
158
+ # https://github.com/cmake-js/cmake-js/issues/205
46
159
  target_link_options(${PROJECT_NAME} PUBLIC /OPT:NOREF)
160
+
161
+ # since we only care about the *.PDB for a command line build, this _should_ be okay.
162
+ if(CMAKE_BUILD_TYPE STREQUAL "Release")
163
+ target_compile_options(${PROJECT_NAME} PUBLIC /Zi)
164
+
165
+ # Do we want /OPT:ICF?
166
+ set_target_properties(${PROJECT_NAME} PROPERTIES
167
+ LINK_FLAGS "/INCREMENTAL:NO /DEBUG"
168
+ COMPILE_PDB_NAME ${PROJECT_NAME}
169
+ COMPILE_PDB_OUTPUT_DIR ${CMAKE_BINARY_DIR}
170
+ )
171
+ endif()
47
172
  endif()
package/dist/binding.js CHANGED
@@ -9,7 +9,7 @@ eslint
9
9
  jsdoc/require-jsdoc: off,
10
10
  @typescript-eslint/no-empty-interface: off
11
11
  */
12
- const bindings_1 = __importDefault(require("bindings"));
12
+ const path_1 = __importDefault(require("path"));
13
13
  exports.zeroCas = 0;
14
14
  //#region Autogenerated Bindings
15
15
  var CppManagementAnalyticsCouchbaseLinkEncryptionLevel;
@@ -157,5 +157,6 @@ var CppTxnExternalException;
157
157
  (function (CppTxnExternalException) {
158
158
  })(CppTxnExternalException = exports.CppTxnExternalException || (exports.CppTxnExternalException = {}));
159
159
  // Load it with require
160
- const binding = (0, bindings_1.default)('couchbase_impl');
160
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
161
+ const binding = require('../scripts/prebuilds').loadPrebuild(path_1.default.resolve(__dirname, '..'));
161
162
  exports.default = binding;
package/package.json CHANGED
@@ -1 +1,96 @@
1
- {"bugs":{"url":"http://www.couchbase.com/issues/browse/JSCBC"},"description":"The official Couchbase Node.js Client Library.","engines":{"node":">=12.0.0"},"homepage":"http://www.couchbase.com/communities/nodejs","keywords":["couchbase","libcouchbase","memcached","nosql","json","document"],"main":"dist/couchbase.js","types":"dist/couchbase.d.ts","license":"Apache-2.0","name":"couchbase","dependencies":{"bindings":"^1.5.0","cmake-js":"^6.3.2","node-addon-api":"^5.0.0","prebuild-install":"^7.1.1"},"devDependencies":{"@trivago/prettier-plugin-sort-imports":"^4.1.0","@tsconfig/node12":"^1.0.11","@types/bindings":"^1.5.1","@types/debug":"^4.1.7","@types/node":"^20.1.0","@typescript-eslint/eslint-plugin":"^5.32.0","@typescript-eslint/parser":"^5.32.0","chai":"^4.3.6","eslint":"^8.21.0","eslint-config-prettier":"^8.5.0","eslint-plugin-jsdoc":"^41.1.0","eslint-plugin-mocha":"^10.1.0","eslint-plugin-node":"^11.1.0","expose-gc":"^1.0.0","mocha":"^10.0.0","npm-check-updates":"^16.0.5","nyc":"^15.1.0","prebuild":"^11.0.4","prettier":"^2.7.1","segfault-handler":"^1.3.0","semver":"^7.3.7","ts-mocha":"^10.0.0","ts-node":"^10.9.1","typedoc":"^0.24.1","typescript":"^4.7.4","uuid":"^9.0.0"},"repository":{"type":"git","url":"http://github.com/couchbase/couchnode.git"},"version":"4.2.4","config":{"native":false},"scripts":{"install":"prebuild-install -r napi || cmake-js compile","build":"cmake-js build && tsc","rebuild":"cmake-js rebuild && tsc","prebuild":"prebuild --backend cmake-js --verbose --strip","prepare":"tsc","build-docs":"typedoc","test":"ts-mocha test/*.test.*","test-fast":"ts-mocha test/*.test.* -ig '(slow)'","cover":"nyc ts-mocha test/*.test.*","cover-fast":"nyc ts-mocha test/*.test.* -ig '(slow)'","lint":"eslint ./lib/ ./test/","check-deps":"ncu"},"binary":{"napi_versions":[6]}}
1
+ {
2
+ "bugs": {
3
+ "url": "http://www.couchbase.com/issues/browse/JSCBC"
4
+ },
5
+ "description": "The official Couchbase Node.js Client Library.",
6
+ "engines": {
7
+ "node": ">=12.0.0"
8
+ },
9
+ "homepage": "http://www.couchbase.com/communities/nodejs",
10
+ "keywords": [
11
+ "couchbase",
12
+ "libcouchbase",
13
+ "memcached",
14
+ "nosql",
15
+ "json",
16
+ "document"
17
+ ],
18
+ "main": "dist/couchbase.js",
19
+ "types": "dist/couchbase.d.ts",
20
+ "license": "Apache-2.0",
21
+ "name": "couchbase",
22
+ "dependencies": {
23
+ "cmake-js": "^7.2.0",
24
+ "node-addon-api": "^5.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@trivago/prettier-plugin-sort-imports": "^4.1.0",
28
+ "@types/bindings": "^1.5.1",
29
+ "@types/debug": "^4.1.7",
30
+ "@types/node": "^20.1.0",
31
+ "@tsconfig/node12": "^1.0.11",
32
+ "@typescript-eslint/eslint-plugin": "^5.32.0",
33
+ "@typescript-eslint/parser": "^5.32.0",
34
+ "chai": "^4.3.6",
35
+ "eslint": "^8.21.0",
36
+ "eslint-config-prettier": "^8.5.0",
37
+ "eslint-plugin-jsdoc": "^41.1.0",
38
+ "eslint-plugin-mocha": "^10.1.0",
39
+ "eslint-plugin-node": "^11.1.0",
40
+ "expose-gc": "^1.0.0",
41
+ "mocha": "^10.0.0",
42
+ "npm-check-updates": "^16.0.5",
43
+ "nyc": "^15.1.0",
44
+ "prebuild": "^11.0.4",
45
+ "prettier": "^2.7.1",
46
+ "segfault-handler": "^1.3.0",
47
+ "semver": "^7.3.7",
48
+ "ts-mocha": "^10.0.0",
49
+ "ts-node": "^10.9.1",
50
+ "typedoc": "^0.24.1",
51
+ "typescript": "^4.7.4",
52
+ "uuid": "^9.0.0"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "http://github.com/couchbase/couchnode.git"
57
+ },
58
+ "version": "4.2.5-dev.2",
59
+ "config": {
60
+ "native": false
61
+ },
62
+ "scripts": {
63
+ "install": "node ./scripts/install.js",
64
+ "build": "cmake-js build && tsc",
65
+ "rebuild": "cmake-js rebuild && tsc",
66
+ "prebuild": "prebuild --backend cmake-js --verbose --strip",
67
+ "prepare": "tsc",
68
+ "help-prune": "node ./scripts/prune.js",
69
+ "build-docs": "typedoc",
70
+ "test": "ts-mocha test/*.test.*",
71
+ "test-fast": "ts-mocha test/*.test.* -ig '(slow)'",
72
+ "cover": "nyc ts-mocha test/*.test.*",
73
+ "cover-fast": "nyc ts-mocha test/*.test.* -ig '(slow)'",
74
+ "lint": "eslint ./lib/ ./test/",
75
+ "check-deps": "ncu"
76
+ },
77
+ "binary": {
78
+ "napi_versions": [
79
+ 6
80
+ ]
81
+ },
82
+ "optionalDependencies": {
83
+ "@couchbase/couchbase-darwin-arm64-openssl1": "4.2.5-dev.2",
84
+ "@couchbase/couchbase-darwin-arm64-openssl3": "4.2.5-dev.2",
85
+ "@couchbase/couchbase-darwin-x64-openssl1": "4.2.5-dev.2",
86
+ "@couchbase/couchbase-darwin-x64-openssl3": "4.2.5-dev.2",
87
+ "@couchbase/couchbase-linux-arm64-openssl1": "4.2.5-dev.2",
88
+ "@couchbase/couchbase-linux-arm64-openssl3": "4.2.5-dev.2",
89
+ "@couchbase/couchbase-linux-x64-openssl1": "4.2.5-dev.2",
90
+ "@couchbase/couchbase-linux-x64-openssl3": "4.2.5-dev.2",
91
+ "@couchbase/couchbase-linuxmusl-x64-openssl1": "4.2.5-dev.2",
92
+ "@couchbase/couchbase-linuxmusl-x64-openssl3": "4.2.5-dev.2",
93
+ "@couchbase/couchbase-win32-x64-openssl1": "4.2.5-dev.2",
94
+ "@couchbase/couchbase-win32-x64-openssl3": "4.2.5-dev.2"
95
+ }
96
+ }
@@ -0,0 +1,108 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const { getSupportedPlatformPackages } = require('./prebuilds')
4
+
5
+ try {
6
+ // we run this script w/in a Jenkins dir("couchnode"){} block
7
+ const couchbasePkgData = JSON.parse(fs.readFileSync('package.json'))
8
+ const packageName = couchbasePkgData.name
9
+ const packageVersion = couchbasePkgData.version
10
+ let platformPackages = (couchbasePkgData.optionalDependencies = {})
11
+ const prebuildsPath = path.join(process.cwd(), 'prebuilds')
12
+ const prebuilds = fs.readdirSync(prebuildsPath)
13
+ const supportedPlatPkgs = getSupportedPlatformPackages(couchbasePkgData.name)
14
+ for (const prebuild of prebuilds) {
15
+ if (fs.lstatSync(path.join(prebuildsPath, prebuild)).isDirectory()) continue
16
+ // prebuild format:
17
+ // couchbase-v<pkg-version>-<runtime>-v<runtime-version>-<platform>-<arch>-<SSL type>.node.tar.gz
18
+ const tokens = prebuild.split('-')
19
+ if (tokens.length < 7) continue
20
+ if (tokens[tokens.length - 1].startsWith('debug')) {
21
+ fs.renameSync(`prebuilds/${prebuild}`, `prebuilds_debug/${prebuild}`)
22
+ continue
23
+ }
24
+ const nodeVersion = parseInt(
25
+ tokens[tokens.length - 1].replace('.node', '').replace('node', '')
26
+ )
27
+ const arch = tokens[tokens.length - 2]
28
+ const platform = tokens[tokens.length - 3]
29
+ const runtime = tokens[tokens.length - 5]
30
+ const sslType =
31
+ runtime === 'napi'
32
+ ? nodeVersion >= 18
33
+ ? 'openssl3'
34
+ : 'openssl1'
35
+ : 'boringssl'
36
+ const platPkg = `${tokens[0]}-${platform}-${arch}-${sslType}`
37
+ let description = `Couchbase Node.js SDK platform specific binary for ${runtime} runtime on ${platform} OS with ${arch} architecture`
38
+ if (runtime === 'napi') {
39
+ description += ` and OpenSSL ${nodeVersion >= 18 ? '3.x' : '1.x'}.`
40
+ } else {
41
+ description += ' and BoringSSL.'
42
+ }
43
+ console.log(`platformPackage=${platPkg}`)
44
+ if (supportedPlatPkgs.includes(platPkg)) {
45
+ console.log(`Building requirements for platform package: ${platPkg}`)
46
+ if (!fs.existsSync(`prebuilds/${platPkg}`)) {
47
+ fs.mkdirSync(`prebuilds/${platPkg}`)
48
+ }
49
+ tokens[tokens.length - 1] = `${sslType}.node`
50
+ const newPrebuildName = tokens.join('-')
51
+ const oldPath = path.join('prebuilds', prebuild)
52
+ const newPath = path.join('prebuilds', platPkg)
53
+ fs.renameSync(oldPath, path.join(newPath, newPrebuildName))
54
+ const platformPackage = `@${packageName}/${platPkg}`
55
+ // build the platform package files: package.json, README and index.js
56
+ const engines = { node: `>=16.0.0` }
57
+ if (runtime === 'napi') {
58
+ engines.node = nodeVersion >= 18 ? '>=18.0.0' : '<18'
59
+ }
60
+ fs.writeFileSync(
61
+ path.join(newPath, 'package.json'),
62
+ JSON.stringify(
63
+ {
64
+ name: platformPackage,
65
+ version: packageVersion,
66
+ engines: engines,
67
+ os: [platform.includes('linux') ? 'linux' : platform],
68
+ cpu: [arch],
69
+ bugs: couchbasePkgData.bugs,
70
+ homepage: couchbasePkgData.homepage,
71
+ license: couchbasePkgData.license,
72
+ repository: couchbasePkgData.repository,
73
+ description: description,
74
+ },
75
+ null,
76
+ 2
77
+ )
78
+ )
79
+ fs.writeFileSync(path.join(newPath, 'index.js'), '')
80
+ fs.writeFileSync(path.join(newPath, 'README.md'), description)
81
+ platformPackages[platformPackage] = packageVersion
82
+ }
83
+ }
84
+
85
+ if (
86
+ !process.env.ALLOW_MISMATCH &&
87
+ Object.keys(platformPackages).length != supportedPlatPkgs.length
88
+ ) {
89
+ const builtPlatformPkgs = Object.keys(platformPackages).map((pkg) => {
90
+ const tokens = pkg.split('/')
91
+ return tokens[1]
92
+ })
93
+ const missingPkgs = supportedPlatPkgs.filter(
94
+ (pkg) => !builtPlatformPkgs.includes(pkg)
95
+ )
96
+ const extraPkgs = builtPlatformPkgs.filter(
97
+ (pkg) => !supportedPlatPkgs.includes(pkg)
98
+ )
99
+ let msg = 'Mismatch in built platform packages.\n'
100
+ msg += 'Missing: ' + JSON.stringify(missingPkgs) + '.\n'
101
+ msg += 'Extra: ' + JSON.stringify(extraPkgs) + '.'
102
+ throw new Error(msg)
103
+ }
104
+ fs.writeFileSync('package.json', JSON.stringify(couchbasePkgData, null, 2))
105
+ } catch (err) {
106
+ console.log('An error occurred:', err)
107
+ process.exitCode = 1
108
+ }
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path')
4
+ var proc = require('child_process')
5
+ const prebuilds = require('./prebuilds')
6
+
7
+ if (hasLocalPrebuild()) {
8
+ const destination = path.join(
9
+ path.resolve(__dirname, '..'),
10
+ 'build',
11
+ 'Release'
12
+ )
13
+ const source = getLocalPrebuild()
14
+ // on either success or failure of resolving local prebuild we still confirm we have a prebuild
15
+ prebuilds.resolveLocalPrebuild(source, destination).then(installPrebuild())
16
+ } else {
17
+ installPrebuild()
18
+ }
19
+
20
+ function getLocalPrebuild() {
21
+ const localPrebuildsName = `npm_config_couchbase_local_prebuilds`
22
+ return process.env[localPrebuildsName]
23
+ }
24
+
25
+ function hasLocalPrebuild() {
26
+ return typeof getLocalPrebuild() === 'string'
27
+ }
28
+
29
+ function installPrebuild() {
30
+ try {
31
+ prebuilds.resolvePrebuild(path.resolve(__dirname, '..'), false)
32
+ process.exit(0)
33
+ } catch (err) {
34
+ const cmakejs = path.join(
35
+ require.resolve('cmake-js/package.json'),
36
+ '..',
37
+ require('cmake-js/package.json').bin['cmake-js']
38
+ )
39
+ // @TODO: is spawning sync a problem? Seemed to be easiest way to get Ctrl-C to kill the whole build process
40
+ const cmakejsProc = proc.spawnSync(process.execPath, [cmakejs, 'compile'], {
41
+ stdio: 'inherit',
42
+ })
43
+ process.exit(cmakejsProc.status)
44
+ }
45
+ }
@@ -0,0 +1,249 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const zlib = require('zlib')
4
+ const stream = require('stream')
5
+ const { promisify } = require('util')
6
+ const pipe = promisify(stream.pipeline)
7
+
8
+ // Workaround to fix webpack's build warnings: 'the request of a dependency is an expression'
9
+ const runtimeRequire =
10
+ typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
11
+
12
+ const openSSLVersions = ['openssl1', 'openssl3']
13
+ const supportedPlatforms = ['darwin', 'linux', 'linuxmusl', 'win32']
14
+ const supportedArches = ['x64', 'arm64']
15
+
16
+ const runtime = isElectron() ? 'electron' : 'node'
17
+ const nodeVersion = getNodeVersion()
18
+ const nodeVersionMajor = getNodeMajorVersion(nodeVersion)
19
+ const arch = process.arch
20
+ const platform = process.platform
21
+ const libc = getLinuxType(platform)
22
+ const sslType = getSSLType(runtime, nodeVersion)
23
+
24
+ function getLocalPrebuild(dir) {
25
+ const localPrebuildDir = path.join(dir, 'build/Release')
26
+ const files = readdirSync(localPrebuildDir).filter(matchBuild)
27
+ return files[0] && path.join(localPrebuildDir, files[0])
28
+ }
29
+
30
+ function getLinuxType(platform) {
31
+ if (platform !== 'linux') {
32
+ return ''
33
+ }
34
+ return `linux${isAlpine(platform) ? 'musl' : ''}`
35
+ }
36
+
37
+ function getNodeMajorVersion(version) {
38
+ const tokens = version.split('.')
39
+ return parseInt(tokens[0])
40
+ }
41
+
42
+ function getNodeVersion() {
43
+ return process.version.replace('v', '')
44
+ }
45
+
46
+ function getPrebuildsInfo(dir) {
47
+ dir = path.resolve(dir || '.')
48
+ const info = {
49
+ packageDir: path.join(dir, 'package.json'),
50
+ platformPackageDir: undefined,
51
+ }
52
+
53
+ const packageName = JSON.parse(fs.readFileSync(info.packageDir)).name
54
+ if (packageName !== undefined) {
55
+ const allowedPlatformPkg = `${packageName}-${
56
+ platform === 'linux' ? libc : platform
57
+ }-${arch}-${sslType}`
58
+ const fullPlatformPkgName = `@${packageName}/${allowedPlatformPkg}`
59
+ const packageRequire = require('module').createRequire(
60
+ path.join(dir, 'package.json')
61
+ )
62
+ info.packageDir = path.dirname(path.join(dir, 'package.json'))
63
+ info.platformPackageDir = path.dirname(
64
+ packageRequire.resolve(fullPlatformPkgName)
65
+ )
66
+ }
67
+ return info
68
+ }
69
+
70
+ function getSSLType(runtime, version) {
71
+ if (runtime === 'electron') {
72
+ return 'boringssl'
73
+ }
74
+
75
+ const major = getNodeMajorVersion(version)
76
+ if (major >= 18) {
77
+ return 'openssl3'
78
+ }
79
+ return 'openssl1'
80
+ }
81
+
82
+ function getSupportedPlatformPackages(packageName) {
83
+ packageName = packageName || 'couchbase'
84
+ if (packageName !== 'couchbase') {
85
+ throw new Error(
86
+ 'Cannot build supported platform packages for package other than couchbase.'
87
+ )
88
+ }
89
+
90
+ const packageNames = []
91
+ // format: <platform>-<arch>-<runtime>-<SSL Type>
92
+ supportedPlatforms.forEach((plat) => {
93
+ supportedArches.forEach((arch) => {
94
+ if (plat === 'win32' && arch === 'arm64') return
95
+ openSSLVersions.forEach((ssl) => {
96
+ packageNames.push(`${packageName}-${plat}-${arch}-${ssl}`)
97
+ })
98
+ packageNames.push(`${packageName}-${plat}-${arch}-boringssl`)
99
+ })
100
+ })
101
+ return packageNames
102
+ }
103
+
104
+ function isAlpine(platform) {
105
+ return platform === 'linux' && fs.existsSync('/etc/alpine-release')
106
+ }
107
+
108
+ function isElectron() {
109
+ if (process.versions && process.versions.electron) return true
110
+ if (process.env.ELECTRON_RUN_AS_NODE) return true
111
+ return (
112
+ typeof window !== 'undefined' &&
113
+ window.process &&
114
+ window.process.type === 'renderer'
115
+ )
116
+ }
117
+
118
+ function loadPrebuild(dir) {
119
+ return runtimeRequire(resolvePrebuild(dir))
120
+ }
121
+
122
+ function matchBuild(name) {
123
+ return /\.node$/.test(name)
124
+ }
125
+
126
+ function matchingPlatformPrebuild(filename) {
127
+ if (['index.js', 'package.json', 'README.md'].includes(filename)) {
128
+ return false
129
+ }
130
+ const tokens = filename.split('-')
131
+ // filename format:
132
+ // couchbase-v<pkg-version>-<runtime>-v<runtime-version>-<platform>-<arch>-<ssltype>.node
133
+ if (tokens.length < 7) return false
134
+ const prebuildSSL = tokens[tokens.length - 1].replace('.node', '')
135
+ if (runtime === 'electron') {
136
+ if (prebuildSSL !== 'boringssl') return false
137
+ } else {
138
+ if (nodeVersionMajor >= 18 && prebuildSSL !== 'openssl3') return false
139
+ if (nodeVersionMajor < 18 && prebuildSSL !== 'openssl1') return false
140
+ }
141
+ if (tokens[tokens.length - 2] !== arch) return false
142
+ const platCompare = platform === 'linux' ? libc : platform
143
+ if (tokens[tokens.length - 3] !== platCompare) return false
144
+ if (!matchBuild(filename)) return false
145
+ // yay -- found a match!
146
+ return true
147
+ }
148
+
149
+ function matchPrebuild(name) {
150
+ return /\.tar\.gz$/.test(name) || matchBuild(name)
151
+ }
152
+
153
+ function readdirSync(dir) {
154
+ try {
155
+ return fs.readdirSync(dir)
156
+ } catch (err) {
157
+ return []
158
+ }
159
+ }
160
+
161
+ async function resolveLocalPrebuild(src, dest) {
162
+ if (fs.existsSync(src)) {
163
+ const prebuilds = readdirSync(src).filter(matchPrebuild)
164
+ if (prebuilds && prebuilds.length >= 1) {
165
+ if (!fs.existsSync(dest)) {
166
+ fs.mkdirSync(dest, { recursive: true })
167
+ }
168
+ const prebuild = prebuilds[0]
169
+ let prebuildDestName = prebuild
170
+ if (prebuild.endsWith('.tar.gz')) {
171
+ const gzip = zlib.createGunzip()
172
+ const source = fs.createReadStream(src)
173
+ prebuildDestName = `${prebuild.substring(0, prebuild.length - 7)}.node`
174
+ const destination = fs.createWriteStream(
175
+ path.join(src, prebuildDestName)
176
+ )
177
+ await pipe(source, gzip, destination)
178
+ }
179
+ try {
180
+ fs.copyFileSync(
181
+ path.join(src, prebuild),
182
+ path.join(dest, prebuildDestName)
183
+ )
184
+ } catch (_) {}
185
+ }
186
+ }
187
+ }
188
+
189
+ function resolvePrebuild(dir, runtimeResolve = true) {
190
+ dir = path.resolve(dir || '.')
191
+ try {
192
+ const localPrebuild = getLocalPrebuild(dir)
193
+ if (localPrebuild) {
194
+ return localPrebuild
195
+ }
196
+
197
+ const packageName = runtimeResolve
198
+ ? runtimeRequire(path.join(dir, 'package.json')).name
199
+ : JSON.parse(fs.readFileSync(path.join(dir, 'package.json'))).name
200
+ if (packageName !== undefined) {
201
+ const supportedPackages = getSupportedPlatformPackages(packageName)
202
+ const platformPkg = `${packageName}-${
203
+ platform === 'linux' ? libc : platform
204
+ }-${arch}-${sslType}`
205
+ if (supportedPackages.includes(platformPkg)) {
206
+ const fullPlatformPkgName = `@${packageName}/${platformPkg}`
207
+ const packageRequire = require('module').createRequire(
208
+ path.join(dir, 'package.json')
209
+ )
210
+ const platformPackagesDir = path.dirname(
211
+ packageRequire.resolve(fullPlatformPkgName)
212
+ )
213
+ if (platformPackagesDir !== undefined) {
214
+ const platformPrebuild = readdirSync(platformPackagesDir).filter(
215
+ matchingPlatformPrebuild
216
+ )
217
+ if (platformPrebuild && platformPrebuild.length == 1) {
218
+ return path.join(platformPackagesDir, platformPrebuild[0])
219
+ }
220
+ }
221
+ }
222
+ }
223
+ } catch (_) {}
224
+
225
+ let target = [
226
+ `platform=${platform}`,
227
+ `arch=${arch}`,
228
+ `runtime=${runtime}`,
229
+ `nodeVersion=${nodeVersion}`,
230
+ `sslType=${sslType}`,
231
+ ]
232
+ if (libc) {
233
+ target.push(`libc=${libc}`)
234
+ }
235
+ if (typeof __webpack_require__ === 'function') {
236
+ target.push('webpack=true')
237
+ }
238
+ throw new Error(
239
+ `Could not find native build for ${target.join(', ')} loaded from ${dir}.`
240
+ )
241
+ }
242
+
243
+ module.exports = {
244
+ getPrebuildsInfo,
245
+ getSupportedPlatformPackages,
246
+ loadPrebuild,
247
+ resolveLocalPrebuild,
248
+ resolvePrebuild,
249
+ }
@@ -0,0 +1,124 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const prebuilds = require('./prebuilds')
4
+
5
+ function getMismatchedPlatformPackagesInfo(
6
+ platformPackagesDir,
7
+ expectedPlatformPackage
8
+ ) {
9
+ let message = `Checking for platform packages in ${platformPackagesDir} `
10
+ message += `that do not match the expected platform package (${expectedPlatformPackage}).`
11
+ console.log(message)
12
+ let mismatches = []
13
+ try {
14
+ const files = fs.readdirSync(platformPackagesDir)
15
+ files.forEach((file) => {
16
+ if (file === expectedPlatformPackage) {
17
+ return
18
+ }
19
+ const stats = fs.statSync(path.join(platformPackagesDir, file))
20
+ if (!stats.isDirectory()) {
21
+ return
22
+ }
23
+ const filePath = path.join(platformPackagesDir, file)
24
+ const size = getDirectorySize(filePath)
25
+ console.log(`Found mismatch: Path=${filePath}`)
26
+ const platformPackage = path.basename(filePath)
27
+ mismatches.push({
28
+ name: platformPackage,
29
+ dir: filePath,
30
+ size: size,
31
+ })
32
+ })
33
+ } catch (err) {
34
+ console.error(`Error trying to delete mismatched platform packages.`, err)
35
+ }
36
+ return mismatches
37
+ }
38
+
39
+ function getDirectorySize(dir) {
40
+ let size = 0
41
+ const dirContents = fs.readdirSync(dir)
42
+ dirContents.forEach((content) => {
43
+ const contentPath = path.join(dir, content)
44
+ const stats = fs.statSync(contentPath)
45
+ if (stats.isFile()) {
46
+ size += stats.size
47
+ } else if (stats.isDirectory()) {
48
+ size += getDirectorySize(contentPath)
49
+ }
50
+ })
51
+
52
+ return size
53
+ }
54
+
55
+ function getPrebuildsInfo() {
56
+ try {
57
+ const prebuildsInfo = prebuilds.getPrebuildsInfo()
58
+ return prebuildsInfo
59
+ } catch (err) {
60
+ console.error('Error trying to obtain couchbase prebuilds info.', err)
61
+ return undefined
62
+ }
63
+ }
64
+
65
+ function pruneCouchbaseHelp() {
66
+ const prebuildsInfo = getPrebuildsInfo()
67
+ const platformPackagesDir = path.dirname(prebuildsInfo.platformPackageDir)
68
+ const expectedPlatformPackage = path.basename(
69
+ prebuildsInfo.platformPackageDir
70
+ )
71
+
72
+ const mismatchedPlatPkgs = getMismatchedPlatformPackagesInfo(
73
+ platformPackagesDir,
74
+ expectedPlatformPackage
75
+ )
76
+ const cbDeps = {
77
+ dir: path.join(prebuildsInfo.packageDir, 'deps'),
78
+ size: undefined,
79
+ }
80
+ const cbSrc = {
81
+ dir: path.join(prebuildsInfo.packageDir, 'src'),
82
+ size: undefined,
83
+ }
84
+ try {
85
+ cbDeps.size = getDirectorySize(cbDeps.dir)
86
+ } catch (_) {
87
+ console.log('Couchbase deps/ not found.')
88
+ }
89
+ try {
90
+ cbSrc.size = getDirectorySize(cbSrc.dir)
91
+ } catch (_) {
92
+ console.log('Couchbase src/ not found.')
93
+ }
94
+
95
+ console.log('\nRecommendations for pruning:\n')
96
+ if (mismatchedPlatPkgs.length > 0) {
97
+ for (const pkg of mismatchedPlatPkgs) {
98
+ const sizeMb = pkg.size / 1024 / 1024
99
+ console.log(
100
+ `Removing mismatched platform=${pkg.name} (path=${
101
+ pkg.dir
102
+ }) saves ~${sizeMb.toFixed(2)} MB on disk.`
103
+ )
104
+ }
105
+ }
106
+ if (cbDeps.size) {
107
+ const sizeMb = cbDeps.size / 1024 / 1024
108
+ console.log(
109
+ `Removing Couchbase deps/ (path=${cbDeps.dir}) saves ~${sizeMb.toFixed(
110
+ 2
111
+ )} MB on disk.`
112
+ )
113
+ }
114
+ if (cbSrc.size) {
115
+ const sizeMb = cbSrc.size / 1024 / 1024
116
+ console.log(
117
+ `Removing Couchbase src/ (path=${cbSrc.dir}) saves ~${sizeMb.toFixed(
118
+ 2
119
+ )} MB on disk.`
120
+ )
121
+ }
122
+ }
123
+
124
+ pruneCouchbaseHelp()