Mass Block [bsky] Reposts [and more]
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add URL type detection + make index.js importable for tests

- guard main() behind entry-point check to allow importing for tests
- add isProfileUrl() to detect profile URLs (rejecting post URLs)
- add resolveProfileTarget() to parse profile URLs and resolve handles to DIDs
- create test.js with comprehensive test coverage for isProfileUrl()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Winter 17c7fb4a 6bdfa564

+47 -4
+28 -4
index.js
··· 9 9 import { Prompt } from "@clack/core"; 10 10 import * as p from "@clack/prompts"; 11 11 import color from "picocolors"; 12 + import { fileURLToPath } from "node:url"; 12 13 13 14 // ── runtime detection ─────────────────────────────────────────────── 14 15 const IS_BUN = typeof Bun !== "undefined"; ··· 110 111 v >>= 5n; 111 112 } 112 113 return out; 114 + } 115 + 116 + // ── URL type detection ────────────────────────────────────────────── 117 + function isProfileUrl(input) { 118 + if (input.startsWith("at://")) return false; 119 + return input.includes("/profile/") && !input.includes("/post/"); 120 + } 121 + 122 + async function resolveProfileTarget(input) { 123 + const match = input.match(/\/profile\/([^/?#]+)/); 124 + if (!match) throw new Error(`can't parse profile URL: ${input}`); 125 + const handleOrDid = match[1]; 126 + if (handleOrDid.startsWith("did:")) return handleOrDid; 127 + return resolveHandle(handleOrDid); 113 128 } 114 129 115 130 // ── URL/URI parsing ───────────────────────────────────────────────── ··· 757 772 }); 758 773 } 759 774 760 - main().catch((err) => { 761 - p.cancel(`fatal: ${err.message}`); 762 - process.exit(1); 763 - }); 775 + // Only run when executed directly (not imported by tests) 776 + const __isMain = IS_BUN 777 + ? import.meta.main 778 + : fileURLToPath(import.meta.url) === process.argv[1]; 779 + 780 + if (__isMain) { 781 + main().catch((err) => { 782 + p.cancel(`fatal: ${err.message}`); 783 + process.exit(1); 784 + }); 785 + } 786 + 787 + export { isProfileUrl };
+19
test.js
··· 1 + import { test } from "node:test"; 2 + import assert from "node:assert/strict"; 3 + import { isProfileUrl } from "./index.js"; 4 + 5 + test("isProfileUrl: profile URLs", () => { 6 + assert.equal(isProfileUrl("https://bsky.app/profile/alice.bsky.social"), true); 7 + assert.equal(isProfileUrl("https://witchsky.app/profile/jim.bsky.social"), true); 8 + assert.equal(isProfileUrl("https://bsky.app/profile/did:plc:abc123"), true); 9 + }); 10 + 11 + test("isProfileUrl: post URLs are rejected", () => { 12 + assert.equal(isProfileUrl("https://bsky.app/profile/alice.bsky.social/post/abc"), false); 13 + assert.equal(isProfileUrl("at://did:plc:abc/app.bsky.feed.post/rkey"), false); 14 + }); 15 + 16 + test("isProfileUrl: unrelated URLs are rejected", () => { 17 + assert.equal(isProfileUrl("https://bsky.app/"), false); 18 + assert.equal(isProfileUrl("https://bsky.app/search"), false); 19 + });