// Name: Deduplicate Emails // Description: Accepts a comma-separated list of emails, returns a deduplicated string and lists which emails had duplicates. // Author: zacjones93 // GitHub: zacjones93 import "@johnlindquist/kit" const input = await arg({ placeholder: "Paste comma-separated emails", enter: "Deduplicate", strict: false, }) const tokens = input .replace(/[\n\r;]+/g, ",") .split(",") .map(s => s.trim()) .filter(Boolean) const counts = new Map<string, number>() const firstOriginal = new Map<string, string>() // normalized -> first seen original for (const email of tokens) { const norm = email.toLowerCase() if (!firstOriginal.has(norm)) firstOriginal.set(norm, email) counts.set(norm, (counts.get(norm) || 0) + 1) } const deduped = Array.from(firstOriginal.values()) const dedupedCSV = deduped.join(", ") const duplicates = Array.from(counts.entries()) .filter(([_, c]) => c > 1) .map(([norm, c]) => ({ email: firstOriginal.get(norm) || norm, count: c, })) await copy(dedupedCSV) toast("Copied deduplicated list to clipboard") const summary = md(` # Deduplicated Emails - Total provided: ${tokens.length} - Unique: ${deduped.length} - Duplicates found: ${duplicates.length} ## Deduplicated CSV \`\`\` ${dedupedCSV} \`\`\` ${ duplicates.length ? `## Emails with duplicates ${duplicates.map(d => `- ${d.email} (${d.count} occurrences)`).join("\n")}` : `## Emails with duplicates - None 🎉` } `) await div(summary)// Name: Email List Subtractor // Description: Remove emails in List 2 that exist in List 1 and return the remaining emails. // Author: zacjones93 // GitHub: zacjones93 import '@johnlindquist/kit' const [list1Str, list2Str] = await fields([ { label: 'List 1 (comma-separated)', placeholder: 'a@x.com, b@y.com' }, { label: 'List 2 (comma-separated)', placeholder: 'c@z.com, a@x.com' }, ]) const toArray = (s: string) => (s || '') .split(/[,\s;]+/g) .map(e => e.trim()) .filter(Boolean) const list1 = toArray(list1Str) const list2 = toArray(list2Str) const set1 = new Set(list1.map(e => e.toLowerCase())) const remaining = list2.filter(e => !set1.has(e.toLowerCase())) const output = remaining.join('\n') await clipboard.writeText(output) await editor({ value: output, language: 'text', hint: `${remaining.length} remaining of ${list2.length} after excluding ${list1.length} from list 1`, footer: `Results copied to clipboard`, })