diff --git a/CHANGELOG.md b/CHANGELOG.md index 84721ccf2d..0df2a83541 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,8 @@ This is the log of notable changes to EAS CLI and related packages. - [build-tools] Upload tvOS (and other non-iOS) IPAs to the App Store Connect platform declared in the bundle's `DTPlatformName`, instead of always uploading to the iOS train. ([#4234](https://github.com/expo/eas-cli/pull/4234) by [@douglowder](https://github.com/douglowder)) +- [eas-cli] Bump `minizlib` to 3.1.0 to drop its deprecated `rimraf@5` transitive dependency. ([#4281](https://github.com/expo/eas-cli/pull/4281) by [@brentvatne](https://github.com/brentvatne)) + ## [22.2.0](https://github.com/expo/eas-cli/releases/tag/v22.2.0) - 2026-08-20 ### 🎉 New features diff --git a/packages/eas-cli/package.json b/packages/eas-cli/package.json index d4699aa555..20f022cfcc 100644 --- a/packages/eas-cli/package.json +++ b/packages/eas-cli/package.json @@ -104,7 +104,7 @@ "log-symbols": "4.1.0", "mime": "3.0.0", "minimatch": "5.1.2", - "minizlib": "3.0.1", + "minizlib": "3.1.0", "nanoid": "3.3.8", "node-fetch": "2.6.7", "node-forge": "1.4.0", diff --git a/packages/eas-cli/src/worker/__tests__/assets.test.ts b/packages/eas-cli/src/worker/__tests__/assets.test.ts new file mode 100644 index 0000000000..d717c7ca66 --- /dev/null +++ b/packages/eas-cli/src/worker/__tests__/assets.test.ts @@ -0,0 +1,70 @@ +import fs from 'node:fs'; +import { Readable } from 'node:stream'; +import { extract } from 'tar-stream'; +import zlib from 'node:zlib'; + +import { FileEntry, packFilesIterableAsync } from '../assets'; + +async function extractTarEntriesAsync(tarData: Buffer): Promise> { + const entries = new Map(); + const extractor = extract(); + extractor.on('entry', (header, stream, next) => { + const chunks: Buffer[] = []; + stream.on('data', chunk => chunks.push(chunk)); + stream.on('end', () => { + entries.set(header.name, Buffer.concat(chunks).toString('utf8')); + next(); + }); + stream.resume(); + }); + await new Promise((resolve, reject) => { + extractor.on('finish', resolve); + extractor.on('error', reject); + Readable.from(tarData).pipe(extractor); + }); + return entries; +} + +describe(packFilesIterableAsync, () => { + let tarPath: string | null = null; + + afterEach(async () => { + if (tarPath) { + await fs.promises.rm(tarPath, { force: true }); + tarPath = null; + } + }); + + it('packs file entries into a gzip-compressed tarball', async () => { + const files: FileEntry[] = [ + ['index.html', '

hello

'], + ['assets/data.json', '{"key":"value"}'], + ]; + tarPath = await packFilesIterableAsync(files); + + const compressed = await fs.promises.readFile(tarPath); + // gzip magic bytes + expect(compressed[0]).toBe(0x1f); + expect(compressed[1]).toBe(0x8b); + // portable mode zeroes the gzip MTIME field (bytes 4-7) + expect(compressed.subarray(4, 8)).toEqual(Buffer.from([0, 0, 0, 0])); + + const entries = await extractTarEntriesAsync(zlib.gunzipSync(compressed)); + expect(entries.get('index.html')).toBe('

hello

'); + expect(entries.get('assets/data.json')).toBe('{"key":"value"}'); + expect(entries.size).toBe(2); + }); + + it('accepts async iterables and forwards gzip options', async () => { + async function* files(): AsyncIterable { + yield ['a.txt', 'aaaa']; + yield ['b.txt', Buffer.from('bbbb')]; + } + tarPath = await packFilesIterableAsync(files(), { level: 9 }); + + const compressed = await fs.promises.readFile(tarPath); + const entries = await extractTarEntriesAsync(zlib.gunzipSync(compressed)); + expect(entries.get('a.txt')).toBe('aaaa'); + expect(entries.get('b.txt')).toBe('bbbb'); + }); +}); diff --git a/yarn.lock b/yarn.lock index 2614385264..304540ea0a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10480,7 +10480,7 @@ __metadata: memfs: "npm:3.4.13" mime: "npm:3.0.0" minimatch: "npm:5.1.2" - minizlib: "npm:3.0.1" + minizlib: "npm:3.1.0" mockdate: "npm:3.0.5" nanoid: "npm:3.3.8" nock: "npm:13.4.0" @@ -11699,7 +11699,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.2": +"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.2": version: 10.5.0 resolution: "glob@npm:10.5.0" dependencies: @@ -15026,13 +15026,12 @@ __metadata: languageName: node linkType: hard -"minizlib@npm:3.0.1": - version: 3.0.1 - resolution: "minizlib@npm:3.0.1" +"minizlib@npm:3.1.0, minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": + version: 3.1.0 + resolution: "minizlib@npm:3.1.0" dependencies: - minipass: "npm:^7.0.4" - rimraf: "npm:^5.0.5" - checksum: 10c0/82f8bf70da8af656909a8ee299d7ed3b3372636749d29e105f97f20e88971be31f5ed7642f2e898f00283b68b701cc01307401cdc209b0efc5dd3818220e5093 + minipass: "npm:^7.1.2" + checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec languageName: node linkType: hard @@ -15046,15 +15045,6 @@ __metadata: languageName: node linkType: hard -"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": - version: 3.1.0 - resolution: "minizlib@npm:3.1.0" - dependencies: - minipass: "npm:^7.1.2" - checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec - languageName: node - linkType: hard - "mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" @@ -17404,17 +17394,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^5.0.5": - version: 5.0.7 - resolution: "rimraf@npm:5.0.7" - dependencies: - glob: "npm:^10.3.7" - bin: - rimraf: dist/esm/bin.mjs - checksum: 10c0/bd6dbfaa98ae34ce1e54d1e06045d2d63e8859d9a1979bb4a4628b652b459a2d17b17dc20ee072b034bd2d09bd691e801d24c4d9cfe94e16fdbcc8470a1d4807 - languageName: node - linkType: hard - "rimraf@npm:~2.4.0": version: 2.4.5 resolution: "rimraf@npm:2.4.5"