opensentinel 2.1.1 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/README.md +354 -283
  2. package/dist/archiver-AVNBYCKQ.js +15340 -0
  3. package/dist/archiver-AVNBYCKQ.js.map +1 -0
  4. package/dist/audit-logger-OBPR7CRO.js +22 -0
  5. package/dist/auth-UOX5K2BE.js +18 -0
  6. package/dist/autonomy-ZXDBDQUJ.js +86 -0
  7. package/dist/autonomy-ZXDBDQUJ.js.map +1 -0
  8. package/dist/aws-s3-Q4LLZZPD.js +146 -0
  9. package/dist/aws-s3-Q4LLZZPD.js.map +1 -0
  10. package/dist/backup-restore-PZ7CYYB7.js +16 -0
  11. package/dist/blocks-R3PODY47.js +23 -0
  12. package/dist/bot-QRARP4UN.js +36 -0
  13. package/dist/brain-7XLLM3KC.js +56 -0
  14. package/dist/camera-monitor-M5CYKUU4.js +335 -0
  15. package/dist/camera-monitor-M5CYKUU4.js.map +1 -0
  16. package/dist/{charts-MMXM6BWW.js → charts-V7ARZNKF.js} +2 -2
  17. package/dist/chunk-22VGGA7S.js +330 -0
  18. package/dist/chunk-22VGGA7S.js.map +1 -0
  19. package/dist/chunk-35WYTA3C.js +382 -0
  20. package/dist/chunk-35WYTA3C.js.map +1 -0
  21. package/dist/chunk-3E2PSU2C.js +146 -0
  22. package/dist/chunk-3E2PSU2C.js.map +1 -0
  23. package/dist/{chunk-L3F43VPB.js → chunk-4GLYY4NN.js} +2 -2
  24. package/dist/{chunk-L3F43VPB.js.map → chunk-4GLYY4NN.js.map} +1 -1
  25. package/dist/{chunk-L3PDU3XN.js → chunk-4UOE5TUZ.js} +4 -4
  26. package/dist/{chunk-6SNHU3CY.js → chunk-66OJ3WB4.js} +2 -2
  27. package/dist/chunk-6KONMXQ6.js +297 -0
  28. package/dist/chunk-6KONMXQ6.js.map +1 -0
  29. package/dist/chunk-6PMVAAA7.js +196 -0
  30. package/dist/chunk-6PMVAAA7.js.map +1 -0
  31. package/dist/chunk-766ASQWE.js +32620 -0
  32. package/dist/chunk-766ASQWE.js.map +1 -0
  33. package/dist/chunk-7WQO5J2M.js +29 -0
  34. package/dist/chunk-7WQO5J2M.js.map +1 -0
  35. package/dist/chunk-APHSRMBS.js +148 -0
  36. package/dist/chunk-APHSRMBS.js.map +1 -0
  37. package/dist/{chunk-4LVWXUNC.js → chunk-AYUKPTSM.js} +57 -39
  38. package/dist/chunk-AYUKPTSM.js.map +1 -0
  39. package/dist/chunk-BIPYADGB.js +84 -0
  40. package/dist/chunk-BIPYADGB.js.map +1 -0
  41. package/dist/chunk-BRBWNV65.js +457 -0
  42. package/dist/chunk-BRBWNV65.js.map +1 -0
  43. package/dist/chunk-BXZ6EA52.js +382 -0
  44. package/dist/chunk-BXZ6EA52.js.map +1 -0
  45. package/dist/chunk-EVE7MIIY.js +290 -0
  46. package/dist/chunk-EVE7MIIY.js.map +1 -0
  47. package/dist/chunk-F3TTNID2.js +138 -0
  48. package/dist/chunk-F3TTNID2.js.map +1 -0
  49. package/dist/chunk-H5RQOFO2.js +190 -0
  50. package/dist/chunk-H5RQOFO2.js.map +1 -0
  51. package/dist/chunk-HN3F4WSW.js +145 -0
  52. package/dist/chunk-HN3F4WSW.js.map +1 -0
  53. package/dist/{chunk-6DRDKB45.js → chunk-I6BDYQIG.js} +20 -9
  54. package/dist/chunk-I6BDYQIG.js.map +1 -0
  55. package/dist/chunk-IZJMVV7O.js +347 -0
  56. package/dist/chunk-IZJMVV7O.js.map +1 -0
  57. package/dist/chunk-KM22GV7G.js +211 -0
  58. package/dist/chunk-KM22GV7G.js.map +1 -0
  59. package/dist/chunk-MGFBLVR7.js +103 -0
  60. package/dist/chunk-MGFBLVR7.js.map +1 -0
  61. package/dist/chunk-MQJ2ECQT.js +228 -0
  62. package/dist/chunk-MQJ2ECQT.js.map +1 -0
  63. package/dist/{chunk-F6QUZQGI.js → chunk-MXAPLSJ5.js} +2 -2
  64. package/dist/{chunk-GK3E2I7A.js → chunk-NHMBTUMW.js} +2 -2
  65. package/dist/chunk-NPRTSZIF.js +131 -0
  66. package/dist/chunk-NPRTSZIF.js.map +1 -0
  67. package/dist/chunk-O7IH7JTI.js +1898 -0
  68. package/dist/chunk-O7IH7JTI.js.map +1 -0
  69. package/dist/chunk-OCVQGBJK.js +293 -0
  70. package/dist/chunk-OCVQGBJK.js.map +1 -0
  71. package/dist/chunk-P6QINGFL.js +332 -0
  72. package/dist/chunk-P6QINGFL.js.map +1 -0
  73. package/dist/chunk-PHDZKPNE.js +91 -0
  74. package/dist/chunk-PHDZKPNE.js.map +1 -0
  75. package/dist/chunk-PLDDJCW6.js +49 -0
  76. package/dist/chunk-PTGTGXV2.js +164 -0
  77. package/dist/chunk-PTGTGXV2.js.map +1 -0
  78. package/dist/chunk-REMIY4U2.js +171 -0
  79. package/dist/chunk-REMIY4U2.js.map +1 -0
  80. package/dist/chunk-RZ4YESBG.js +141 -0
  81. package/dist/chunk-RZ4YESBG.js.map +1 -0
  82. package/dist/chunk-SAX5MHK4.js +111 -0
  83. package/dist/chunk-SAX5MHK4.js.map +1 -0
  84. package/dist/{chunk-GVJVEWHI.js → chunk-SJSUSJ47.js} +2 -2
  85. package/dist/chunk-SPPMCAKG.js +777 -0
  86. package/dist/chunk-SPPMCAKG.js.map +1 -0
  87. package/dist/chunk-SVAPX2XN.js +2441 -0
  88. package/dist/chunk-SVAPX2XN.js.map +1 -0
  89. package/dist/chunk-TVEWKIK3.js +452 -0
  90. package/dist/chunk-TVEWKIK3.js.map +1 -0
  91. package/dist/{chunk-HH2HBTQM.js → chunk-TYAGMJNV.js} +5 -5
  92. package/dist/{chunk-JXUP2X7V.js → chunk-VEHFVBLI.js} +2 -2
  93. package/dist/chunk-VNX5GMTN.js +128 -0
  94. package/dist/chunk-VNX5GMTN.js.map +1 -0
  95. package/dist/chunk-VRD5CYRL.js +1568 -0
  96. package/dist/chunk-VRD5CYRL.js.map +1 -0
  97. package/dist/chunk-WLUHNG6X.js +122 -0
  98. package/dist/chunk-WLUHNG6X.js.map +1 -0
  99. package/dist/chunk-WRAKK6K6.js +265 -0
  100. package/dist/chunk-WRAKK6K6.js.map +1 -0
  101. package/dist/chunk-XKYRH4FM.js +681 -0
  102. package/dist/chunk-XKYRH4FM.js.map +1 -0
  103. package/dist/{chunk-GUBEEYDW.js → chunk-XMCVRVTF.js} +2 -2
  104. package/dist/{chunk-GUBEEYDW.js.map → chunk-XMCVRVTF.js.map} +1 -1
  105. package/dist/chunk-ZLZKF2PM.js +310 -0
  106. package/dist/chunk-ZLZKF2PM.js.map +1 -0
  107. package/dist/cli.js +5 -1
  108. package/dist/cli.js.map +1 -1
  109. package/dist/client-ZQSFPMOB.js +21 -0
  110. package/dist/clipboard-manager-TEO2GEDN.js +24 -0
  111. package/dist/commands/setup.js +3 -3
  112. package/dist/commands/setup.js.map +1 -1
  113. package/dist/commands/start.js +3 -3
  114. package/dist/commands/status.js +2 -2
  115. package/dist/commands/stop.js +2 -2
  116. package/dist/commands/utils.js +2 -2
  117. package/dist/cron-explain-HHQKPD3M.js +16 -0
  118. package/dist/crypto-4AP47IKC.js +14 -0
  119. package/dist/crypto-4AP47IKC.js.map +1 -0
  120. package/dist/databases-37X4CI2Y.js +21 -0
  121. package/dist/databases-37X4CI2Y.js.map +1 -0
  122. package/dist/discord-B3HUPGQ6.js +70 -0
  123. package/dist/discord-B3HUPGQ6.js.map +1 -0
  124. package/dist/dist-UISMLMFN.js +21847 -0
  125. package/dist/dist-UISMLMFN.js.map +1 -0
  126. package/dist/email-K7LO2IPB.js +268 -0
  127. package/dist/email-K7LO2IPB.js.map +1 -0
  128. package/dist/enhanced-retrieval-DNLLEM4Z.js +753 -0
  129. package/dist/enhanced-retrieval-DNLLEM4Z.js.map +1 -0
  130. package/dist/enrichment-pipeline-MNHNW65K.js +13 -0
  131. package/dist/enrichment-pipeline-MNHNW65K.js.map +1 -0
  132. package/dist/entity-resolution-Y3IUWEAT.js +24 -0
  133. package/dist/entity-resolution-Y3IUWEAT.js.map +1 -0
  134. package/dist/env-IWXUVTCB.js +12 -0
  135. package/dist/env-IWXUVTCB.js.map +1 -0
  136. package/dist/google-workspace-DKWUVNGC.js +169 -0
  137. package/dist/google-workspace-DKWUVNGC.js.map +1 -0
  138. package/dist/hash-tool-ULQYD7B5.js +22 -0
  139. package/dist/hash-tool-ULQYD7B5.js.map +1 -0
  140. package/dist/heartbeat-monitor-GCISLXI3.js +22 -0
  141. package/dist/heartbeat-monitor-GCISLXI3.js.map +1 -0
  142. package/dist/image-generation-OSU7FP6F.js +486 -0
  143. package/dist/image-generation-OSU7FP6F.js.map +1 -0
  144. package/dist/imessage-NGA2XF2V.js +35 -0
  145. package/dist/imessage-NGA2XF2V.js.map +1 -0
  146. package/dist/inbox-summarizer-NRI4S7IF.js +47 -0
  147. package/dist/inbox-summarizer-NRI4S7IF.js.map +1 -0
  148. package/dist/incident-response-C5J7Q6DT.js +244 -0
  149. package/dist/incident-response-C5J7Q6DT.js.map +1 -0
  150. package/dist/inventory-manager-352OHXWD.js +24 -0
  151. package/dist/inventory-manager-352OHXWD.js.map +1 -0
  152. package/dist/jira-GSGDBMIG.js +199 -0
  153. package/dist/jira-GSGDBMIG.js.map +1 -0
  154. package/dist/json-tool-QE2SYHEG.js +26 -0
  155. package/dist/json-tool-QE2SYHEG.js.map +1 -0
  156. package/dist/key-rotation-DPHU4ZTB.js +18 -0
  157. package/dist/key-rotation-DPHU4ZTB.js.map +1 -0
  158. package/dist/lib.d.ts +603 -11
  159. package/dist/lib.js +161 -35
  160. package/dist/lib.js.map +1 -1
  161. package/dist/mailchimp-KKNF6QJ7.js +152 -0
  162. package/dist/mailchimp-KKNF6QJ7.js.map +1 -0
  163. package/dist/matrix-QVHG76I7.js +279 -0
  164. package/dist/matrix-QVHG76I7.js.map +1 -0
  165. package/dist/{mcp-LS7Q3Z5W.js → mcp-3JI6W7ZE.js} +3 -3
  166. package/dist/mcp-3JI6W7ZE.js.map +1 -0
  167. package/dist/microsoft365-UCBKJHNX.js +164 -0
  168. package/dist/microsoft365-UCBKJHNX.js.map +1 -0
  169. package/dist/ocr-AC7NPX33.js +22 -0
  170. package/dist/ocr-AC7NPX33.js.map +1 -0
  171. package/dist/ollama-BOAMSPLJ.js +8 -0
  172. package/dist/ollama-BOAMSPLJ.js.map +1 -0
  173. package/dist/pages-MI523RB7.js +26 -0
  174. package/dist/pages-MI523RB7.js.map +1 -0
  175. package/dist/pair-JDFTERIK.js +24 -0
  176. package/dist/pair-JDFTERIK.js.map +1 -0
  177. package/dist/pairing-IFQYCPNS.js +10 -0
  178. package/dist/pairing-IFQYCPNS.js.map +1 -0
  179. package/dist/pdf-ALQVOEJR.js +17 -0
  180. package/dist/pdf-ALQVOEJR.js.map +1 -0
  181. package/dist/presentations-DSV5IHG5.js +1002 -0
  182. package/dist/presentations-DSV5IHG5.js.map +1 -0
  183. package/dist/prometheus-JNT2BD4L.js +10 -0
  184. package/dist/prometheus-JNT2BD4L.js.map +1 -0
  185. package/dist/providers-J4LYPHDR.js +19 -0
  186. package/dist/providers-J4LYPHDR.js.map +1 -0
  187. package/dist/qr-code-WIX4PB4U.js +16 -0
  188. package/dist/qr-code-WIX4PB4U.js.map +1 -0
  189. package/dist/quickbooks-XB4NII2S.js +190 -0
  190. package/dist/quickbooks-XB4NII2S.js.map +1 -0
  191. package/dist/regex-tool-W4ABRKGK.js +24 -0
  192. package/dist/regex-tool-W4ABRKGK.js.map +1 -0
  193. package/dist/scheduler-VK4WFERV.js +63 -0
  194. package/dist/scheduler-VK4WFERV.js.map +1 -0
  195. package/dist/search-BCLBO5E3.js +25 -0
  196. package/dist/search-BCLBO5E3.js.map +1 -0
  197. package/dist/sendgrid-RNXCAFKM.js +152 -0
  198. package/dist/sendgrid-RNXCAFKM.js.map +1 -0
  199. package/dist/shopify-NCXYJB4R.js +171 -0
  200. package/dist/shopify-NCXYJB4R.js.map +1 -0
  201. package/dist/signal-6CGDFYL2.js +35 -0
  202. package/dist/signal-6CGDFYL2.js.map +1 -0
  203. package/dist/slack-IZQWIKOH.js +75 -0
  204. package/dist/slack-IZQWIKOH.js.map +1 -0
  205. package/dist/sms-M3JIOTCW.js +23 -0
  206. package/dist/sms-M3JIOTCW.js.map +1 -0
  207. package/dist/{src-K7GASHRH.js → src-VYUE6LRA.js} +138 -32
  208. package/dist/src-VYUE6LRA.js.map +1 -0
  209. package/dist/stocks-XXWBPOCU.js +14 -0
  210. package/dist/stocks-XXWBPOCU.js.map +1 -0
  211. package/dist/text-transform-6SGUA5Z4.js +22 -0
  212. package/dist/text-transform-6SGUA5Z4.js.map +1 -0
  213. package/dist/tools-2RLEI2N6.js +38 -0
  214. package/dist/tools-2RLEI2N6.js.map +1 -0
  215. package/dist/tunnel-IWMXUML4.js +301 -0
  216. package/dist/tunnel-IWMXUML4.js.map +1 -0
  217. package/dist/twilio-53GEW5JT.js +139 -0
  218. package/dist/twilio-53GEW5JT.js.map +1 -0
  219. package/dist/unit-converter-ZYXMEZOE.js +14 -0
  220. package/dist/unit-converter-ZYXMEZOE.js.map +1 -0
  221. package/dist/whatsapp-LFX6YKCM.js +35 -0
  222. package/dist/whatsapp-LFX6YKCM.js.map +1 -0
  223. package/dist/word-document-7B6SJMAY.js +902 -0
  224. package/dist/word-document-7B6SJMAY.js.map +1 -0
  225. package/dist/xero-QYO66D45.js +162 -0
  226. package/dist/xero-QYO66D45.js.map +1 -0
  227. package/dist/zapier-webhook-TBZ5YF2A.js +106 -0
  228. package/dist/zapier-webhook-TBZ5YF2A.js.map +1 -0
  229. package/drizzle/0002_mushy_master_mold.sql +140 -0
  230. package/drizzle/meta/0002_snapshot.json +3637 -0
  231. package/drizzle/meta/_journal.json +7 -0
  232. package/package.json +100 -98
  233. package/dist/bot-KJ26BG56.js +0 -15
  234. package/dist/chunk-4LVWXUNC.js.map +0 -1
  235. package/dist/chunk-4TG2IG5K.js +0 -5249
  236. package/dist/chunk-4TG2IG5K.js.map +0 -1
  237. package/dist/chunk-6DRDKB45.js.map +0 -1
  238. package/dist/chunk-CI6Q63MM.js +0 -1613
  239. package/dist/chunk-CI6Q63MM.js.map +0 -1
  240. package/dist/chunk-KHNYJY2Z.js +0 -178
  241. package/dist/chunk-KHNYJY2Z.js.map +0 -1
  242. package/dist/chunk-NSBPE2FW.js +0 -17
  243. package/dist/discord-ZOJFTVTB.js +0 -49
  244. package/dist/imessage-JFRB6EJ7.js +0 -14
  245. package/dist/scheduler-EZ7CZMCS.js +0 -42
  246. package/dist/signal-T3MCSULM.js +0 -14
  247. package/dist/slack-N2M4FHAJ.js +0 -54
  248. package/dist/src-K7GASHRH.js.map +0 -1
  249. package/dist/tools-24GZHYRF.js +0 -16
  250. package/dist/whatsapp-VCRUPAO5.js +0 -14
  251. /package/dist/{bot-KJ26BG56.js.map → audit-logger-OBPR7CRO.js.map} +0 -0
  252. /package/dist/{chunk-NSBPE2FW.js.map → auth-UOX5K2BE.js.map} +0 -0
  253. /package/dist/{discord-ZOJFTVTB.js.map → backup-restore-PZ7CYYB7.js.map} +0 -0
  254. /package/dist/{imessage-JFRB6EJ7.js.map → blocks-R3PODY47.js.map} +0 -0
  255. /package/dist/{mcp-LS7Q3Z5W.js.map → bot-QRARP4UN.js.map} +0 -0
  256. /package/dist/{scheduler-EZ7CZMCS.js.map → brain-7XLLM3KC.js.map} +0 -0
  257. /package/dist/{charts-MMXM6BWW.js.map → charts-V7ARZNKF.js.map} +0 -0
  258. /package/dist/{chunk-L3PDU3XN.js.map → chunk-4UOE5TUZ.js.map} +0 -0
  259. /package/dist/{chunk-6SNHU3CY.js.map → chunk-66OJ3WB4.js.map} +0 -0
  260. /package/dist/{chunk-F6QUZQGI.js.map → chunk-MXAPLSJ5.js.map} +0 -0
  261. /package/dist/{chunk-GK3E2I7A.js.map → chunk-NHMBTUMW.js.map} +0 -0
  262. /package/dist/{signal-T3MCSULM.js.map → chunk-PLDDJCW6.js.map} +0 -0
  263. /package/dist/{chunk-GVJVEWHI.js.map → chunk-SJSUSJ47.js.map} +0 -0
  264. /package/dist/{chunk-HH2HBTQM.js.map → chunk-TYAGMJNV.js.map} +0 -0
  265. /package/dist/{chunk-JXUP2X7V.js.map → chunk-VEHFVBLI.js.map} +0 -0
  266. /package/dist/{slack-N2M4FHAJ.js.map → client-ZQSFPMOB.js.map} +0 -0
  267. /package/dist/{tools-24GZHYRF.js.map → clipboard-manager-TEO2GEDN.js.map} +0 -0
  268. /package/dist/{whatsapp-VCRUPAO5.js.map → cron-explain-HHQKPD3M.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/integrations/spotify/auth.ts"],"sourcesContent":["/**\n * Spotify OAuth2 Authentication Module\n *\n * Handles OAuth2 flow, token management, and authenticated API requests\n */\n\nexport interface SpotifyAuthConfig {\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n}\n\nexport interface SpotifyTokens {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n scope: string;\n tokenType: string;\n}\n\nexport interface SpotifyTokenResponse {\n access_token: string;\n token_type: string;\n scope: string;\n expires_in: number;\n refresh_token?: string;\n}\n\nexport interface SpotifyUserProfile {\n id: string;\n display_name: string | null;\n email?: string;\n country?: string;\n product?: string;\n images?: Array<{\n url: string;\n height: number | null;\n width: number | null;\n }>;\n followers?: {\n total: number;\n };\n external_urls: {\n spotify: string;\n };\n uri: string;\n}\n\nexport interface SpotifyErrorResponse {\n error: {\n status: number;\n message: string;\n };\n}\n\nexport class SpotifyAuthError extends Error {\n public readonly statusCode?: number;\n public readonly spotifyError?: SpotifyErrorResponse[\"error\"];\n\n constructor(\n message: string,\n statusCode?: number,\n spotifyError?: SpotifyErrorResponse[\"error\"]\n ) {\n super(message);\n this.name = \"SpotifyAuthError\";\n this.statusCode = statusCode;\n this.spotifyError = spotifyError;\n }\n}\n\n/**\n * Available Spotify OAuth2 scopes\n */\nexport const SPOTIFY_SCOPES = {\n // Images\n UGC_IMAGE_UPLOAD: \"ugc-image-upload\",\n\n // Spotify Connect\n USER_READ_PLAYBACK_STATE: \"user-read-playback-state\",\n USER_MODIFY_PLAYBACK_STATE: \"user-modify-playback-state\",\n USER_READ_CURRENTLY_PLAYING: \"user-read-currently-playing\",\n\n // Playback\n STREAMING: \"streaming\",\n APP_REMOTE_CONTROL: \"app-remote-control\",\n\n // Users\n USER_READ_EMAIL: \"user-read-email\",\n USER_READ_PRIVATE: \"user-read-private\",\n\n // Follow\n USER_FOLLOW_READ: \"user-follow-read\",\n USER_FOLLOW_MODIFY: \"user-follow-modify\",\n\n // Library\n USER_LIBRARY_MODIFY: \"user-library-modify\",\n USER_LIBRARY_READ: \"user-library-read\",\n\n // Listening History\n USER_READ_PLAYBACK_POSITION: \"user-read-playback-position\",\n USER_TOP_READ: \"user-top-read\",\n USER_READ_RECENTLY_PLAYED: \"user-read-recently-played\",\n\n // Playlists\n PLAYLIST_MODIFY_PRIVATE: \"playlist-modify-private\",\n PLAYLIST_READ_COLLABORATIVE: \"playlist-read-collaborative\",\n PLAYLIST_READ_PRIVATE: \"playlist-read-private\",\n PLAYLIST_MODIFY_PUBLIC: \"playlist-modify-public\",\n} as const;\n\nexport type SpotifyScope = (typeof SPOTIFY_SCOPES)[keyof typeof SPOTIFY_SCOPES];\n\n/**\n * Default scopes for a full-featured Spotify integration\n */\nexport const DEFAULT_SCOPES: SpotifyScope[] = [\n SPOTIFY_SCOPES.USER_READ_PLAYBACK_STATE,\n SPOTIFY_SCOPES.USER_MODIFY_PLAYBACK_STATE,\n SPOTIFY_SCOPES.USER_READ_CURRENTLY_PLAYING,\n SPOTIFY_SCOPES.USER_READ_EMAIL,\n SPOTIFY_SCOPES.USER_READ_PRIVATE,\n SPOTIFY_SCOPES.USER_LIBRARY_MODIFY,\n SPOTIFY_SCOPES.USER_LIBRARY_READ,\n SPOTIFY_SCOPES.USER_TOP_READ,\n SPOTIFY_SCOPES.USER_READ_RECENTLY_PLAYED,\n SPOTIFY_SCOPES.PLAYLIST_MODIFY_PRIVATE,\n SPOTIFY_SCOPES.PLAYLIST_READ_COLLABORATIVE,\n SPOTIFY_SCOPES.PLAYLIST_READ_PRIVATE,\n SPOTIFY_SCOPES.PLAYLIST_MODIFY_PUBLIC,\n];\n\nconst SPOTIFY_ACCOUNTS_URL = \"https://accounts.spotify.com\";\nconst SPOTIFY_API_URL = \"https://api.spotify.com/v1\";\n\n/**\n * Spotify Authentication Client\n */\nexport class SpotifyAuth {\n private config: SpotifyAuthConfig;\n private tokens: SpotifyTokens | null = null;\n private tokenRefreshPromise: Promise<SpotifyTokens> | null = null;\n\n constructor(config: SpotifyAuthConfig) {\n this.config = config;\n }\n\n /**\n * Get the Base64 encoded client credentials\n */\n private getBasicAuthHeader(): string {\n const credentials = `${this.config.clientId}:${this.config.clientSecret}`;\n return `Basic ${Buffer.from(credentials).toString(\"base64\")}`;\n }\n\n /**\n * Generate the authorization URL for the OAuth2 flow\n */\n getAuthorizationUrl(\n scopes: SpotifyScope[] = DEFAULT_SCOPES,\n state?: string,\n showDialog = false\n ): string {\n const params = new URLSearchParams({\n client_id: this.config.clientId,\n response_type: \"code\",\n redirect_uri: this.config.redirectUri,\n scope: scopes.join(\" \"),\n show_dialog: String(showDialog),\n });\n\n if (state) {\n params.set(\"state\", state);\n }\n\n return `${SPOTIFY_ACCOUNTS_URL}/authorize?${params.toString()}`;\n }\n\n /**\n * Exchange an authorization code for tokens\n */\n async exchangeCode(code: string): Promise<SpotifyTokens> {\n const response = await fetch(`${SPOTIFY_ACCOUNTS_URL}/api/token`, {\n method: \"POST\",\n headers: {\n Authorization: this.getBasicAuthHeader(),\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: this.config.redirectUri,\n }),\n });\n\n if (!response.ok) {\n const error = await this.parseErrorResponse(response);\n throw new SpotifyAuthError(\n `Failed to exchange code: ${error.message}`,\n response.status,\n error\n );\n }\n\n const data: SpotifyTokenResponse = await response.json();\n this.tokens = this.parseTokenResponse(data);\n return this.tokens;\n }\n\n /**\n * Refresh the access token using the refresh token\n */\n async refreshAccessToken(refreshToken?: string): Promise<SpotifyTokens> {\n const tokenToRefresh = refreshToken ?? this.tokens?.refreshToken;\n\n if (!tokenToRefresh) {\n throw new SpotifyAuthError(\"No refresh token available\");\n }\n\n // Prevent concurrent refresh requests\n if (this.tokenRefreshPromise) {\n return this.tokenRefreshPromise;\n }\n\n this.tokenRefreshPromise = this.performTokenRefresh(tokenToRefresh);\n\n try {\n const tokens = await this.tokenRefreshPromise;\n return tokens;\n } finally {\n this.tokenRefreshPromise = null;\n }\n }\n\n private async performTokenRefresh(\n refreshToken: string\n ): Promise<SpotifyTokens> {\n const response = await fetch(`${SPOTIFY_ACCOUNTS_URL}/api/token`, {\n method: \"POST\",\n headers: {\n Authorization: this.getBasicAuthHeader(),\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n }),\n });\n\n if (!response.ok) {\n const error = await this.parseErrorResponse(response);\n throw new SpotifyAuthError(\n `Failed to refresh token: ${error.message}`,\n response.status,\n error\n );\n }\n\n const data: SpotifyTokenResponse = await response.json();\n\n // Keep the existing refresh token if a new one wasn't provided\n this.tokens = {\n ...this.parseTokenResponse(data),\n refreshToken: data.refresh_token ?? refreshToken,\n };\n\n return this.tokens;\n }\n\n /**\n * Parse the token response into our internal format\n */\n private parseTokenResponse(data: SpotifyTokenResponse): SpotifyTokens {\n return {\n accessToken: data.access_token,\n tokenType: data.token_type,\n scope: data.scope,\n expiresAt: Date.now() + data.expires_in * 1000,\n refreshToken: data.refresh_token ?? \"\",\n };\n }\n\n /**\n * Parse an error response from Spotify\n */\n private async parseErrorResponse(\n response: Response\n ): Promise<SpotifyErrorResponse[\"error\"]> {\n try {\n const data = await response.json();\n if (data.error) {\n return data.error;\n }\n return {\n status: response.status,\n message: data.error_description ?? response.statusText,\n };\n } catch {\n return {\n status: response.status,\n message: response.statusText,\n };\n }\n }\n\n /**\n * Check if the current access token is expired (or about to expire)\n */\n isTokenExpired(bufferMs = 60000): boolean {\n if (!this.tokens) {\n return true;\n }\n return Date.now() >= this.tokens.expiresAt - bufferMs;\n }\n\n /**\n * Get a valid access token, refreshing if necessary\n */\n async getAccessToken(): Promise<string> {\n if (!this.tokens) {\n throw new SpotifyAuthError(\"Not authenticated. Please authenticate first.\");\n }\n\n if (this.isTokenExpired()) {\n await this.refreshAccessToken();\n }\n\n return this.tokens!.accessToken;\n }\n\n /**\n * Get the current tokens\n */\n getTokens(): SpotifyTokens | null {\n return this.tokens;\n }\n\n /**\n * Set tokens (useful for restoring from storage)\n */\n setTokens(tokens: SpotifyTokens): void {\n this.tokens = tokens;\n }\n\n /**\n * Clear stored tokens\n */\n clearTokens(): void {\n this.tokens = null;\n }\n\n /**\n * Check if authenticated\n */\n isAuthenticated(): boolean {\n return this.tokens !== null && !!this.tokens.refreshToken;\n }\n\n /**\n * Make an authenticated request to the Spotify API\n */\n async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const accessToken = await this.getAccessToken();\n\n const url = endpoint.startsWith(\"http\")\n ? endpoint\n : `${SPOTIFY_API_URL}${endpoint}`;\n\n const response = await fetch(url, {\n ...options,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n });\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n if (!response.ok) {\n // Handle token expiration\n if (response.status === 401) {\n // Try refreshing the token once\n await this.refreshAccessToken();\n return this.request<T>(endpoint, options);\n }\n\n const error = await this.parseErrorResponse(response);\n throw new SpotifyAuthError(\n `API request failed: ${error.message}`,\n response.status,\n error\n );\n }\n\n const text = await response.text();\n if (!text) {\n return undefined as T;\n }\n\n return JSON.parse(text) as T;\n }\n\n /**\n * GET request helper\n */\n async get<T>(endpoint: string, params?: Record<string, string>): Promise<T> {\n let url = endpoint;\n if (params) {\n const searchParams = new URLSearchParams(params);\n url = `${endpoint}?${searchParams.toString()}`;\n }\n return this.request<T>(url, { method: \"GET\" });\n }\n\n /**\n * POST request helper\n */\n async post<T>(endpoint: string, body?: unknown): Promise<T> {\n return this.request<T>(endpoint, {\n method: \"POST\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n /**\n * PUT request helper\n */\n async put<T>(endpoint: string, body?: unknown): Promise<T> {\n return this.request<T>(endpoint, {\n method: \"PUT\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n /**\n * DELETE request helper\n */\n async delete<T>(endpoint: string, body?: unknown): Promise<T> {\n return this.request<T>(endpoint, {\n method: \"DELETE\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n /**\n * Get the current user's profile\n */\n async getCurrentUser(): Promise<SpotifyUserProfile> {\n return this.get<SpotifyUserProfile>(\"/me\");\n }\n}\n\n/**\n * Create a Spotify authentication client\n */\nexport function createSpotifyAuth(config: SpotifyAuthConfig): SpotifyAuth {\n return new SpotifyAuth(config);\n}\n\nexport default SpotifyAuth;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,91 @@
1
+ // src/tools/hash-tool.ts
2
+ import { createHash, randomBytes, timingSafeEqual } from "crypto";
3
+ import { createReadStream } from "fs";
4
+ function hashString(input, algorithm = "sha256") {
5
+ return createHash(algorithm).update(input, "utf8").digest("hex");
6
+ }
7
+ async function hashFile(filePath, algorithm = "sha256") {
8
+ return new Promise((resolve, reject) => {
9
+ const hash = createHash(algorithm);
10
+ const stream = createReadStream(filePath);
11
+ stream.on("data", (chunk) => hash.update(chunk));
12
+ stream.on("end", () => resolve(hash.digest("hex")));
13
+ stream.on("error", reject);
14
+ });
15
+ }
16
+ function compareHashes(hash1, hash2) {
17
+ if (hash1.length !== hash2.length) return false;
18
+ try {
19
+ return timingSafeEqual(Buffer.from(hash1, "hex"), Buffer.from(hash2, "hex"));
20
+ } catch {
21
+ return hash1 === hash2;
22
+ }
23
+ }
24
+ function generateToken(length = 32, encoding = "hex") {
25
+ const bytes = Math.ceil(length / 2);
26
+ const token = randomBytes(bytes);
27
+ switch (encoding) {
28
+ case "hex":
29
+ return token.toString("hex").slice(0, length);
30
+ case "base64":
31
+ return token.toString("base64").slice(0, length);
32
+ case "base64url":
33
+ return token.toString("base64url").slice(0, length);
34
+ default:
35
+ return token.toString("hex").slice(0, length);
36
+ }
37
+ }
38
+ function generateUUID() {
39
+ const bytes = randomBytes(16);
40
+ bytes[6] = bytes[6] & 15 | 64;
41
+ bytes[8] = bytes[8] & 63 | 128;
42
+ const hex = bytes.toString("hex");
43
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
44
+ }
45
+ function hashAll(input) {
46
+ return {
47
+ md5: hashString(input, "md5"),
48
+ sha1: hashString(input, "sha1"),
49
+ sha256: hashString(input, "sha256"),
50
+ sha512: hashString(input, "sha512")
51
+ };
52
+ }
53
+ async function hashTool(action, input, options) {
54
+ try {
55
+ const algorithm = options?.algorithm || "sha256";
56
+ switch (action) {
57
+ case "hash":
58
+ return { success: true, result: hashString(input, algorithm) };
59
+ case "hash_file":
60
+ return { success: true, result: await hashFile(input, algorithm) };
61
+ case "hash_all":
62
+ return { success: true, result: hashAll(input) };
63
+ case "compare": {
64
+ const other = options?.compare;
65
+ if (!other) return { success: false, error: "Missing 'compare' option" };
66
+ return { success: true, result: { match: compareHashes(input, other) } };
67
+ }
68
+ case "generate_token":
69
+ return { success: true, result: generateToken(options?.length || 32, options?.encoding || "hex") };
70
+ case "generate_uuid":
71
+ return { success: true, result: generateUUID() };
72
+ default:
73
+ return { success: false, error: `Unknown action: ${action}` };
74
+ }
75
+ } catch (error) {
76
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
77
+ }
78
+ }
79
+ var hash_tool_default = { hashTool, hashString, hashFile, compareHashes, generateToken, generateUUID, hashAll };
80
+
81
+ export {
82
+ hashString,
83
+ hashFile,
84
+ compareHashes,
85
+ generateToken,
86
+ generateUUID,
87
+ hashAll,
88
+ hashTool,
89
+ hash_tool_default
90
+ };
91
+ //# sourceMappingURL=chunk-PHDZKPNE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/hash-tool.ts"],"sourcesContent":["/**\r\n * Hash Tool\r\n * Compute hashes, compare values, generate tokens\r\n */\r\n\r\nimport { createHash, randomBytes, timingSafeEqual } from \"crypto\";\r\nimport { createReadStream } from \"fs\";\r\n\r\nexport interface HashResult {\r\n success: boolean;\r\n result?: unknown;\r\n error?: string;\r\n}\r\n\r\n// Hash a string with the specified algorithm\r\nexport function hashString(\r\n input: string,\r\n algorithm: \"md5\" | \"sha1\" | \"sha256\" | \"sha512\" = \"sha256\"\r\n): string {\r\n return createHash(algorithm).update(input, \"utf8\").digest(\"hex\");\r\n}\r\n\r\n// Hash a file with the specified algorithm\r\nexport async function hashFile(\r\n filePath: string,\r\n algorithm: \"md5\" | \"sha1\" | \"sha256\" | \"sha512\" = \"sha256\"\r\n): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const hash = createHash(algorithm);\r\n const stream = createReadStream(filePath);\r\n stream.on(\"data\", (chunk) => hash.update(chunk));\r\n stream.on(\"end\", () => resolve(hash.digest(\"hex\")));\r\n stream.on(\"error\", reject);\r\n });\r\n}\r\n\r\n// Compare two hashes (timing-safe)\r\nexport function compareHashes(hash1: string, hash2: string): boolean {\r\n if (hash1.length !== hash2.length) return false;\r\n try {\r\n return timingSafeEqual(Buffer.from(hash1, \"hex\"), Buffer.from(hash2, \"hex\"));\r\n } catch {\r\n return hash1 === hash2;\r\n }\r\n}\r\n\r\n// Generate a random token\r\nexport function generateToken(length: number = 32, encoding: \"hex\" | \"base64\" | \"base64url\" = \"hex\"): string {\r\n const bytes = Math.ceil(length / 2);\r\n const token = randomBytes(bytes);\r\n\r\n switch (encoding) {\r\n case \"hex\":\r\n return token.toString(\"hex\").slice(0, length);\r\n case \"base64\":\r\n return token.toString(\"base64\").slice(0, length);\r\n case \"base64url\":\r\n return token.toString(\"base64url\").slice(0, length);\r\n default:\r\n return token.toString(\"hex\").slice(0, length);\r\n }\r\n}\r\n\r\n// Generate a UUID v4\r\nexport function generateUUID(): string {\r\n const bytes = randomBytes(16);\r\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4\r\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 1\r\n\r\n const hex = bytes.toString(\"hex\");\r\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\r\n}\r\n\r\n// Compute multiple hashes at once\r\nexport function hashAll(input: string): Record<string, string> {\r\n return {\r\n md5: hashString(input, \"md5\"),\r\n sha1: hashString(input, \"sha1\"),\r\n sha256: hashString(input, \"sha256\"),\r\n sha512: hashString(input, \"sha512\"),\r\n };\r\n}\r\n\r\n// Main entry point\r\nexport async function hashTool(\r\n action: string,\r\n input: string,\r\n options?: Record<string, unknown>\r\n): Promise<HashResult> {\r\n try {\r\n const algorithm = (options?.algorithm as string || \"sha256\") as \"md5\" | \"sha1\" | \"sha256\" | \"sha512\";\r\n\r\n switch (action) {\r\n case \"hash\":\r\n return { success: true, result: hashString(input, algorithm) };\r\n case \"hash_file\":\r\n return { success: true, result: await hashFile(input, algorithm) };\r\n case \"hash_all\":\r\n return { success: true, result: hashAll(input) };\r\n case \"compare\": {\r\n const other = options?.compare as string;\r\n if (!other) return { success: false, error: \"Missing 'compare' option\" };\r\n return { success: true, result: { match: compareHashes(input, other) } };\r\n }\r\n case \"generate_token\":\r\n return { success: true, result: generateToken((options?.length as number) || 32, (options?.encoding as any) || \"hex\") };\r\n case \"generate_uuid\":\r\n return { success: true, result: generateUUID() };\r\n default:\r\n return { success: false, error: `Unknown action: ${action}` };\r\n }\r\n } catch (error) {\r\n return { success: false, error: error instanceof Error ? error.message : String(error) };\r\n }\r\n}\r\n\r\nexport default { hashTool, hashString, hashFile, compareHashes, generateToken, generateUUID, hashAll };\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,49 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x + '" is not supported');
12
+ });
13
+ var __esm = (fn, res) => function __init() {
14
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ };
16
+ var __commonJS = (cb, mod) => function __require2() {
17
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, { get: all[name], enumerable: true });
22
+ };
23
+ var __copyProps = (to, from, except, desc) => {
24
+ if (from && typeof from === "object" || typeof from === "function") {
25
+ for (let key of __getOwnPropNames(from))
26
+ if (!__hasOwnProp.call(to, key) && key !== except)
27
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28
+ }
29
+ return to;
30
+ };
31
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32
+ // If the importer is in node compatibility mode or this is not an ESM
33
+ // file that has been converted to a CommonJS file using a Babel-
34
+ // compatible transform (i.e. "__esModule" has not been set), then set
35
+ // "default" to the CommonJS "module.exports" for node compatibility.
36
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37
+ mod
38
+ ));
39
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
+
41
+ export {
42
+ __require,
43
+ __esm,
44
+ __commonJS,
45
+ __export,
46
+ __toESM,
47
+ __toCommonJS
48
+ };
49
+ //# sourceMappingURL=chunk-PLDDJCW6.js.map
@@ -0,0 +1,164 @@
1
+ // src/tools/text-transform.ts
2
+ function countText(text) {
3
+ const characters = text.length;
4
+ const words = text.trim() ? text.trim().split(/\s+/).length : 0;
5
+ const sentences = text.split(/[.!?]+/).filter((s) => s.trim()).length;
6
+ const paragraphs = text.split(/\n\s*\n/).filter((p) => p.trim()).length;
7
+ const lines = text.split("\n").length;
8
+ return { characters, words, sentences, paragraphs, lines };
9
+ }
10
+ function detectLanguage(text) {
11
+ const sample = text.slice(0, 500).toLowerCase();
12
+ if (/[\u4e00-\u9fff]/.test(sample)) return "zh";
13
+ if (/[\u3040-\u309f\u30a0-\u30ff]/.test(sample)) return "ja";
14
+ if (/[\uac00-\ud7af]/.test(sample)) return "ko";
15
+ if (/[\u0600-\u06ff]/.test(sample)) return "ar";
16
+ if (/[\u0400-\u04ff]/.test(sample)) return "ru";
17
+ if (/[\u0900-\u097f]/.test(sample)) return "hi";
18
+ const wordFreq = {
19
+ "the,and,is,in,to,of,a,for": "en",
20
+ "de,la,el,en,es,que,un,los": "es",
21
+ "de,le,la,les,des,un,une,et": "fr",
22
+ "der,die,das,und,ist,ein,den,von": "de",
23
+ "di,il,la,che,in,un,per,del": "it",
24
+ "de,o,a,que,em,um,do,da": "pt"
25
+ };
26
+ let bestMatch = "en";
27
+ let bestScore = 0;
28
+ for (const [words, lang] of Object.entries(wordFreq)) {
29
+ const langWords = words.split(",");
30
+ const score = langWords.filter((w) => sample.includes(` ${w} `)).length;
31
+ if (score > bestScore) {
32
+ bestScore = score;
33
+ bestMatch = lang;
34
+ }
35
+ }
36
+ return bestMatch;
37
+ }
38
+ function extractKeywords(text, count = 10) {
39
+ const stopWords = /* @__PURE__ */ new Set([
40
+ "the",
41
+ "a",
42
+ "an",
43
+ "and",
44
+ "or",
45
+ "but",
46
+ "in",
47
+ "on",
48
+ "at",
49
+ "to",
50
+ "for",
51
+ "of",
52
+ "with",
53
+ "by",
54
+ "from",
55
+ "is",
56
+ "are",
57
+ "was",
58
+ "were",
59
+ "be",
60
+ "been",
61
+ "have",
62
+ "has",
63
+ "had",
64
+ "do",
65
+ "does",
66
+ "did",
67
+ "will",
68
+ "would",
69
+ "could",
70
+ "should",
71
+ "may",
72
+ "might",
73
+ "can",
74
+ "this",
75
+ "that",
76
+ "these",
77
+ "those",
78
+ "it",
79
+ "its",
80
+ "i",
81
+ "you",
82
+ "he",
83
+ "she",
84
+ "we",
85
+ "they",
86
+ "not",
87
+ "no"
88
+ ]);
89
+ const words = text.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 2 && !stopWords.has(w));
90
+ const freq = /* @__PURE__ */ new Map();
91
+ for (const word of words) {
92
+ freq.set(word, (freq.get(word) || 0) + 1);
93
+ }
94
+ return Array.from(freq.entries()).sort((a, b) => b[1] - a[1]).slice(0, count).map(([word]) => word);
95
+ }
96
+ function changeCase(text, targetCase) {
97
+ switch (targetCase) {
98
+ case "upper":
99
+ return text.toUpperCase();
100
+ case "lower":
101
+ return text.toLowerCase();
102
+ case "title":
103
+ return text.replace(/\b\w/g, (c) => c.toUpperCase());
104
+ case "sentence":
105
+ return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
106
+ case "camel":
107
+ return text.toLowerCase().replace(/[^a-z0-9]+(.)/g, (_, c) => c.toUpperCase());
108
+ case "snake":
109
+ return text.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
110
+ case "kebab":
111
+ return text.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
112
+ default:
113
+ return text;
114
+ }
115
+ }
116
+ function truncate(text, maxLength, suffix = "...") {
117
+ if (text.length <= maxLength) return text;
118
+ return text.slice(0, maxLength - suffix.length) + suffix;
119
+ }
120
+ function deduplicateLines(text) {
121
+ const lines = text.split("\n");
122
+ const seen = /* @__PURE__ */ new Set();
123
+ return lines.filter((line) => {
124
+ const trimmed = line.trim();
125
+ if (seen.has(trimmed)) return false;
126
+ seen.add(trimmed);
127
+ return true;
128
+ }).join("\n");
129
+ }
130
+ async function transformText(text, action, options) {
131
+ try {
132
+ switch (action) {
133
+ case "count":
134
+ return { success: true, result: countText(text) };
135
+ case "detect_language":
136
+ return { success: true, result: { language: detectLanguage(text) } };
137
+ case "extract_keywords":
138
+ return { success: true, result: extractKeywords(text, options?.count || 10) };
139
+ case "change_case":
140
+ return { success: true, result: changeCase(text, options?.target_case || "lower") };
141
+ case "truncate":
142
+ return { success: true, result: truncate(text, options?.max_length || 100) };
143
+ case "deduplicate":
144
+ return { success: true, result: deduplicateLines(text) };
145
+ default:
146
+ return { success: false, error: `Unknown action: ${action}` };
147
+ }
148
+ } catch (error) {
149
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
150
+ }
151
+ }
152
+ var text_transform_default = { transformText, countText, detectLanguage, extractKeywords, changeCase, truncate, deduplicateLines };
153
+
154
+ export {
155
+ countText,
156
+ detectLanguage,
157
+ extractKeywords,
158
+ changeCase,
159
+ truncate,
160
+ deduplicateLines,
161
+ transformText,
162
+ text_transform_default
163
+ };
164
+ //# sourceMappingURL=chunk-PTGTGXV2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/text-transform.ts"],"sourcesContent":["/**\r\n * Text Transform Tool\r\n * Text manipulation utilities: word count, language detection, keyword extraction, etc.\r\n */\r\n\r\nexport interface TextTransformResult {\r\n success: boolean;\r\n result?: unknown;\r\n error?: string;\r\n}\r\n\r\n// Word and character count\r\nexport function countText(text: string): {\r\n characters: number;\r\n words: number;\r\n sentences: number;\r\n paragraphs: number;\r\n lines: number;\r\n} {\r\n const characters = text.length;\r\n const words = text.trim() ? text.trim().split(/\\s+/).length : 0;\r\n const sentences = text.split(/[.!?]+/).filter((s) => s.trim()).length;\r\n const paragraphs = text.split(/\\n\\s*\\n/).filter((p) => p.trim()).length;\r\n const lines = text.split(\"\\n\").length;\r\n\r\n return { characters, words, sentences, paragraphs, lines };\r\n}\r\n\r\n// Simple language detection based on character ranges and common words\r\nexport function detectLanguage(text: string): string {\r\n const sample = text.slice(0, 500).toLowerCase();\r\n\r\n // Check for CJK characters\r\n if (/[\\u4e00-\\u9fff]/.test(sample)) return \"zh\"; // Chinese\r\n if (/[\\u3040-\\u309f\\u30a0-\\u30ff]/.test(sample)) return \"ja\"; // Japanese\r\n if (/[\\uac00-\\ud7af]/.test(sample)) return \"ko\"; // Korean\r\n if (/[\\u0600-\\u06ff]/.test(sample)) return \"ar\"; // Arabic\r\n if (/[\\u0400-\\u04ff]/.test(sample)) return \"ru\"; // Russian/Cyrillic\r\n if (/[\\u0900-\\u097f]/.test(sample)) return \"hi\"; // Hindi\r\n\r\n // Latin-based language detection by common words\r\n const wordFreq: Record<string, string> = {\r\n \"the,and,is,in,to,of,a,for\": \"en\",\r\n \"de,la,el,en,es,que,un,los\": \"es\",\r\n \"de,le,la,les,des,un,une,et\": \"fr\",\r\n \"der,die,das,und,ist,ein,den,von\": \"de\",\r\n \"di,il,la,che,in,un,per,del\": \"it\",\r\n \"de,o,a,que,em,um,do,da\": \"pt\",\r\n };\r\n\r\n let bestMatch = \"en\";\r\n let bestScore = 0;\r\n\r\n for (const [words, lang] of Object.entries(wordFreq)) {\r\n const langWords = words.split(\",\");\r\n const score = langWords.filter((w) => sample.includes(` ${w} `)).length;\r\n if (score > bestScore) {\r\n bestScore = score;\r\n bestMatch = lang;\r\n }\r\n }\r\n\r\n return bestMatch;\r\n}\r\n\r\n// Extract keywords (simple TF-based approach)\r\nexport function extractKeywords(text: string, count: number = 10): string[] {\r\n const stopWords = new Set([\r\n \"the\", \"a\", \"an\", \"and\", \"or\", \"but\", \"in\", \"on\", \"at\", \"to\", \"for\",\r\n \"of\", \"with\", \"by\", \"from\", \"is\", \"are\", \"was\", \"were\", \"be\", \"been\",\r\n \"have\", \"has\", \"had\", \"do\", \"does\", \"did\", \"will\", \"would\", \"could\",\r\n \"should\", \"may\", \"might\", \"can\", \"this\", \"that\", \"these\", \"those\",\r\n \"it\", \"its\", \"i\", \"you\", \"he\", \"she\", \"we\", \"they\", \"not\", \"no\",\r\n ]);\r\n\r\n const words = text\r\n .toLowerCase()\r\n .replace(/[^a-z0-9\\s]/g, \"\")\r\n .split(/\\s+/)\r\n .filter((w) => w.length > 2 && !stopWords.has(w));\r\n\r\n const freq = new Map<string, number>();\r\n for (const word of words) {\r\n freq.set(word, (freq.get(word) || 0) + 1);\r\n }\r\n\r\n return Array.from(freq.entries())\r\n .sort((a, b) => b[1] - a[1])\r\n .slice(0, count)\r\n .map(([word]) => word);\r\n}\r\n\r\n// Change text case\r\nexport function changeCase(\r\n text: string,\r\n targetCase: \"upper\" | \"lower\" | \"title\" | \"sentence\" | \"camel\" | \"snake\" | \"kebab\"\r\n): string {\r\n switch (targetCase) {\r\n case \"upper\":\r\n return text.toUpperCase();\r\n case \"lower\":\r\n return text.toLowerCase();\r\n case \"title\":\r\n return text.replace(/\\b\\w/g, (c) => c.toUpperCase());\r\n case \"sentence\":\r\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\r\n case \"camel\":\r\n return text\r\n .toLowerCase()\r\n .replace(/[^a-z0-9]+(.)/g, (_, c) => c.toUpperCase());\r\n case \"snake\":\r\n return text\r\n .replace(/([a-z])([A-Z])/g, \"$1_$2\")\r\n .replace(/[\\s-]+/g, \"_\")\r\n .toLowerCase();\r\n case \"kebab\":\r\n return text\r\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\r\n .replace(/[\\s_]+/g, \"-\")\r\n .toLowerCase();\r\n default:\r\n return text;\r\n }\r\n}\r\n\r\n// Truncate text with ellipsis\r\nexport function truncate(text: string, maxLength: number, suffix: string = \"...\"): string {\r\n if (text.length <= maxLength) return text;\r\n return text.slice(0, maxLength - suffix.length) + suffix;\r\n}\r\n\r\n// Remove duplicate lines\r\nexport function deduplicateLines(text: string): string {\r\n const lines = text.split(\"\\n\");\r\n const seen = new Set<string>();\r\n return lines\r\n .filter((line) => {\r\n const trimmed = line.trim();\r\n if (seen.has(trimmed)) return false;\r\n seen.add(trimmed);\r\n return true;\r\n })\r\n .join(\"\\n\");\r\n}\r\n\r\n// Main entry point for the tool\r\nexport async function transformText(\r\n text: string,\r\n action: string,\r\n options?: Record<string, unknown>\r\n): Promise<TextTransformResult> {\r\n try {\r\n switch (action) {\r\n case \"count\":\r\n return { success: true, result: countText(text) };\r\n case \"detect_language\":\r\n return { success: true, result: { language: detectLanguage(text) } };\r\n case \"extract_keywords\":\r\n return { success: true, result: extractKeywords(text, (options?.count as number) || 10) };\r\n case \"change_case\":\r\n return { success: true, result: changeCase(text, (options?.target_case as string || \"lower\") as any) };\r\n case \"truncate\":\r\n return { success: true, result: truncate(text, (options?.max_length as number) || 100) };\r\n case \"deduplicate\":\r\n return { success: true, result: deduplicateLines(text) };\r\n default:\r\n return { success: false, error: `Unknown action: ${action}` };\r\n }\r\n } catch (error) {\r\n return { success: false, error: error instanceof Error ? error.message : String(error) };\r\n }\r\n}\r\n\r\nexport default { transformText, countText, detectLanguage, extractKeywords, changeCase, truncate, deduplicateLines };\r\n"],"mappings":";AAYO,SAAS,UAAU,MAMxB;AACA,QAAM,aAAa,KAAK;AACxB,QAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,SAAS;AAC9D,QAAM,YAAY,KAAK,MAAM,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;AAC/D,QAAM,aAAa,KAAK,MAAM,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;AACjE,QAAM,QAAQ,KAAK,MAAM,IAAI,EAAE;AAE/B,SAAO,EAAE,YAAY,OAAO,WAAW,YAAY,MAAM;AAC3D;AAGO,SAAS,eAAe,MAAsB;AACnD,QAAM,SAAS,KAAK,MAAM,GAAG,GAAG,EAAE,YAAY;AAG9C,MAAI,kBAAkB,KAAK,MAAM,EAAG,QAAO;AAC3C,MAAI,+BAA+B,KAAK,MAAM,EAAG,QAAO;AACxD,MAAI,kBAAkB,KAAK,MAAM,EAAG,QAAO;AAC3C,MAAI,kBAAkB,KAAK,MAAM,EAAG,QAAO;AAC3C,MAAI,kBAAkB,KAAK,MAAM,EAAG,QAAO;AAC3C,MAAI,kBAAkB,KAAK,MAAM,EAAG,QAAO;AAG3C,QAAM,WAAmC;AAAA,IACvC,6BAA6B;AAAA,IAC7B,6BAA6B;AAAA,IAC7B,8BAA8B;AAAA,IAC9B,mCAAmC;AAAA,IACnC,8BAA8B;AAAA,IAC9B,0BAA0B;AAAA,EAC5B;AAEA,MAAI,YAAY;AAChB,MAAI,YAAY;AAEhB,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACpD,UAAM,YAAY,MAAM,MAAM,GAAG;AACjC,UAAM,QAAQ,UAAU,OAAO,CAAC,MAAM,OAAO,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE;AACjE,QAAI,QAAQ,WAAW;AACrB,kBAAY;AACZ,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,gBAAgB,MAAc,QAAgB,IAAc;AAC1E,QAAM,YAAY,oBAAI,IAAI;AAAA,IACxB;AAAA,IAAO;AAAA,IAAK;AAAA,IAAM;AAAA,IAAO;AAAA,IAAM;AAAA,IAAO;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAC9D;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAM;AAAA,IAAO;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAM;AAAA,IAC9D;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAO;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAS;AAAA,IAC5D;AAAA,IAAU;AAAA,IAAO;AAAA,IAAS;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAS;AAAA,IAC1D;AAAA,IAAM;AAAA,IAAO;AAAA,IAAK;AAAA,IAAO;AAAA,IAAM;AAAA,IAAO;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAO;AAAA,EAC7D,CAAC;AAED,QAAM,QAAQ,KACX,YAAY,EACZ,QAAQ,gBAAgB,EAAE,EAC1B,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;AAElD,QAAM,OAAO,oBAAI,IAAoB;AACrC,aAAW,QAAQ,OAAO;AACxB,SAAK,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EAC1C;AAEA,SAAO,MAAM,KAAK,KAAK,QAAQ,CAAC,EAC7B,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,MAAM,GAAG,KAAK,EACd,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AACzB;AAGO,SAAS,WACd,MACA,YACQ;AACR,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,aAAO,KAAK,YAAY;AAAA,IAC1B,KAAK;AACH,aAAO,KAAK,YAAY;AAAA,IAC1B,KAAK;AACH,aAAO,KAAK,QAAQ,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,IACrD,KAAK;AACH,aAAO,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY;AAAA,IAClE,KAAK;AACH,aAAO,KACJ,YAAY,EACZ,QAAQ,kBAAkB,CAAC,GAAG,MAAM,EAAE,YAAY,CAAC;AAAA,IACxD,KAAK;AACH,aAAO,KACJ,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,WAAW,GAAG,EACtB,YAAY;AAAA,IACjB,KAAK;AACH,aAAO,KACJ,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,WAAW,GAAG,EACtB,YAAY;AAAA,IACjB;AACE,aAAO;AAAA,EACX;AACF;AAGO,SAAS,SAAS,MAAc,WAAmB,SAAiB,OAAe;AACxF,MAAI,KAAK,UAAU,UAAW,QAAO;AACrC,SAAO,KAAK,MAAM,GAAG,YAAY,OAAO,MAAM,IAAI;AACpD;AAGO,SAAS,iBAAiB,MAAsB;AACrD,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,MACJ,OAAO,CAAC,SAAS;AAChB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,KAAK,IAAI,OAAO,EAAG,QAAO;AAC9B,SAAK,IAAI,OAAO;AAChB,WAAO;AAAA,EACT,CAAC,EACA,KAAK,IAAI;AACd;AAGA,eAAsB,cACpB,MACA,QACA,SAC8B;AAC9B,MAAI;AACF,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO,EAAE,SAAS,MAAM,QAAQ,UAAU,IAAI,EAAE;AAAA,MAClD,KAAK;AACH,eAAO,EAAE,SAAS,MAAM,QAAQ,EAAE,UAAU,eAAe,IAAI,EAAE,EAAE;AAAA,MACrE,KAAK;AACH,eAAO,EAAE,SAAS,MAAM,QAAQ,gBAAgB,MAAO,SAAS,SAAoB,EAAE,EAAE;AAAA,MAC1F,KAAK;AACH,eAAO,EAAE,SAAS,MAAM,QAAQ,WAAW,MAAO,SAAS,eAAyB,OAAe,EAAE;AAAA,MACvG,KAAK;AACH,eAAO,EAAE,SAAS,MAAM,QAAQ,SAAS,MAAO,SAAS,cAAyB,GAAG,EAAE;AAAA,MACzF,KAAK;AACH,eAAO,EAAE,SAAS,MAAM,QAAQ,iBAAiB,IAAI,EAAE;AAAA,MACzD;AACE,eAAO,EAAE,SAAS,OAAO,OAAO,mBAAmB,MAAM,GAAG;AAAA,IAChE;AAAA,EACF,SAAS,OAAO;AACd,WAAO,EAAE,SAAS,OAAO,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AAAA,EACzF;AACF;AAEA,IAAO,yBAAQ,EAAE,eAAe,WAAW,gBAAgB,iBAAiB,YAAY,UAAU,iBAAiB;","names":[]}
@@ -0,0 +1,171 @@
1
+ // src/tools/unit-converter.ts
2
+ var LENGTH = {
3
+ // Base: meters
4
+ mm: { toBase: 1e-3 },
5
+ cm: { toBase: 0.01 },
6
+ m: { toBase: 1 },
7
+ km: { toBase: 1e3 },
8
+ in: { toBase: 0.0254 },
9
+ ft: { toBase: 0.3048 },
10
+ yd: { toBase: 0.9144 },
11
+ mi: { toBase: 1609.344 },
12
+ nm: { toBase: 1852 }
13
+ };
14
+ var WEIGHT = {
15
+ // Base: grams
16
+ mg: { toBase: 1e-3 },
17
+ g: { toBase: 1 },
18
+ kg: { toBase: 1e3 },
19
+ t: { toBase: 1e6 },
20
+ oz: { toBase: 28.3495 },
21
+ lb: { toBase: 453.592 },
22
+ st: { toBase: 6350.29 }
23
+ };
24
+ var VOLUME = {
25
+ // Base: liters
26
+ ml: { toBase: 1e-3 },
27
+ l: { toBase: 1 },
28
+ gal: { toBase: 3.78541 },
29
+ qt: { toBase: 0.946353 },
30
+ pt: { toBase: 0.473176 },
31
+ cup: { toBase: 0.236588 },
32
+ floz: { toBase: 0.0295735 },
33
+ tbsp: { toBase: 0.0147868 },
34
+ tsp: { toBase: 492892e-8 }
35
+ };
36
+ var DATA_SIZE = {
37
+ // Base: bytes
38
+ b: { toBase: 1 },
39
+ kb: { toBase: 1024 },
40
+ mb: { toBase: 1048576 },
41
+ gb: { toBase: 1073741824 },
42
+ tb: { toBase: 1099511627776 },
43
+ pb: { toBase: 1125899906842624 },
44
+ bit: { toBase: 0.125 },
45
+ kbit: { toBase: 128 },
46
+ mbit: { toBase: 131072 },
47
+ gbit: { toBase: 134217728 }
48
+ };
49
+ var TIME = {
50
+ // Base: seconds
51
+ ms: { toBase: 1e-3 },
52
+ s: { toBase: 1 },
53
+ min: { toBase: 60 },
54
+ hr: { toBase: 3600 },
55
+ day: { toBase: 86400 },
56
+ week: { toBase: 604800 },
57
+ month: { toBase: 2592e3 },
58
+ year: { toBase: 31536e3 }
59
+ };
60
+ var SPEED = {
61
+ // Base: m/s
62
+ "m/s": { toBase: 1 },
63
+ "km/h": { toBase: 0.277778 },
64
+ mph: { toBase: 0.44704 },
65
+ knot: { toBase: 0.514444 },
66
+ "ft/s": { toBase: 0.3048 }
67
+ };
68
+ var CATEGORIES = {
69
+ length: LENGTH,
70
+ weight: WEIGHT,
71
+ volume: VOLUME,
72
+ data: DATA_SIZE,
73
+ time: TIME,
74
+ speed: SPEED
75
+ };
76
+ function convertTemperature(value, from, to) {
77
+ let celsius;
78
+ switch (from.toLowerCase()) {
79
+ case "c":
80
+ case "celsius":
81
+ celsius = value;
82
+ break;
83
+ case "f":
84
+ case "fahrenheit":
85
+ celsius = (value - 32) * 5 / 9;
86
+ break;
87
+ case "k":
88
+ case "kelvin":
89
+ celsius = value - 273.15;
90
+ break;
91
+ default:
92
+ throw new Error(`Unknown temperature unit: ${from}`);
93
+ }
94
+ switch (to.toLowerCase()) {
95
+ case "c":
96
+ case "celsius":
97
+ return celsius;
98
+ case "f":
99
+ case "fahrenheit":
100
+ return celsius * 9 / 5 + 32;
101
+ case "k":
102
+ case "kelvin":
103
+ return celsius + 273.15;
104
+ default:
105
+ throw new Error(`Unknown temperature unit: ${to}`);
106
+ }
107
+ }
108
+ function convertUnit(value, from, to, conversionMap) {
109
+ const fromFactor = conversionMap[from.toLowerCase()];
110
+ const toFactor = conversionMap[to.toLowerCase()];
111
+ if (!fromFactor) throw new Error(`Unknown unit: ${from}`);
112
+ if (!toFactor) throw new Error(`Unknown unit: ${to}`);
113
+ const baseValue = value * fromFactor.toBase;
114
+ return baseValue / toFactor.toBase;
115
+ }
116
+ function detectCategory(unit) {
117
+ const lower = unit.toLowerCase();
118
+ if (["c", "f", "k", "celsius", "fahrenheit", "kelvin"].includes(lower)) return "temperature";
119
+ for (const [category, map] of Object.entries(CATEGORIES)) {
120
+ if (lower in map) return category;
121
+ }
122
+ return null;
123
+ }
124
+ function listUnits(category) {
125
+ if (category) {
126
+ if (category === "temperature") return { temperature: ["C", "F", "K"] };
127
+ const map = CATEGORIES[category];
128
+ return map ? { [category]: Object.keys(map) } : {};
129
+ }
130
+ const result = { temperature: ["C", "F", "K"] };
131
+ for (const [cat, map] of Object.entries(CATEGORIES)) {
132
+ result[cat] = Object.keys(map);
133
+ }
134
+ return result;
135
+ }
136
+ function convert(value, from, to) {
137
+ try {
138
+ const category = detectCategory(from);
139
+ if (!category) {
140
+ return { success: false, error: `Unknown unit: ${from}. Use listUnits() to see available units.` };
141
+ }
142
+ let result;
143
+ if (category === "temperature") {
144
+ result = convertTemperature(value, from, to);
145
+ } else {
146
+ result = convertUnit(value, from, to, CATEGORIES[category]);
147
+ }
148
+ const formatted = result < 0.01 || result > 1e6 ? result.toExponential(4) : Number(result.toPrecision(8)).toString();
149
+ return {
150
+ success: true,
151
+ result: { value: result, from, to, formatted: `${value} ${from} = ${formatted} ${to}` }
152
+ };
153
+ } catch (error) {
154
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
155
+ }
156
+ }
157
+ async function unitConverter(action, value, from, to) {
158
+ if (action === "list") {
159
+ return { success: true, result: listUnits(from) };
160
+ }
161
+ return convert(value, from, to);
162
+ }
163
+ var unit_converter_default = { convert, listUnits, unitConverter };
164
+
165
+ export {
166
+ listUnits,
167
+ convert,
168
+ unitConverter,
169
+ unit_converter_default
170
+ };
171
+ //# sourceMappingURL=chunk-REMIY4U2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/unit-converter.ts"],"sourcesContent":["/**\r\n * Unit Converter Tool\r\n * Convert between units of measurement\r\n */\r\n\r\nexport interface ConversionResult {\r\n success: boolean;\r\n result?: { value: number; from: string; to: string; formatted: string };\r\n error?: string;\r\n}\r\n\r\ntype ConversionMap = Record<string, Record<string, number>>;\r\n\r\n// All values are conversion factors to the base unit\r\nconst LENGTH: ConversionMap = {\r\n // Base: meters\r\n mm: { toBase: 0.001 }, cm: { toBase: 0.01 }, m: { toBase: 1 }, km: { toBase: 1000 },\r\n in: { toBase: 0.0254 }, ft: { toBase: 0.3048 }, yd: { toBase: 0.9144 }, mi: { toBase: 1609.344 },\r\n nm: { toBase: 1852 },\r\n};\r\n\r\nconst WEIGHT: ConversionMap = {\r\n // Base: grams\r\n mg: { toBase: 0.001 }, g: { toBase: 1 }, kg: { toBase: 1000 }, t: { toBase: 1000000 },\r\n oz: { toBase: 28.3495 }, lb: { toBase: 453.592 }, st: { toBase: 6350.29 },\r\n};\r\n\r\nconst VOLUME: ConversionMap = {\r\n // Base: liters\r\n ml: { toBase: 0.001 }, l: { toBase: 1 }, gal: { toBase: 3.78541 },\r\n qt: { toBase: 0.946353 }, pt: { toBase: 0.473176 }, cup: { toBase: 0.236588 },\r\n floz: { toBase: 0.0295735 }, tbsp: { toBase: 0.0147868 }, tsp: { toBase: 0.00492892 },\r\n};\r\n\r\nconst DATA_SIZE: ConversionMap = {\r\n // Base: bytes\r\n b: { toBase: 1 }, kb: { toBase: 1024 }, mb: { toBase: 1048576 }, gb: { toBase: 1073741824 },\r\n tb: { toBase: 1099511627776 }, pb: { toBase: 1125899906842624 },\r\n bit: { toBase: 0.125 }, kbit: { toBase: 128 }, mbit: { toBase: 131072 }, gbit: { toBase: 134217728 },\r\n};\r\n\r\nconst TIME: ConversionMap = {\r\n // Base: seconds\r\n ms: { toBase: 0.001 }, s: { toBase: 1 }, min: { toBase: 60 }, hr: { toBase: 3600 },\r\n day: { toBase: 86400 }, week: { toBase: 604800 }, month: { toBase: 2592000 }, year: { toBase: 31536000 },\r\n};\r\n\r\nconst SPEED: ConversionMap = {\r\n // Base: m/s\r\n \"m/s\": { toBase: 1 }, \"km/h\": { toBase: 0.277778 }, mph: { toBase: 0.44704 },\r\n knot: { toBase: 0.514444 }, \"ft/s\": { toBase: 0.3048 },\r\n};\r\n\r\nconst CATEGORIES: Record<string, ConversionMap> = {\r\n length: LENGTH,\r\n weight: WEIGHT,\r\n volume: VOLUME,\r\n data: DATA_SIZE,\r\n time: TIME,\r\n speed: SPEED,\r\n};\r\n\r\n// Temperature conversion (special case - not multiplicative)\r\nfunction convertTemperature(value: number, from: string, to: string): number {\r\n // Convert to Celsius first\r\n let celsius: number;\r\n switch (from.toLowerCase()) {\r\n case \"c\": case \"celsius\": celsius = value; break;\r\n case \"f\": case \"fahrenheit\": celsius = (value - 32) * 5 / 9; break;\r\n case \"k\": case \"kelvin\": celsius = value - 273.15; break;\r\n default: throw new Error(`Unknown temperature unit: ${from}`);\r\n }\r\n\r\n // Convert from Celsius to target\r\n switch (to.toLowerCase()) {\r\n case \"c\": case \"celsius\": return celsius;\r\n case \"f\": case \"fahrenheit\": return celsius * 9 / 5 + 32;\r\n case \"k\": case \"kelvin\": return celsius + 273.15;\r\n default: throw new Error(`Unknown temperature unit: ${to}`);\r\n }\r\n}\r\n\r\n// Generic unit conversion\r\nfunction convertUnit(value: number, from: string, to: string, conversionMap: ConversionMap): number {\r\n const fromFactor = conversionMap[from.toLowerCase()];\r\n const toFactor = conversionMap[to.toLowerCase()];\r\n\r\n if (!fromFactor) throw new Error(`Unknown unit: ${from}`);\r\n if (!toFactor) throw new Error(`Unknown unit: ${to}`);\r\n\r\n const baseValue = value * fromFactor.toBase;\r\n return baseValue / toFactor.toBase;\r\n}\r\n\r\n// Detect which category a unit belongs to\r\nfunction detectCategory(unit: string): string | null {\r\n const lower = unit.toLowerCase();\r\n if ([\"c\", \"f\", \"k\", \"celsius\", \"fahrenheit\", \"kelvin\"].includes(lower)) return \"temperature\";\r\n\r\n for (const [category, map] of Object.entries(CATEGORIES)) {\r\n if (lower in map) return category;\r\n }\r\n return null;\r\n}\r\n\r\n// List available units for a category\r\nexport function listUnits(category?: string): Record<string, string[]> {\r\n if (category) {\r\n if (category === \"temperature\") return { temperature: [\"C\", \"F\", \"K\"] };\r\n const map = CATEGORIES[category];\r\n return map ? { [category]: Object.keys(map) } : {};\r\n }\r\n\r\n const result: Record<string, string[]> = { temperature: [\"C\", \"F\", \"K\"] };\r\n for (const [cat, map] of Object.entries(CATEGORIES)) {\r\n result[cat] = Object.keys(map);\r\n }\r\n return result;\r\n}\r\n\r\n// Main conversion function\r\nexport function convert(value: number, from: string, to: string): ConversionResult {\r\n try {\r\n const category = detectCategory(from);\r\n if (!category) {\r\n return { success: false, error: `Unknown unit: ${from}. Use listUnits() to see available units.` };\r\n }\r\n\r\n let result: number;\r\n if (category === \"temperature\") {\r\n result = convertTemperature(value, from, to);\r\n } else {\r\n result = convertUnit(value, from, to, CATEGORIES[category]);\r\n }\r\n\r\n // Smart formatting\r\n const formatted = result < 0.01 || result > 1000000\r\n ? result.toExponential(4)\r\n : Number(result.toPrecision(8)).toString();\r\n\r\n return {\r\n success: true,\r\n result: { value: result, from, to, formatted: `${value} ${from} = ${formatted} ${to}` },\r\n };\r\n } catch (error) {\r\n return { success: false, error: error instanceof Error ? error.message : String(error) };\r\n }\r\n}\r\n\r\n// Main entry point\r\nexport async function unitConverter(\r\n action: string,\r\n value: number,\r\n from: string,\r\n to: string\r\n): Promise<ConversionResult> {\r\n if (action === \"list\") {\r\n return { success: true, result: listUnits(from) as any };\r\n }\r\n return convert(value, from, to);\r\n}\r\n\r\nexport default { convert, listUnits, unitConverter };\r\n"],"mappings":"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","names":[]}