From 33d334f94d1f004570084471e0aeef722000c1e3 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Tue, 25 Nov 2025 16:21:47 +0200 Subject: [PATCH 01/13] Support private S3 buckets --- README.md | 28 +++++++++++++++++ lib/install.js | 66 +++++++++++++++++++++++++++++++++++++++++ lib/node-pre-gyp.js | 3 +- lib/publish.js | 5 ++-- lib/util/versioning.js | 3 +- test/versioning.test.js | 50 +++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5aef79a6..3dedd9cc 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ Options include: - `--target=0.4.0`: Pass the target node or node-webkit version to compile against - `--target_arch=ia32`: Pass the target arch and override the host `arch`. Any value that is [supported by Node.js](https://nodejs.org/api/os.html#osarch) is valid. - `--target_platform=win32`: Pass the target platform and override the host `platform`. Valid values are `linux`, `darwin`, `win32`, `sunos`, `freebsd`, `openbsd`, and `aix`. + - `--acl=`: Set the S3 ACL when publishing binaries (e.g., `public-read`, `private`). Overrides the `binary.acl` setting in package.json. Both `--build-from-source` and `--fallback-to-build` can be passed alone or they can provide values. You can pass `--fallback-to-build=false` to override the option as declared in package.json. In addition to being able to pass `--build-from-source` you can also pass `--build-from-source=myapp` where `myapp` is the name of your module. @@ -185,6 +186,33 @@ Your S3 server region. Set `s3ForcePathStyle` to true if the endpoint url should not be prefixed with the bucket name. If false (default), the server endpoint would be constructed as `bucket_name.your_server.com`. +###### acl + +The S3 Access Control List (ACL) to apply when publishing binaries. Defaults to `'public-read'` for backward compatibility. Common values include: + +- `public-read` - (default) Binary is publicly accessible by anyone +- `private` - Binary requires AWS credentials to download +- `authenticated-read` - Any authenticated AWS user can download +- `bucket-owner-read` - Bucket owner gets READ access +- `bucket-owner-full-control` - Bucket owner gets FULL_CONTROL access + +**For private binaries:** +- Users installing your package will need AWS credentials configured (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables) +- The `aws-sdk` package must be available at install time +- If authentication fails, node-pre-gyp will fall back to building from source (if `--fallback-to-build` is specified) + +You can also specify the ACL via command-line flag: `node-pre-gyp publish --acl=private` + +Example for private binaries: +```json +"binary": { + "module_name": "your_module", + "module_path": "./lib/binding/", + "host": "https://your-bucket.s3.us-east-1.amazonaws.com", + "acl": "private" +} +``` + ##### The `binary` object has optional properties ###### remote_path diff --git a/lib/install.js b/lib/install.js index 119af6db..f032a0b6 100644 --- a/lib/install.js +++ b/lib/install.js @@ -10,6 +10,8 @@ const log = require('./util/log.js'); const existsAsync = fs.exists || path.exists; const versioning = require('./util/versioning.js'); const napi = require('./util/napi.js'); +const s3_setup = require('./util/s3_setup.js'); +const url = require('url'); // for fetching binaries const fetch = require('node-fetch'); const tar = require('tar'); @@ -23,6 +25,65 @@ try { // do nothing } +function place_binary_authenticated(opts, targetDir, callback) { + log.info('install', 'Attempting authenticated S3 download'); + + // Check if AWS credentials are available + if (!process.env.AWS_ACCESS_KEY_ID && !process.env.AWS_SECRET_ACCESS_KEY) { + const err = new Error('Binary is private but AWS credentials not found. Please configure AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or use --fallback-to-build to compile from source.'); + err.statusCode = 403; + return callback(err); + } + + try { + const config = s3_setup.detect(opts); + const s3 = s3_setup.get_s3(config); + const key_name = url.resolve(config.prefix, opts.package_name); + + log.info('install', 'Downloading from S3:', config.bucket, key_name); + + const s3_opts = { + Bucket: config.bucket, + Key: key_name + }; + + s3.getObject(s3_opts, (err, data) => { + if (err) { + log.error('install', 'Authenticated S3 download failed:', err.message); + return callback(err); + } + + log.info('install', 'Authenticated download successful, extracting...'); + + const { Readable } = require('stream'); + const dataStream = Readable.from(data.Body); + + let extractions = 0; + const countExtractions = (entry) => { + extractions += 1; + log.info('install', `unpacking ${entry.path}`); + }; + + dataStream.pipe(extract(targetDir, countExtractions)) + .on('error', (e) => { + callback(e); + }) + .on('close', () => { + log.info('install', `extracted file count: ${extractions}`); + callback(); + }); + }); + } catch (e) { + if (e.code === 'MODULE_NOT_FOUND' && e.message.includes('aws-sdk')) { + const err = new Error('Binary is private and requires aws-sdk for authenticated download. Please run: npm install aws-sdk'); + err.statusCode = 403; + return callback(err); + } + log.error('install', 'Error setting up authenticated download:', e.message); + callback(e); + } +} + function place_binary(uri, targetDir, opts, callback) { log.log('GET', uri); @@ -63,6 +124,11 @@ function place_binary(uri, targetDir, opts, callback) { fetch(sanitized, { agent }) .then((res) => { if (!res.ok) { + // If we get 403 Forbidden, the binary might be private - try authenticated download + if (res.status === 403) { + log.info('install', 'Received 403 Forbidden - attempting authenticated download'); + return place_binary_authenticated(opts, targetDir, callback); + } throw new Error(`response status ${res.status} ${res.statusText} on ${sanitized}`); } const dataStream = res.body; diff --git a/lib/node-pre-gyp.js b/lib/node-pre-gyp.js index 26c0e512..bc80dd90 100644 --- a/lib/node-pre-gyp.js +++ b/lib/node-pre-gyp.js @@ -98,7 +98,8 @@ proto.configDefs = { debug: Boolean, // 'build' directory: String, // bin proxy: String, // 'install' - loglevel: String // everywhere + loglevel: String, // everywhere + acl: String // 'publish' - S3 ACL for published binaries }; /** diff --git a/lib/publish.js b/lib/publish.js index 3b2e08cd..97067ce4 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -43,12 +43,13 @@ function publish(gyp, argv, callback) { // the object does not already exist log.info('publish', 'Preparing to put object'); const s3_put_opts = { - ACL: 'public-read', + ACL: opts.acl, Body: fs.createReadStream(tarball), Key: key_name, Bucket: config.bucket }; - log.info('publish', 'Putting object', s3_put_opts.ACL, s3_put_opts.Bucket, s3_put_opts.Key); + log.info('publish', 'Putting object with ACL:', s3_put_opts.ACL); + log.info('publish', 'Bucket:', s3_put_opts.Bucket, 'Key:', s3_put_opts.Key); try { s3.putObject(s3_put_opts, (err2, resp) => { log.info('publish', 'returned from putting object'); diff --git a/lib/util/versioning.js b/lib/util/versioning.js index b65e84e7..b69b367e 100644 --- a/lib/util/versioning.js +++ b/lib/util/versioning.js @@ -307,7 +307,8 @@ module.exports.evaluate = function(package_json, options, napi_build_version) { toolset: options.toolset || '', // address https://github.com/mapbox/node-pre-gyp/issues/119 bucket: package_json.binary.bucket, region: package_json.binary.region, - s3ForcePathStyle: package_json.binary.s3ForcePathStyle || false + s3ForcePathStyle: package_json.binary.s3ForcePathStyle || false, + acl: options.acl || package_json.binary.acl || 'public-read' }; // support host mirror with npm config `--{module_name}_binary_host_mirror` // e.g.: https://github.com/node-inspector/v8-profiler/blob/master/package.json#L25 diff --git a/test/versioning.test.js b/test/versioning.test.js index 45541999..77e3b75f 100644 --- a/test/versioning.test.js +++ b/test/versioning.test.js @@ -100,6 +100,56 @@ test('should throw when custom node target is not found in abi_crosswalk file', } }); +test('should default ACL to public-read when not specified', (t) => { + const mock_package_json = { + 'name': 'test', + 'main': 'test.js', + 'version': '0.1.0', + 'binary': { + 'module_name': 'test', + 'module_path': './lib/binding/', + 'host': 'https://some-bucket.s3.us-east-1.amazonaws.com' + } + }; + const opts = versioning.evaluate(mock_package_json, {}); + t.equal(opts.acl, 'public-read', 'ACL should default to public-read'); + t.end(); +}); + +test('should use ACL from package.json binary.acl', (t) => { + const mock_package_json = { + 'name': 'test', + 'main': 'test.js', + 'version': '0.1.0', + 'binary': { + 'module_name': 'test', + 'module_path': './lib/binding/', + 'host': 'https://some-bucket.s3.us-east-1.amazonaws.com', + 'acl': 'private' + } + }; + const opts = versioning.evaluate(mock_package_json, {}); + t.equal(opts.acl, 'private', 'ACL should be read from package.json binary.acl'); + t.end(); +}); + +test('should allow CLI flag to override package.json ACL', (t) => { + const mock_package_json = { + 'name': 'test', + 'main': 'test.js', + 'version': '0.1.0', + 'binary': { + 'module_name': 'test', + 'module_path': './lib/binding/', + 'host': 'https://some-bucket.s3.us-east-1.amazonaws.com', + 'acl': 'private' + } + }; + const opts = versioning.evaluate(mock_package_json, { acl: 'authenticated-read' }); + t.equal(opts.acl, 'authenticated-read', 'CLI flag should override package.json ACL'); + t.end(); +}); + test('should throw when custom node target is not semver', (t) => { try { versioning.get_runtime_abi('node', '1.2.3.4'); From f11710cc79550cff8e15a9bdd286445df4a6ec0b Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Tue, 25 Nov 2025 16:23:43 +0200 Subject: [PATCH 02/13] fix vuln --- package-lock.json | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f29063b..407d0c78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1118,9 +1118,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -3772,9 +3772,9 @@ } }, "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -6435,9 +6435,9 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -6450,9 +6450,6 @@ "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } From 1211904a154bc005b159e1dafd63772f740d2151 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Tue, 25 Nov 2025 16:29:23 +0200 Subject: [PATCH 03/13] fix vuln --- package-lock.json | 6 +++--- package.json | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 407d0c78..5a064c77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5322,9 +5322,9 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 1b744cbd..2d054c47 100644 --- a/package.json +++ b/package.json @@ -61,5 +61,8 @@ "test": "tape test/*test.js", "test:s3": "tape test/s3.test.js", "bucket": "node scripts/set-bucket.js" + }, + "overrides": { + "js-yaml": "^3.14.2" } } From ed4453bacf5ee54d41dc1e3613d1ab6dc235188d Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Tue, 25 Nov 2025 17:25:41 +0200 Subject: [PATCH 04/13] dev version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5a064c77..46a3554a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/node-pre-gyp", - "version": "2.0.1", + "version": "2.0.2-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/node-pre-gyp", - "version": "2.0.1", + "version": "2.0.2-dev", "license": "BSD-3-Clause", "dependencies": { "consola": "^3.2.3", diff --git a/package.json b/package.json index 2d054c47..aa55596a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "2.0.1", + "version": "2.0.2-dev", "keywords": [ "native", "addon", From 666ce1057ccce756da0e22b25aad9a39c18cf3b0 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Tue, 25 Nov 2025 17:40:25 +0200 Subject: [PATCH 05/13] move aws-sdk to prod packages --- package-lock.json | 43 +++---------------------------------------- package.json | 4 ++-- 2 files changed, 5 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46a3554a..2805e917 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-dev", + "version": "2.0.2-dev.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-dev", + "version": "2.0.2-dev.1", "license": "BSD-3-Clause", "dependencies": { + "aws-sdk": "^2.1087.0", "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", @@ -23,7 +24,6 @@ "devDependencies": { "@mapbox/cloudfriend": "^9.0.0", "@mapbox/eslint-config-mapbox": "^5.0.1", - "aws-sdk": "^2.1087.0", "codecov": "^3.8.3", "eslint": "^8.57.0", "eslint-plugin-n": "^17.9.0", @@ -2636,7 +2636,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -2652,7 +2651,6 @@ "version": "2.1659.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1659.0.tgz", "integrity": "sha512-WOoy5DdWW4kpQuxjWiQdoSDR+dT/HeAUwjb6b+8taEMZzvUzp3fmdDwdryUTlLWGxrnb7ru2yu5pryjhPOzANg==", - "dev": true, "hasInstallScript": true, "dependencies": { "buffer": "4.9.2", @@ -2759,7 +2757,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -2849,7 +2846,6 @@ "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, "license": "MIT", "dependencies": { "base64-js": "^1.0.2", @@ -2877,7 +2873,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -3212,7 +3207,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -3434,7 +3428,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" @@ -3447,7 +3440,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3879,7 +3871,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.x" @@ -4096,7 +4087,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.1.3" @@ -4170,7 +4160,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4229,7 +4218,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4403,7 +4391,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" @@ -4467,7 +4454,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -4480,7 +4466,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4493,7 +4478,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4506,7 +4490,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -4549,7 +4532,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -4609,7 +4591,6 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/ignore": { @@ -4708,7 +4689,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, "license": "ISC" }, "node_modules/internal-slot": { @@ -4730,7 +4710,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.2", @@ -4794,7 +4773,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4874,7 +4852,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" @@ -5057,7 +5034,6 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" @@ -5133,7 +5109,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, "license": "MIT" }, "node_modules/isexe": { @@ -5309,7 +5284,6 @@ "version": "0.16.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">= 0.6.0" @@ -6187,7 +6161,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6252,7 +6225,6 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, "engines": { "node": ">=0.4.x" } @@ -6526,7 +6498,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", - "dev": true, "license": "ISC" }, "node_modules/semver": { @@ -6552,7 +6523,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -7357,7 +7327,6 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", - "dev": true, "license": "MIT", "dependencies": { "punycode": "1.3.2", @@ -7368,7 +7337,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true, "license": "MIT" }, "node_modules/urlgrey": { @@ -7385,7 +7353,6 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -7399,7 +7366,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "dev": true, "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -7483,7 +7449,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -7573,7 +7538,6 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", - "dev": true, "license": "MIT", "dependencies": { "sax": ">=0.6.0", @@ -7587,7 +7551,6 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4.0" diff --git a/package.json b/package.json index aa55596a..30ee1d33 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "2.0.2-dev", + "version": "2.0.2-dev.1", "keywords": [ "native", "addon", @@ -23,6 +23,7 @@ "node": ">=18" }, "dependencies": { + "aws-sdk": "^2.1087.0", "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", @@ -34,7 +35,6 @@ "devDependencies": { "@mapbox/cloudfriend": "^9.0.0", "@mapbox/eslint-config-mapbox": "^5.0.1", - "aws-sdk": "^2.1087.0", "codecov": "^3.8.3", "eslint": "^8.57.0", "eslint-plugin-n": "^17.9.0", From 7719aebfa8daaf8d39393cddfad77bc03906e69a Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 10:37:24 +0200 Subject: [PATCH 06/13] Add getObject function --- lib/mock/s3.js | 3 +++ lib/util/s3_setup.js | 3 +++ package-lock.json | 43 ++++++++++++++++++++++++++++++++++++++++--- package.json | 4 ++-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/mock/s3.js b/lib/mock/s3.js index e485e3bd..9633e5d3 100644 --- a/lib/mock/s3.js +++ b/lib/mock/s3.js @@ -36,6 +36,9 @@ function s3_mock() { }, putObject(params, callback) { return s3.putObject(params, wcb(callback)); + }, + getObject(params, callback) { + return s3.getObject(params, wcb(callback)); } }; } diff --git a/lib/util/s3_setup.js b/lib/util/s3_setup.js index 0095cd34..6fd3c924 100644 --- a/lib/util/s3_setup.js +++ b/lib/util/s3_setup.js @@ -84,6 +84,9 @@ module.exports.get_s3 = function(config) { }, putObject(params, callback) { return s3.putObject(params, callback); + }, + getObject(params, callback) { + return s3.getObject(params, callback); } }; }; diff --git a/package-lock.json b/package-lock.json index 2805e917..632d1849 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,14 @@ { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-dev.1", + "version": "2.0.2-dev.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-dev.1", + "version": "2.0.2-dev.2", "license": "BSD-3-Clause", "dependencies": { - "aws-sdk": "^2.1087.0", "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", @@ -24,6 +23,7 @@ "devDependencies": { "@mapbox/cloudfriend": "^9.0.0", "@mapbox/eslint-config-mapbox": "^5.0.1", + "aws-sdk": "^2.1087.0", "codecov": "^3.8.3", "eslint": "^8.57.0", "eslint-plugin-n": "^17.9.0", @@ -2636,6 +2636,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -2651,6 +2652,7 @@ "version": "2.1659.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1659.0.tgz", "integrity": "sha512-WOoy5DdWW4kpQuxjWiQdoSDR+dT/HeAUwjb6b+8taEMZzvUzp3fmdDwdryUTlLWGxrnb7ru2yu5pryjhPOzANg==", + "dev": true, "hasInstallScript": true, "dependencies": { "buffer": "4.9.2", @@ -2757,6 +2759,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, "funding": [ { "type": "github", @@ -2846,6 +2849,7 @@ "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, "license": "MIT", "dependencies": { "base64-js": "^1.0.2", @@ -2873,6 +2877,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -3207,6 +3212,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -3428,6 +3434,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" @@ -3440,6 +3447,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3871,6 +3879,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.4.x" @@ -4087,6 +4096,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.1.3" @@ -4160,6 +4170,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4218,6 +4229,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4391,6 +4403,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" @@ -4454,6 +4467,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -4466,6 +4480,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4478,6 +4493,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4490,6 +4506,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -4532,6 +4549,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -4591,6 +4609,7 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/ignore": { @@ -4689,6 +4708,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, "license": "ISC" }, "node_modules/internal-slot": { @@ -4710,6 +4730,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.2", @@ -4773,6 +4794,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4852,6 +4874,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" @@ -5034,6 +5057,7 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" @@ -5109,6 +5133,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, "license": "MIT" }, "node_modules/isexe": { @@ -5284,6 +5309,7 @@ "version": "0.16.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">= 0.6.0" @@ -6161,6 +6187,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6225,6 +6252,7 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, "engines": { "node": ">=0.4.x" } @@ -6498,6 +6526,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", + "dev": true, "license": "ISC" }, "node_modules/semver": { @@ -6523,6 +6552,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -7327,6 +7357,7 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "dev": true, "license": "MIT", "dependencies": { "punycode": "1.3.2", @@ -7337,6 +7368,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true, "license": "MIT" }, "node_modules/urlgrey": { @@ -7353,6 +7385,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -7366,6 +7399,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "dev": true, "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -7449,6 +7483,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -7538,6 +7573,7 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dev": true, "license": "MIT", "dependencies": { "sax": ">=0.6.0", @@ -7551,6 +7587,7 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, "license": "MIT", "engines": { "node": ">=4.0" diff --git a/package.json b/package.json index 30ee1d33..742a6feb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "2.0.2-dev.1", + "version": "2.0.2-dev.2", "keywords": [ "native", "addon", @@ -23,7 +23,6 @@ "node": ">=18" }, "dependencies": { - "aws-sdk": "^2.1087.0", "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", @@ -35,6 +34,7 @@ "devDependencies": { "@mapbox/cloudfriend": "^9.0.0", "@mapbox/eslint-config-mapbox": "^5.0.1", + "aws-sdk": "^2.1087.0", "codecov": "^3.8.3", "eslint": "^8.57.0", "eslint-plugin-n": "^17.9.0", From d53c1206213016e174f7b551ecb9a34d28bdea1d Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 11:13:40 +0200 Subject: [PATCH 07/13] v2.0.2 --- CHANGELOG.md | 3 +++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5ad5768..5b164790 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## master +## 2.0.2 +- Support private ACL for S3 buckets [#923](https://github.com/mapbox/node-pre-gyp/pull/923) + ## 2.0.1 - Update abi_crosswalk.json for abi 137 / node 24 (https://github.com/mapbox/node-pre-gyp/pull/904) diff --git a/package-lock.json b/package-lock.json index 632d1849..f18ab83f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-dev.2", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-dev.2", + "version": "2.0.2", "license": "BSD-3-Clause", "dependencies": { "consola": "^3.2.3", diff --git a/package.json b/package.json index 742a6feb..81cfa20e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "2.0.2-dev.2", + "version": "2.0.2", "keywords": [ "native", "addon", From 59a65e04e75f31801fc0257e1653c6f3f34b2603 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 12:12:50 +0200 Subject: [PATCH 08/13] add tests for fallback --- lib/install.js | 10 ++- package-lock.json | 4 +- package.json | 2 +- test/private-binary.test.js | 158 ++++++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 test/private-binary.test.js diff --git a/lib/install.js b/lib/install.js index f032a0b6..51839cc8 100644 --- a/lib/install.js +++ b/lib/install.js @@ -29,7 +29,7 @@ function place_binary_authenticated(opts, targetDir, callback) { log.info('install', 'Attempting authenticated S3 download'); // Check if AWS credentials are available - if (!process.env.AWS_ACCESS_KEY_ID && !process.env.AWS_SECRET_ACCESS_KEY) { + if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) { const err = new Error('Binary is private but AWS credentials not found. Please configure AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or use --fallback-to-build to compile from source.'); err.statusCode = 403; return callback(err); @@ -127,7 +127,10 @@ function place_binary(uri, targetDir, opts, callback) { // If we get 403 Forbidden, the binary might be private - try authenticated download if (res.status === 403) { log.info('install', 'Received 403 Forbidden - attempting authenticated download'); - return place_binary_authenticated(opts, targetDir, callback); + // Call place_binary_authenticated and return a special marker + // to prevent the promise chain from calling callback again + place_binary_authenticated(opts, targetDir, callback); + return { authenticated: true }; } throw new Error(`response status ${res.status} ${res.statusText} on ${sanitized}`); } @@ -153,6 +156,9 @@ function place_binary(uri, targetDir, opts, callback) { }); }) .then((text) => { + if (text && text.authenticated) { + return; // Don't call callback - place_binary_authenticated will handle it + } log.info(text); callback(); }) diff --git a/package-lock.json b/package-lock.json index f18ab83f..0f85e843 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2", + "version": "2.0.2-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2", + "version": "2.0.2-beta", "license": "BSD-3-Clause", "dependencies": { "consola": "^3.2.3", diff --git a/package.json b/package.json index 81cfa20e..8bac2d6f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "2.0.2", + "version": "2.0.2-beta", "keywords": [ "native", "addon", diff --git a/test/private-binary.test.js b/test/private-binary.test.js new file mode 100644 index 00000000..ee453c7f --- /dev/null +++ b/test/private-binary.test.js @@ -0,0 +1,158 @@ +'use strict'; + +const fs = require('fs'); +const test = require('tape'); +const nock = require('nock'); +const install = require('../lib/install.js'); + +// Dummy tar.gz data - contains a blank directory +const targz = 'H4sICPr8u1oCA3gudGFyANPTZ6A5MDAwMDc1VQDTZhAaCGA0hGNobGRqZm5uZmxupGBgaGhiZsKgYMpAB1BaXJJYBHRKYk5pcioedeUZqak5+D2J5CkFhlEwCkbBKBjkAAAyG1ofAAYAAA=='; + +test('should fallback to authenticated download on 403 Forbidden', (t) => { + process.env.node_pre_gyp_mock_s3 = 'true'; + process.env.AWS_ACCESS_KEY_ID = 'mock-key'; + process.env.AWS_SECRET_ACCESS_KEY = 'mock-secret'; + + const origin = 'https://npg-mock-bucket.s3.us-east-1.amazonaws.com'; + nock.cleanAll(); + + // Mock the public HTTPS request to return 403 + const publicScope = nock(origin) + .get(/\/node-pre-gyp\/node-pre-gyp-test-app1\/v0.1.0\/Release\/node-v\d+-\S+.tar.gz/) + .reply(403, 'Forbidden'); + + const opts = { + opts: { + 'build-from-source': false, + 'update-binary': true + } + }; + + process.chdir('test/app1'); + opts.package_json = JSON.parse(fs.readFileSync('./package.json')); + opts.package_json.binary.host = origin; + + install(opts, [], (err) => { + delete process.env.node_pre_gyp_mock_s3; + delete process.env.AWS_ACCESS_KEY_ID; + delete process.env.AWS_SECRET_ACCESS_KEY; + + t.ok(publicScope.isDone(), 'Public HTTPS request was attempted'); + if (err) { + t.ok(err.message.includes('does not exist') || err.message.includes('NotFound'), + 'Error should be about missing file in S3, not credentials'); + } else { + t.pass('Authenticated download succeeded'); + } + + nock.cleanAll(); + t.end(); + }); +}); + +test('should fail gracefully when 403 and no AWS credentials', (t) => { + try { + process.chdir('test/app1'); + } catch (e) { + // Already in test/app1 from previous test + } + + // Ensure no AWS credentials + delete process.env.AWS_ACCESS_KEY_ID; + delete process.env.AWS_SECRET_ACCESS_KEY; + delete process.env.node_pre_gyp_mock_s3; + + const origin = 'https://npg-mock-bucket.s3.us-east-1.amazonaws.com'; + + nock.cleanAll(); + const publicScope = nock(origin) + .get(/\/node-pre-gyp\/node-pre-gyp-test-app1\/v0.1.0\/Release\/node-v\d+-\S+.tar.gz/) + .reply(403, 'Forbidden'); + + const opts = { + opts: { + 'build-from-source': false, + 'update-binary': true + } + }; + + opts.package_json = JSON.parse(fs.readFileSync('./package.json')); + opts.package_json.binary.host = origin; + + install(opts, [], (err) => { + t.ok(err, 'Should error without credentials'); + t.ok(err.message.includes('AWS credentials not found'), 'Error should mention missing credentials'); + t.equal(err.statusCode, 403, 'Error should have 403 status code'); + t.ok(publicScope.isDone(), 'Public HTTPS request was attempted'); + + nock.cleanAll(); + t.end(); + }); +}); + +test('should succeed with public binary (no 403)', (t) => { + try { + process.chdir('test/app1'); + } catch (e) { + // Already in test/app1 + } + + const origin = 'https://npg-mock-bucket.s3.us-east-1.amazonaws.com'; + nock.cleanAll(); + const scope = nock(origin) + .get(/\/node-pre-gyp\/node-pre-gyp-test-app1\/v0.1.0\/Release\/node-v\d+-\S+.tar.gz/) + .reply(200, Buffer.from(targz, 'base64')); + + const opts = { + opts: { + 'build-from-source': false, + 'update-binary': true + } + }; + + opts.package_json = JSON.parse(fs.readFileSync('./package.json')); + opts.package_json.binary.host = origin; + + install(opts, [], (err) => { + t.ifError(err, 'Public binary install should succeed'); + t.ok(scope.isDone(), 'Public download was completed'); + + nock.cleanAll(); + t.end(); + }); +}); + +test('should handle 404 without triggering authenticated fallback', (t) => { + try { + process.chdir('test/app1'); + } catch (e) { + // Already in test/app1 + } + + const origin = 'https://npg-mock-bucket.s3.us-east-1.amazonaws.com'; + + nock.cleanAll(); + const scope = nock(origin) + .get(/\/node-pre-gyp\/node-pre-gyp-test-app1\/v0.1.0\/Release\/node-v\d+-\S+.tar.gz/) + .reply(404, 'Not Found'); + + const opts = { + opts: { + 'build-from-source': false, + 'update-binary': true + } + }; + + opts.package_json = JSON.parse(fs.readFileSync('./package.json')); + opts.package_json.binary.host = origin; + + install(opts, [], (err) => { + t.ok(err, 'Should error with 404'); + t.ok(err.message.includes('404'), 'Error message should mention 404'); + t.notOk(err.message.includes('credentials'), 'Should not mention credentials for 404'); + t.ok(scope.isDone(), 'HTTP request was completed'); + + nock.cleanAll(); + t.end(); + }); +}); From f913a54039cf58e62be15de6ab7fcff0d4769448 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 12:17:29 +0200 Subject: [PATCH 09/13] fix tests --- test/private-binary.test.js | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/test/private-binary.test.js b/test/private-binary.test.js index ee453c7f..a3fccc12 100644 --- a/test/private-binary.test.js +++ b/test/private-binary.test.js @@ -1,6 +1,7 @@ 'use strict'; const fs = require('fs'); +const path = require('path'); const test = require('tape'); const nock = require('nock'); const install = require('../lib/install.js'); @@ -8,6 +9,9 @@ const install = require('../lib/install.js'); // Dummy tar.gz data - contains a blank directory const targz = 'H4sICPr8u1oCA3gudGFyANPTZ6A5MDAwMDc1VQDTZhAaCGA0hGNobGRqZm5uZmxupGBgaGhiZsKgYMpAB1BaXJJYBHRKYk5pcioedeUZqak5+D2J5CkFhlEwCkbBKBjkAAAyG1ofAAYAAA=='; +// Determine the project root (where package.json with @mapbox/node-pre-gyp exists) +const projectRoot = path.join(__dirname, '..'); + test('should fallback to authenticated download on 403 Forbidden', (t) => { process.env.node_pre_gyp_mock_s3 = 'true'; process.env.AWS_ACCESS_KEY_ID = 'mock-key'; @@ -28,7 +32,9 @@ test('should fallback to authenticated download on 403 Forbidden', (t) => { } }; - process.chdir('test/app1'); + // cd into app directory from project root + const appDir = path.join(projectRoot, 'test', 'app1'); + process.chdir(appDir); opts.package_json = JSON.parse(fs.readFileSync('./package.json')); opts.package_json.binary.host = origin; @@ -51,12 +57,6 @@ test('should fallback to authenticated download on 403 Forbidden', (t) => { }); test('should fail gracefully when 403 and no AWS credentials', (t) => { - try { - process.chdir('test/app1'); - } catch (e) { - // Already in test/app1 from previous test - } - // Ensure no AWS credentials delete process.env.AWS_ACCESS_KEY_ID; delete process.env.AWS_SECRET_ACCESS_KEY; @@ -76,6 +76,9 @@ test('should fail gracefully when 403 and no AWS credentials', (t) => { } }; + // cd into app directory from project root + const appDir = path.join(projectRoot, 'test', 'app1'); + process.chdir(appDir); opts.package_json = JSON.parse(fs.readFileSync('./package.json')); opts.package_json.binary.host = origin; @@ -91,12 +94,6 @@ test('should fail gracefully when 403 and no AWS credentials', (t) => { }); test('should succeed with public binary (no 403)', (t) => { - try { - process.chdir('test/app1'); - } catch (e) { - // Already in test/app1 - } - const origin = 'https://npg-mock-bucket.s3.us-east-1.amazonaws.com'; nock.cleanAll(); const scope = nock(origin) @@ -110,6 +107,9 @@ test('should succeed with public binary (no 403)', (t) => { } }; + // cd into app directory from project root + const appDir = path.join(projectRoot, 'test', 'app1'); + process.chdir(appDir); opts.package_json = JSON.parse(fs.readFileSync('./package.json')); opts.package_json.binary.host = origin; @@ -123,12 +123,6 @@ test('should succeed with public binary (no 403)', (t) => { }); test('should handle 404 without triggering authenticated fallback', (t) => { - try { - process.chdir('test/app1'); - } catch (e) { - // Already in test/app1 - } - const origin = 'https://npg-mock-bucket.s3.us-east-1.amazonaws.com'; nock.cleanAll(); @@ -143,6 +137,9 @@ test('should handle 404 without triggering authenticated fallback', (t) => { } }; + // cd into app directory from project root + const appDir = path.join(projectRoot, 'test', 'app1'); + process.chdir(appDir); opts.package_json = JSON.parse(fs.readFileSync('./package.json')); opts.package_json.binary.host = origin; From d054ddd834a0b3a4c8d4cf154721596a04c7c466 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 12:19:42 +0200 Subject: [PATCH 10/13] beta version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f85e843..e3b4cabc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-beta", + "version": "2.0.2-beta.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-beta", + "version": "2.0.2-beta.1", "license": "BSD-3-Clause", "dependencies": { "consola": "^3.2.3", diff --git a/package.json b/package.json index 8bac2d6f..1221182a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "2.0.2-beta", + "version": "2.0.2-beta.1", "keywords": [ "native", "addon", From bded841fd1bdffe6739644260a283eba97636aca Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 12:29:55 +0200 Subject: [PATCH 11/13] final version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3b4cabc..f18ab83f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-beta.1", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mapbox/node-pre-gyp", - "version": "2.0.2-beta.1", + "version": "2.0.2", "license": "BSD-3-Clause", "dependencies": { "consola": "^3.2.3", diff --git a/package.json b/package.json index 1221182a..81cfa20e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "2.0.2-beta.1", + "version": "2.0.2", "keywords": [ "native", "addon", From e68d5651002c9b2471b51cbda7644243293d40a4 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 13:32:49 +0200 Subject: [PATCH 12/13] simplify expectation --- test/private-binary.test.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/private-binary.test.js b/test/private-binary.test.js index a3fccc12..1085c38f 100644 --- a/test/private-binary.test.js +++ b/test/private-binary.test.js @@ -44,12 +44,7 @@ test('should fallback to authenticated download on 403 Forbidden', (t) => { delete process.env.AWS_SECRET_ACCESS_KEY; t.ok(publicScope.isDone(), 'Public HTTPS request was attempted'); - if (err) { - t.ok(err.message.includes('does not exist') || err.message.includes('NotFound'), - 'Error should be about missing file in S3, not credentials'); - } else { - t.pass('Authenticated download succeeded'); - } + t.notOk(err, 'Authenticated download succeeded'); nock.cleanAll(); t.end(); From 3e216b3b1ae46c7c2df43ef723b873561ea89185 Mon Sep 17 00:00:00 2001 From: rafaykh90 Date: Wed, 26 Nov 2025 13:49:46 +0200 Subject: [PATCH 13/13] fix tests --- test/private-binary.test.js | 72 +++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/test/private-binary.test.js b/test/private-binary.test.js index 1085c38f..9491a265 100644 --- a/test/private-binary.test.js +++ b/test/private-binary.test.js @@ -5,6 +5,8 @@ const path = require('path'); const test = require('tape'); const nock = require('nock'); const install = require('../lib/install.js'); +const os = require('os'); +const rimraf = require('rimraf'); // Dummy tar.gz data - contains a blank directory const targz = 'H4sICPr8u1oCA3gudGFyANPTZ6A5MDAwMDc1VQDTZhAaCGA0hGNobGRqZm5uZmxupGBgaGhiZsKgYMpAB1BaXJJYBHRKYk5pcioedeUZqak5+D2J5CkFhlEwCkbBKBjkAAAyG1ofAAYAAA=='; @@ -12,42 +14,58 @@ const targz = 'H4sICPr8u1oCA3gudGFyANPTZ6A5MDAwMDc1VQDTZhAaCGA0hGNobGRqZm5uZmxup // Determine the project root (where package.json with @mapbox/node-pre-gyp exists) const projectRoot = path.join(__dirname, '..'); +// Helper to clean mock S3 directory +function cleanMockS3() { + const mockDir = path.join(os.tmpdir(), 'mock'); + if (fs.existsSync(mockDir)) { + rimraf.sync(mockDir); + } +} + test('should fallback to authenticated download on 403 Forbidden', (t) => { + // Clean mock S3 to ensure deterministic behavior + cleanMockS3(); process.env.node_pre_gyp_mock_s3 = 'true'; process.env.AWS_ACCESS_KEY_ID = 'mock-key'; process.env.AWS_SECRET_ACCESS_KEY = 'mock-secret'; const origin = 'https://npg-mock-bucket.s3.us-east-1.amazonaws.com'; - nock.cleanAll(); - - // Mock the public HTTPS request to return 403 - const publicScope = nock(origin) - .get(/\/node-pre-gyp\/node-pre-gyp-test-app1\/v0.1.0\/Release\/node-v\d+-\S+.tar.gz/) - .reply(403, 'Forbidden'); + const run = require('./run.util.js'); + const app = { name: 'app1', args: '' }; - const opts = { - opts: { - 'build-from-source': false, - 'update-binary': true - } - }; - - // cd into app directory from project root - const appDir = path.join(projectRoot, 'test', 'app1'); - process.chdir(appDir); - opts.package_json = JSON.parse(fs.readFileSync('./package.json')); - opts.package_json.binary.host = origin; - - install(opts, [], (err) => { - delete process.env.node_pre_gyp_mock_s3; - delete process.env.AWS_ACCESS_KEY_ID; - delete process.env.AWS_SECRET_ACCESS_KEY; - - t.ok(publicScope.isDone(), 'Public HTTPS request was attempted'); - t.notOk(err, 'Authenticated download succeeded'); + // First build and publish to mock S3 to create the file + run('node-pre-gyp', 'configure build package publish', '', app, {}, (buildErr) => { + t.ifError(buildErr, 'Build and publish to mock S3 should succeed'); nock.cleanAll(); - t.end(); + const publicScope = nock(origin) + .get(/\/node-pre-gyp\/node-pre-gyp-test-app1\/v0.1.0\/Release\/node-v\d+-\S+.tar.gz/) + .reply(403, 'Forbidden'); + + const appDir = path.join(projectRoot, 'test', 'app1'); + process.chdir(appDir); + const installOpts = { + opts: { + 'build-from-source': false, + 'update-binary': true + }, + package_json: JSON.parse(fs.readFileSync('./package.json')) + }; + installOpts.package_json.binary.host = origin; + + // Run install - should get 403 from HTTP, then succeed with authenticated S3 + install(installOpts, [], (err) => { + delete process.env.node_pre_gyp_mock_s3; + delete process.env.AWS_ACCESS_KEY_ID; + delete process.env.AWS_SECRET_ACCESS_KEY; + + t.ok(publicScope.isDone(), 'Public HTTPS request was attempted (got 403)'); + t.ifError(err, 'Authenticated S3 download should succeed after 403'); + + nock.cleanAll(); + cleanMockS3(); + t.end(); + }); }); });