diff --git a/package-lock.json b/package-lock.json index 795a1e3..5734238 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4861,14 +4861,15 @@ } }, "node_modules/compression": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.2.tgz", + "integrity": "sha512-o8vI5RE5A6EVVOd9o41jKp41aJom+QTEO/Bx8MYNjexMo/Bv2WOjUfZr+aL0WnYSgymUy6zeguqLTsIhV0gMvQ==", "license": "MIT", "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", + "destroy": "1.2.0", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", @@ -4876,6 +4877,10 @@ }, "engines": { "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/compression/node_modules/debug": { @@ -11283,9 +11288,9 @@ } }, "node_modules/shell-quote": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", - "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.12.0.tgz", + "integrity": "sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -11354,9 +11359,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" diff --git a/package.json b/package.json index afae8f0..c0fcdaf 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "uuid": "^11.1.1", "postcss": "^8.5.18", "postcss-selector-parser@^6.0.0": "^6.1.3", + "source-map-js@^1.0.0": "^1.2.2", "http-cache-semantics@^4.0.0": "^4.3.0", "js-yaml@^3.0.0": "^3.15.2", "js-yaml@^4.0.0": "^4.3.2", @@ -81,12 +82,13 @@ "@babel/core": "^7.29.6", "browserslist": "^4.28.7", "@expo/cli": { + "compression": "^1.8.2", "ws": "^8.20.1", "undici": "^6.28.1", "tar": "^7.5.21" }, "react-devtools-core": { - "shell-quote": "^1.8.4", + "shell-quote": "^1.11.0", "ws": "^7.5.11" }, "react-native": { diff --git a/tests/smoke.test.cjs b/tests/smoke.test.cjs index 78cfb23..e870dfb 100644 --- a/tests/smoke.test.cjs +++ b/tests/smoke.test.cjs @@ -335,6 +335,70 @@ check('every installed postcss-selector-parser copy is 6.x and >= 6.1.3', () => ); }); +// --- Override floors (#133, #134, #135) --- +// shell-quote: scoped to react-devtools-core (raised from #95's ^1.8.4). +// compression: scoped to @expo/cli (dev server middleware). +// source-map-js: version-scoped to major 1 (postcss, tailwindcss pipeline). +// Each floor is paired with a call to the API its consumer actually uses. + +check('every installed shell-quote copy is >= 1.11.0 and still quotes/parses', () => { + const copies = installedCopies('shell-quote'); + assert.ok(copies.length > 0, 'shell-quote is not installed'); + const strays = copies.filter((c) => !versionAtLeast(c.version, '1.11.0')); + assert.deepEqual( + strays.map((c) => `${c.version} at ${path.relative(ROOT, c.dir)}`), + [], + 'shell-quote must be >= 1.11.0' + ); + for (const c of copies) { + const { quote, parse } = require(c.dir); + const where = `shell-quote ${c.version} at ${path.relative(ROOT, c.dir)}`; + assert.equal(quote(['code', '-g', 'a b.js:1']), "code -g 'a b.js:1'", `${where}: quote`); + assert.deepEqual(parse('a "b c" d'), ['a', 'b c', 'd'], `${where}: parse`); + } +}); + +check('every installed compression copy is >= 1.8.2 and builds a middleware', () => { + const copies = installedCopies('compression'); + assert.ok(copies.length > 0, 'compression is not installed'); + const strays = copies.filter((c) => !versionAtLeast(c.version, '1.8.2')); + assert.deepEqual( + strays.map((c) => `${c.version} at ${path.relative(ROOT, c.dir)}`), + [], + 'compression must be >= 1.8.2' + ); + for (const c of copies) { + const middleware = require(c.dir)(); + assert.equal(typeof middleware, 'function', `compression ${c.version}: middleware`); + assert.equal(middleware.length, 3, `compression ${c.version}: (req, res, next) signature`); + } +}); + +check('every installed source-map-js copy is 1.x >= 1.2.2 and round-trips a mapping', () => { + const copies = installedCopies('source-map-js'); + assert.ok(copies.length > 0, 'source-map-js is not installed'); + const strays = copies.filter( + (c) => majorOf(c.version) !== '1' || !versionAtLeast(c.version, '1.2.2') + ); + assert.deepEqual( + strays.map((c) => `${c.version} at ${path.relative(ROOT, c.dir)}`), + [], + 'source-map-js must be 1.x >= 1.2.2' + ); + for (const c of copies) { + const { SourceMapGenerator, SourceMapConsumer } = require(c.dir); + const gen = new SourceMapGenerator({ file: 'out.css' }); + gen.addMapping({ + source: 'in.css', + original: { line: 3, column: 2 }, + generated: { line: 1, column: 0 }, + }); + const pos = new SourceMapConsumer(gen.toJSON()).originalPositionFor({ line: 1, column: 0 }); + const where = `source-map-js ${c.version} at ${path.relative(ROOT, c.dir)}`; + assert.deepEqual([pos.source, pos.line, pos.column], ['in.css', 3, 2], where); + } +}); + // The call that broke under the blanket override: each minimatch copy must // still expand braces through its own brace-expansion major. check('every installed minimatch copy still matches globs and braces', () => {