Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/fix-catalog-protocol-republish.md
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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:",
Expand Down
72 changes: 72 additions & 0 deletions scripts/verify-published-manifests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Guards against unresolved pnpm workspace-protocol strings (`catalog:`,
// `catalog:<name>`, `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.`);