A fast, local-first "redirection engine" for !bang users with a few extra features ^-^
5
fork

Configure Feed

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

at main 141 lines 2.8 kB view raw
1import rawBangs from "./bangs.json" with { type: "json" }; 2 3// Developer script that converts ./bangs.json array to hashmap. 4// Only keeps fields needed at runtime: d (domain), ad (alt domain), s (name), u (url) 5 6type RuntimeBang = { 7 d: string; 8 ad?: string; 9 s: string; 10 u: string; 11}; 12 13const hashbang: Record<string, RuntimeBang> = { 14 t3: { 15 d: "www.t3.chat", 16 s: "T3 Chat", 17 u: "https://www.t3.chat/new?q={{{s}}}", 18 }, 19 m2: { 20 d: "meta.dunkirk.sh", 21 s: "metasearch2", 22 u: "https://meta.dunkirk.sh/search?q={{{s}}}", 23 }, 24 tiktok: { 25 d: "www.tiktok.com", 26 s: "TikTok", 27 u: "https://www.tiktok.com/search?q={{{s}}}", 28 }, 29 image: { 30 d: "duckduckgo.com", 31 s: "Duckduckgo images", 32 u: "https://duckduckgo.com/?q={{{s}}}&ia=images&iax=images&atb=v375-1", 33 }, 34 k: { 35 d: "kagi.com", 36 s: "Kagi Search", 37 u: "https://kagi.com/search?q={{{s}}}", 38 }, 39 kagi: { 40 d: "kagi.com", 41 s: "Kagi Search", 42 u: "https://kagi.com/search?q={{{s}}}", 43 }, 44 ki: { 45 d: "kagi.com", 46 s: "Kagi Images", 47 u: "https://kagi.com/images?q={{{s}}}", 48 }, 49 kagii: { 50 d: "kagi.com", 51 s: "Kagi Images", 52 u: "https://kagi.com/images?q={{{s}}}", 53 }, 54 kv: { 55 d: "kagi.com", 56 s: "Kagi Videos", 57 u: "https://kagi.com/videos?q={{{s}}}", 58 }, 59 kagiv: { 60 d: "kagi.com", 61 s: "Kagi Videos", 62 u: "https://kagi.com/videos?q={{{s}}}", 63 }, 64 kn: { 65 d: "kagi.com", 66 s: "Kagi News", 67 u: "https://kagi.com/news?q={{{s}}}", 68 }, 69 kagin: { 70 d: "kagi.com", 71 s: "Kagi News", 72 u: "https://kagi.com/news?q={{{s}}}", 73 }, 74 km: { 75 d: "kagi.com", 76 s: "Kagi Maps", 77 u: "https://kagi.com/maps?q={{{s}}}", 78 }, 79 kagim: { 80 d: "kagi.com", 81 s: "Kagi Maps", 82 u: "https://kagi.com/maps?q={{{s}}}", 83 }, 84 kp: { 85 d: "kagi.com", 86 s: "Kagi Podcasts", 87 u: "https://kagi.com/podcasts?q={{{s}}}", 88 }, 89 kagip: { 90 d: "kagi.com", 91 s: "Kagi Podcasts", 92 u: "https://kagi.com/podcasts?q={{{s}}}", 93 }, 94 kf: { 95 d: "kagi.com", 96 s: "Kagi FastGPT", 97 u: "https://kagi.com/fastgpt?q={{{s}}}", 98 }, 99 fastgpt: { 100 d: "kagi.com", 101 s: "Kagi FastGPT", 102 u: "https://kagi.com/fastgpt?q={{{s}}}", 103 }, 104 ka: { 105 d: "kagi.com", 106 s: "Kagi Assistant", 107 u: "https://kagi.com/assistant?q={{{s}}}", 108 }, 109 assistant: { 110 d: "kagi.com", 111 s: "Kagi Assistant", 112 u: "https://kagi.com/assistant?q={{{s}}}", 113 }, 114}; 115 116rawBangs.forEach((bang: any) => { 117 if (!bang.t || !bang.u || !bang.s || !bang.d) { 118 console.warn(`Skipping invalid bang: ${JSON.stringify(bang)}`); 119 return; 120 } 121 122 const entry: RuntimeBang = { 123 d: bang.d, 124 s: bang.s, 125 u: bang.u, 126 }; 127 if (bang.ad) entry.ad = bang.ad; 128 129 hashbang[bang.t] = entry; 130 131 if (bang.ts) { 132 bang.ts.forEach((trigger: string) => { 133 hashbang[trigger] = entry; 134 }); 135 } 136}); 137 138Bun.write( 139 "./src/bangs/hashbang.ts", 140 `export const bangs: Record<string, { d: string; ad?: string; s: string; u: string }> = ${JSON.stringify(hashbang)};`, 141);