From b7136eea15d1bf4abdc36f609e1f084887c3facc Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Mon, 31 Aug 2026 14:36:08 +0300 Subject: [PATCH] fix(release): validate wildcard export targets --- tools/release-packages/src/tarballs.ts | 21 +++++++++++++++---- tools/release-packages/tests/tarballs.test.ts | 6 ++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tools/release-packages/src/tarballs.ts b/tools/release-packages/src/tarballs.ts index 2c8d2db44..381843308 100644 --- a/tools/release-packages/src/tarballs.ts +++ b/tools/release-packages/src/tarballs.ts @@ -12,7 +12,6 @@ type PackageExports = { type PackageJSON = { bin?: Record | string exports?: PackageExports - imports?: PackageExports name: string } @@ -56,15 +55,29 @@ export async function validateTarballBinTargets(tarballPath: string): Promise { const entries = await tarballEntries(tarballPath) const packageJSON = await tarballPackageJSON(tarballPath) for (const target of packageExportTargetPaths(packageJSON)) { if (!target.startsWith('./')) continue - const entry = `package/${target.slice(2)}` - if (!entries.has(entry)) { - throw new Error(`${tarballPath}: export target missing from tarball: ${entry}`) + const relativeTarget = target.slice(2) + let matchingEntries: string[] + if (relativeTarget.includes('*')) { + const pattern = exportTargetPattern(relativeTarget) + matchingEntries = [...entries].filter((entry) => pattern.test(entry.slice('package/'.length))) + } else { + const exactEntry = `package/${relativeTarget}` + matchingEntries = entries.has(exactEntry) ? [exactEntry] : [] + } + if (matchingEntries.length === 0) { + throw new Error( + `${tarballPath}: export target missing from tarball: package/${relativeTarget}` + ) } } } diff --git a/tools/release-packages/tests/tarballs.test.ts b/tools/release-packages/tests/tarballs.test.ts index 547f1504c..cdd0ad4e5 100644 --- a/tools/release-packages/tests/tarballs.test.ts +++ b/tools/release-packages/tests/tarballs.test.ts @@ -19,6 +19,12 @@ describe('packageBinTargets', () => { }) describe('package export targets', () => { + test('collects wildcard targets from conditional exports', () => { + expect( + packageExportTargetPaths({ exports: { './feature/*': { import: './dist/*.js' } } }) + ).toEqual(['./dist/*.js']) + }) + test('collects targets from conditional exports', () => { expect( packageExportTargetPaths({