From 10b3bc1553e2e403cdab024f8c673e822bd863cc Mon Sep 17 00:00:00 2001 From: Jah-yee <166608075+Jah-yee@users.noreply.github.com> Date: Fri, 24 Apr 2026 23:53:00 +0800 Subject: [PATCH 1/2] fix(react-devtools-fusebox): change private field from string to boolean The `private` field in package.json should be a boolean per npm specification, not the string `"true"` per package.json spec. Fixes #35793 --- packages/react-devtools-fusebox/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-devtools-fusebox/package.json b/packages/react-devtools-fusebox/package.json index bf5456d4cdac..644f42f04cdd 100644 --- a/packages/react-devtools-fusebox/package.json +++ b/packages/react-devtools-fusebox/package.json @@ -1,7 +1,7 @@ { "name": "react-devtools-fusebox", "version": "0.0.0", - "private": "true", + "private": true, "license": "MIT", "files": ["dist"], "scripts": { From 1439173b216af805d2fed53c153c5a778c095975 Mon Sep 17 00:00:00 2001 From: Jah-yee <166608075+Jah-yee@users.noreply.github.com> Date: Sun, 26 Apr 2026 05:46:04 +0800 Subject: [PATCH 2/2] test: add package.json private field validation scripts Adds two validation scripts that enforce the npm spec requirement that the 'private' field must be a boolean, not a string: - scripts/validate-package-private-field.js: validates a single package.json - scripts/validate-all-package-private-fields.js: scans all packages/ These scripts prevent future regressions where 'private' is accidentally set to a string instead of a boolean. --- .../validate-all-package-private-fields.js | 57 +++++++++++++++++++ scripts/validate-package-private-field.js | 43 ++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 scripts/validate-all-package-private-fields.js create mode 100644 scripts/validate-package-private-field.js diff --git a/scripts/validate-all-package-private-fields.js b/scripts/validate-all-package-private-fields.js new file mode 100644 index 000000000000..eaf66af39228 --- /dev/null +++ b/scripts/validate-all-package-private-fields.js @@ -0,0 +1,57 @@ +#!/usr/bin/env node +'use strict'; + +/** + * Scans all packages/ directories and validates that `private` field + * (if present) is a boolean, per npm specification. + * + * Usage: node scripts/validate-all-package-private-fields.js + */ + +const fs = require('fs'); +const path = require('path'); + +function validatePrivateField(packageJsonPath) { + const content = fs.readFileSync(packageJsonPath, 'utf8'); + const pkg = JSON.parse(content); + + if ('private' in pkg) { + if (typeof pkg.private !== 'boolean') { + return { + path: packageJsonPath, + error: `private must be boolean, got ${typeof pkg.private} ("${pkg.private}")` + }; + } + } + return null; +} + +const packagesDir = 'packages'; +const entries = fs.readdirSync(packagesDir); +const packages = entries.filter(e => { + try { + const stat = fs.statSync(path.join(packagesDir, e)); + return stat.isDirectory() && fs.existsSync(path.join(packagesDir, e, 'package.json')); + } catch { + return false; + } +}); + +let hasError = false; +for (const pkgName of packages) { + const pkgPath = path.join(packagesDir, pkgName, 'package.json'); + const error = validatePrivateField(pkgPath); + if (error) { + console.error(`ERROR: ${pkgName}: ${error.error}`); + hasError = true; + } else { + console.log(`✓ ${pkgName}`); + } +} + +if (hasError) { + console.error('\nValidation failed: some packages have invalid private fields'); + process.exit(1); +} else { + console.log(`\nAll ${packages.length} packages passed validation`); +} diff --git a/scripts/validate-package-private-field.js b/scripts/validate-package-private-field.js new file mode 100644 index 000000000000..891c8e36b0d0 --- /dev/null +++ b/scripts/validate-package-private-field.js @@ -0,0 +1,43 @@ +#!/usr/bin/env node +'use strict'; + +/** + * Validates that the `private` field in package.json is a boolean. + * Per npm specification, `private` must be a boolean value. + * + * Usage: node scripts/validate-package-private-field.js + */ + +const fs = require('fs'); +const path = require('path'); + +function validatePrivateField(packageJsonPath) { + const content = fs.readFileSync(packageJsonPath, 'utf8'); + const pkg = JSON.parse(content); + + if ('private' in pkg) { + if (typeof pkg.private !== 'boolean') { + console.error( + `ERROR: 'private' field in ${path.relative(process.cwd(), packageJsonPath)} ` + + `must be a boolean, got ${typeof pkg.private} ("${pkg.private}")` + ); + process.exit(1); + } + console.log(`✓ ${path.relative(process.cwd(), packageJsonPath)}: private=${pkg.private} (boolean)`); + } else { + console.log(`✓ ${path.relative(process.cwd(), packageJsonPath)}: no private field`); + } +} + +const pkgPath = process.argv[2]; +if (!pkgPath) { + console.error('Usage: node scripts/validate-package-private-field.js '); + process.exit(1); +} + +try { + validatePrivateField(path.resolve(process.cwd(), pkgPath)); +} catch (err) { + console.error(err.message); + process.exit(1); +}