diff --git a/.changeset/fix-catalog-protocol-republish.md b/.changeset/fix-catalog-protocol-republish.md new file mode 100644 index 000000000..10756de2f --- /dev/null +++ b/.changeset/fix-catalog-protocol-republish.md @@ -0,0 +1,6 @@ +--- +"@solid-primitives/event-listener": patch +"@solid-primitives/pagination": patch +--- + +Republish only, no functional changes. `event-listener@3.0.0-next.4` and `pagination@1.0.0-next.7` were accidentally published to npm with an unresolved pnpm workspace-catalog protocol string (`"catalog:peer"`) left in `peerDependencies`, instead of a resolved semver range. npm and yarn have no concept of the `catalog:` protocol, so installing either of those exact versions fails with `EUNSUPPORTEDPROTOCOL`. This release republishes both packages with `peerDependencies` correctly resolved (e.g. `"solid-js": "^2.0.0-rc.0"`). If you're on `event-listener@3.0.0-next.4` or `pagination@1.0.0-next.7`, upgrade to this version or later. diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 82330fe00..54275fc11 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,6 +29,9 @@ jobs: - name: Build all packages run: pnpm build + - name: Verify no unresolved workspace protocols in packed manifests + run: pnpm run verify:manifests + - name: Lint # Will run the step even if build step failed if: success() || failure() diff --git a/package.json b/package.json index deb1f5f99..5d8e73cf5 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,10 @@ "jsr:sync-versions:check": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ./scripts/sync-jsr-versions.ts --check", "update-readme": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ./scripts/update-readme.ts", "measure": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ./scripts/measure.ts", + "verify:manifests": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ./scripts/verify-published-manifests.ts", "version": "changeset version && pnpm jsr:sync-versions && pnpm i --no-frozen-lockfile && git add .", - "release": "pnpm build && changeset publish", - "release-tagged": "pnpm build && if [ -f .changeset/pre.json ]; then changeset publish; else changeset publish --tag \"$BRANCH_NAME\"; fi" + "release": "pnpm build && pnpm run verify:manifests && changeset publish", + "release-tagged": "pnpm build && pnpm run verify:manifests && if [ -f .changeset/pre.json ]; then changeset publish; else changeset publish --tag \"$BRANCH_NAME\"; fi" }, "devDependencies": { "@babel/core": "catalog:", diff --git a/scripts/verify-published-manifests.ts b/scripts/verify-published-manifests.ts new file mode 100644 index 000000000..cb6a29251 --- /dev/null +++ b/scripts/verify-published-manifests.ts @@ -0,0 +1,72 @@ +// Guards against unresolved pnpm workspace-protocol strings (`catalog:`, +// `catalog:`, `workspace:`) making it into a package's PUBLISHED +// manifest. Source package.json files are expected to contain these +// protocols — pnpm resolves them at pack/publish time. This script actually +// packs every package (via `pnpm pack`, the same manifest-resolution path +// `pnpm publish` uses) and inspects the packed package/package.json, not the +// source file, so it only fails on a genuine resolution failure. +// +// Background: @solid-primitives/event-listener@3.0.0-next.4 and +// @solid-primitives/pagination@1.0.0-next.7 were published to npm with +// literal "catalog:peer" strings left in peerDependencies, which breaks +// plain npm/yarn installs (EUNSUPPORTEDPROTOCOL). See +// https://github.com/solidjs-community/solid-primitives/issues/1052. +// +// Usage: pnpm run verify:manifests +import * as fs from "node:fs"; +import * as os from "node:os"; +import * as path from "node:path"; +import { execFileSync } from "node:child_process"; + +const repoRoot = path.resolve(import.meta.dirname, ".."); +const DEP_FIELDS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"] as const; +const BAD_PROTOCOLS = ["catalog:", "workspace:"]; + +type PackedPackage = { name: string; version: string; filename: string }; + +const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "verify-manifests-")); + +let packed: PackedPackage[]; +try { + const output = execFileSync( + "pnpm", + ["pack", "--recursive", "--json", "--pack-destination", tmpDir], + { cwd: repoRoot, encoding: "utf8", maxBuffer: 1024 * 1024 * 64 }, + ); + packed = JSON.parse(output); +} catch (err) { + fs.rmSync(tmpDir, { recursive: true, force: true }); + throw err; +} + +const failures: string[] = []; + +for (const pkg of packed) { + const manifestText = execFileSync("tar", ["-xzO", "-f", pkg.filename, "package/package.json"], { + encoding: "utf8", + }); + const manifest = JSON.parse(manifestText); + + for (const field of DEP_FIELDS) { + const deps = manifest[field]; + if (!deps) continue; + for (const [dep, range] of Object.entries(deps)) { + if (typeof range === "string" && BAD_PROTOCOLS.some(p => range.startsWith(p))) { + failures.push(`${pkg.name}@${pkg.version} ${field}.${dep} = "${range}"`); + } + } + } +} + +fs.rmSync(tmpDir, { recursive: true, force: true }); + +if (failures.length > 0) { + console.error("Unresolved workspace-protocol strings found in packed manifests:\n"); + for (const f of failures) console.error(` - ${f}`); + console.error( + "\nThese packages would be published to npm broken (npm/yarn can't resolve `catalog:`/`workspace:`). Aborting release.", + ); + process.exit(1); +} + +console.log(`Verified ${packed.length} packed manifests: no unresolved workspace protocols.`);