podcast manager

cors and reader mode proxies

+205 -42
+100 -38
package-lock.json
··· 8 8 "name": "skypod", 9 9 "version": "0.0.0", 10 10 "dependencies": { 11 + "@mozilla/readability": "^0.6.0", 11 12 "@preact/signals": "^2.2.0", 12 13 "dexie": "^4.0.11", 13 14 "express": "^5.1.0", 14 15 "isomorphic-ws": "^5.0.0", 15 16 "jose": "^6.0.11", 16 17 "level": "^10.0.0", 18 + "linkedom": "^0.18.12", 17 19 "nanoid": "^5.1.5", 18 20 "preact": "^10.26.9", 19 21 "simple-peer": "^9.11.1", ··· 2333 2335 "url": "https://github.com/sponsors/ljharb" 2334 2336 } 2335 2337 }, 2338 + "node_modules/@mozilla/readability": { 2339 + "version": "0.6.0", 2340 + "resolved": "https://registry.npmjs.org/@mozilla/readability/-/readability-0.6.0.tgz", 2341 + "integrity": "sha512-juG5VWh4qAivzTAeMzvY9xs9HY5rAcr2E4I7tiSSCokRFi7XIZCAu92ZkSTsIj1OPceCifL3cpfteP3pDT9/QQ==", 2342 + "license": "Apache-2.0", 2343 + "engines": { 2344 + "node": ">=14.0.0" 2345 + } 2346 + }, 2336 2347 "node_modules/@napi-rs/wasm-runtime": { 2337 2348 "version": "0.2.12", 2338 2349 "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", ··· 5045 5056 "version": "4.1.0", 5046 5057 "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 5047 5058 "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 5048 - "dev": true, 5059 + "devOptional": true, 5049 5060 "license": "MIT", 5050 5061 "dependencies": { 5051 5062 "buffer": "^5.5.0", ··· 5057 5068 "version": "5.7.1", 5058 5069 "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 5059 5070 "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 5060 - "dev": true, 5071 + "devOptional": true, 5061 5072 "funding": [ 5062 5073 { 5063 5074 "type": "github", ··· 5116 5127 "version": "1.0.0", 5117 5128 "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 5118 5129 "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", 5119 - "dev": true, 5120 5130 "license": "ISC" 5121 5131 }, 5122 5132 "node_modules/brace-expansion": { ··· 5692 5702 "version": "3.2.0", 5693 5703 "resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.0.tgz", 5694 5704 "integrity": "sha512-jk0GxrLtUEmW/TmFsk2WghvgHe8B0pxGilqCL21y8lHkPUGa6FTsnCNtHPOzT8O3y+N+m3espawV80bbBlgfTA==", 5695 - "dev": true, 5705 + "devOptional": true, 5696 5706 "hasInstallScript": true, 5697 5707 "license": "MIT", 5698 5708 "dependencies": { ··· 5772 5782 "version": "1.1.4", 5773 5783 "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 5774 5784 "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", 5775 - "dev": true, 5785 + "devOptional": true, 5776 5786 "license": "ISC" 5777 5787 }, 5778 5788 "node_modules/chrome-dgram": { ··· 6297 6307 "version": "5.2.2", 6298 6308 "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", 6299 6309 "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", 6300 - "dev": true, 6301 6310 "license": "BSD-2-Clause", 6302 6311 "dependencies": { 6303 6312 "boolbase": "^1.0.0", ··· 6314 6323 "version": "6.2.2", 6315 6324 "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", 6316 6325 "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", 6317 - "dev": true, 6318 6326 "license": "BSD-2-Clause", 6319 6327 "engines": { 6320 6328 "node": ">= 6" ··· 6330 6338 "dev": true, 6331 6339 "license": "MIT" 6332 6340 }, 6341 + "node_modules/cssom": { 6342 + "version": "0.5.0", 6343 + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", 6344 + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", 6345 + "license": "MIT" 6346 + }, 6333 6347 "node_modules/cssstyle": { 6334 6348 "version": "4.6.0", 6335 6349 "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", ··· 6464 6478 "version": "6.0.0", 6465 6479 "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 6466 6480 "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 6467 - "dev": true, 6481 + "devOptional": true, 6468 6482 "license": "MIT", 6469 6483 "dependencies": { 6470 6484 "mimic-response": "^3.1.0" ··· 6528 6542 "version": "0.6.0", 6529 6543 "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 6530 6544 "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", 6531 - "dev": true, 6545 + "devOptional": true, 6532 6546 "license": "MIT", 6533 6547 "engines": { 6534 6548 "node": ">=4.0.0" ··· 6767 6781 "version": "2.1.2", 6768 6782 "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", 6769 6783 "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", 6770 - "dev": true, 6784 + "devOptional": true, 6771 6785 "license": "Apache-2.0", 6772 6786 "engines": { 6773 6787 "node": ">=8" ··· 6846 6860 "version": "2.0.0", 6847 6861 "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", 6848 6862 "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", 6849 - "dev": true, 6850 6863 "license": "MIT", 6851 6864 "dependencies": { 6852 6865 "domelementtype": "^2.3.0", ··· 6861 6874 "version": "4.5.0", 6862 6875 "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 6863 6876 "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 6864 - "dev": true, 6865 6877 "license": "BSD-2-Clause", 6866 6878 "engines": { 6867 6879 "node": ">=0.12" ··· 6887 6899 "version": "2.3.0", 6888 6900 "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", 6889 6901 "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", 6890 - "dev": true, 6891 6902 "funding": [ 6892 6903 { 6893 6904 "type": "github", ··· 6900 6911 "version": "5.0.3", 6901 6912 "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", 6902 6913 "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", 6903 - "dev": true, 6904 6914 "license": "BSD-2-Clause", 6905 6915 "dependencies": { 6906 6916 "domelementtype": "^2.3.0" ··· 6916 6926 "version": "3.2.2", 6917 6927 "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", 6918 6928 "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", 6919 - "dev": true, 6920 6929 "license": "BSD-2-Clause", 6921 6930 "dependencies": { 6922 6931 "dom-serializer": "^2.0.0", ··· 7038 7047 "version": "1.4.5", 7039 7048 "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", 7040 7049 "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", 7041 - "dev": true, 7050 + "devOptional": true, 7042 7051 "license": "MIT", 7043 7052 "dependencies": { 7044 7053 "once": "^1.4.0" ··· 7048 7057 "version": "6.0.1", 7049 7058 "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", 7050 7059 "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", 7051 - "dev": true, 7052 7060 "license": "BSD-2-Clause", 7053 7061 "engines": { 7054 7062 "node": ">=0.12" ··· 7798 7806 "version": "2.0.3", 7799 7807 "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", 7800 7808 "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", 7801 - "dev": true, 7809 + "devOptional": true, 7802 7810 "license": "(MIT OR WTFPL)", 7803 7811 "engines": { 7804 7812 "node": ">=6" ··· 8212 8220 "version": "1.0.0", 8213 8221 "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 8214 8222 "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", 8215 - "dev": true, 8223 + "devOptional": true, 8216 8224 "license": "MIT" 8217 8225 }, 8218 8226 "node_modules/fs-minipass": { ··· 8545 8553 "version": "0.0.0", 8546 8554 "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", 8547 8555 "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", 8548 - "dev": true, 8556 + "devOptional": true, 8549 8557 "license": "MIT" 8550 8558 }, 8551 8559 "node_modules/github-slugger": { ··· 8848 8856 "dev": true, 8849 8857 "license": "MIT" 8850 8858 }, 8859 + "node_modules/htmlparser2": { 8860 + "version": "10.0.0", 8861 + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", 8862 + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", 8863 + "funding": [ 8864 + "https://github.com/fb55/htmlparser2?sponsor=1", 8865 + { 8866 + "type": "github", 8867 + "url": "https://github.com/sponsors/fb55" 8868 + } 8869 + ], 8870 + "license": "MIT", 8871 + "dependencies": { 8872 + "domelementtype": "^2.3.0", 8873 + "domhandler": "^5.0.3", 8874 + "domutils": "^3.2.1", 8875 + "entities": "^6.0.0" 8876 + } 8877 + }, 8851 8878 "node_modules/http-cache-semantics": { 8852 8879 "version": "4.2.0", 8853 8880 "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", ··· 9135 9162 "version": "1.3.8", 9136 9163 "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", 9137 9164 "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", 9138 - "dev": true, 9165 + "devOptional": true, 9139 9166 "license": "ISC" 9140 9167 }, 9141 9168 "node_modules/internal-slot": { ··· 11145 11172 "dev": true, 11146 11173 "license": "MIT" 11147 11174 }, 11175 + "node_modules/linkedom": { 11176 + "version": "0.18.12", 11177 + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.18.12.tgz", 11178 + "integrity": "sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==", 11179 + "license": "ISC", 11180 + "dependencies": { 11181 + "css-select": "^5.1.0", 11182 + "cssom": "^0.5.0", 11183 + "html-escaper": "^3.0.3", 11184 + "htmlparser2": "^10.0.0", 11185 + "uhyphen": "^0.2.0" 11186 + }, 11187 + "engines": { 11188 + "node": ">=16" 11189 + }, 11190 + "peerDependencies": { 11191 + "canvas": ">= 2" 11192 + }, 11193 + "peerDependenciesMeta": { 11194 + "canvas": { 11195 + "optional": true 11196 + } 11197 + } 11198 + }, 11199 + "node_modules/linkedom/node_modules/html-escaper": { 11200 + "version": "3.0.3", 11201 + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", 11202 + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", 11203 + "license": "MIT" 11204 + }, 11148 11205 "node_modules/load-ip-set": { 11149 11206 "version": "3.0.1", 11150 11207 "resolved": "https://registry.npmjs.org/load-ip-set/-/load-ip-set-3.0.1.tgz", ··· 12530 12587 "version": "3.1.0", 12531 12588 "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 12532 12589 "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 12533 - "dev": true, 12590 + "devOptional": true, 12534 12591 "license": "MIT", 12535 12592 "engines": { 12536 12593 "node": ">=10" ··· 12583 12640 "version": "1.2.8", 12584 12641 "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 12585 12642 "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 12586 - "dev": true, 12643 + "devOptional": true, 12587 12644 "license": "MIT", 12588 12645 "funding": { 12589 12646 "url": "https://github.com/sponsors/ljharb" ··· 12839 12896 "version": "0.5.3", 12840 12897 "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 12841 12898 "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", 12842 - "dev": true, 12899 + "devOptional": true, 12843 12900 "license": "MIT" 12844 12901 }, 12845 12902 "node_modules/module-error": { ··· 12879 12936 "version": "2.0.0", 12880 12937 "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", 12881 12938 "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", 12882 - "dev": true, 12939 + "devOptional": true, 12883 12940 "license": "MIT" 12884 12941 }, 12885 12942 "node_modules/napi-macros": { ··· 12941 12998 "version": "3.78.0", 12942 12999 "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.78.0.tgz", 12943 13000 "integrity": "sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ==", 12944 - "dev": true, 13001 + "devOptional": true, 12945 13002 "license": "MIT", 12946 13003 "dependencies": { 12947 13004 "semver": "^7.3.5" ··· 12954 13011 "version": "7.7.3", 12955 13012 "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", 12956 13013 "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", 12957 - "dev": true, 13014 + "devOptional": true, 12958 13015 "license": "ISC", 12959 13016 "bin": { 12960 13017 "semver": "bin/semver.js" ··· 12967 13024 "version": "7.1.1", 12968 13025 "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", 12969 13026 "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", 12970 - "dev": true, 13027 + "devOptional": true, 12971 13028 "license": "MIT" 12972 13029 }, 12973 13030 "node_modules/node-datachannel": { ··· 13324 13381 "version": "2.1.1", 13325 13382 "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", 13326 13383 "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", 13327 - "dev": true, 13328 13384 "license": "BSD-2-Clause", 13329 13385 "dependencies": { 13330 13386 "boolbase": "^1.0.0" ··· 14007 14063 "version": "7.1.3", 14008 14064 "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", 14009 14065 "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", 14010 - "dev": true, 14066 + "devOptional": true, 14011 14067 "license": "MIT", 14012 14068 "dependencies": { 14013 14069 "detect-libc": "^2.0.0", ··· 14239 14295 "version": "3.0.3", 14240 14296 "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", 14241 14297 "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", 14242 - "dev": true, 14298 + "devOptional": true, 14243 14299 "license": "MIT", 14244 14300 "dependencies": { 14245 14301 "end-of-stream": "^1.1.0", ··· 14435 14491 "version": "1.2.8", 14436 14492 "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 14437 14493 "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 14438 - "dev": true, 14494 + "devOptional": true, 14439 14495 "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", 14440 14496 "dependencies": { 14441 14497 "deep-extend": "^0.6.0", ··· 14451 14507 "version": "2.0.1", 14452 14508 "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 14453 14509 "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", 14454 - "dev": true, 14510 + "devOptional": true, 14455 14511 "license": "MIT", 14456 14512 "engines": { 14457 14513 "node": ">=0.10.0" ··· 15335 15391 "version": "1.0.1", 15336 15392 "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", 15337 15393 "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", 15338 - "dev": true, 15394 + "devOptional": true, 15339 15395 "funding": [ 15340 15396 { 15341 15397 "type": "github", ··· 15356 15412 "version": "4.0.1", 15357 15413 "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", 15358 15414 "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", 15359 - "dev": true, 15415 + "devOptional": true, 15360 15416 "funding": [ 15361 15417 { 15362 15418 "type": "github", ··· 16074 16130 "version": "2.1.4", 16075 16131 "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", 16076 16132 "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", 16077 - "dev": true, 16133 + "devOptional": true, 16078 16134 "license": "MIT", 16079 16135 "dependencies": { 16080 16136 "chownr": "^1.1.1", ··· 16087 16143 "version": "2.2.0", 16088 16144 "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", 16089 16145 "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", 16090 - "dev": true, 16146 + "devOptional": true, 16091 16147 "license": "MIT", 16092 16148 "dependencies": { 16093 16149 "bl": "^4.0.3", ··· 16583 16639 "version": "0.6.0", 16584 16640 "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 16585 16641 "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", 16586 - "dev": true, 16642 + "devOptional": true, 16587 16643 "license": "Apache-2.0", 16588 16644 "dependencies": { 16589 16645 "safe-buffer": "^5.0.1" ··· 16821 16877 "engines": { 16822 16878 "node": ">=0.8.0" 16823 16879 } 16880 + }, 16881 + "node_modules/uhyphen": { 16882 + "version": "0.2.0", 16883 + "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", 16884 + "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==", 16885 + "license": "ISC" 16824 16886 }, 16825 16887 "node_modules/uint8-util": { 16826 16888 "version": "2.2.5",
+2
package.json
··· 22 22 "#skypod/*": "./src/skypod/*" 23 23 }, 24 24 "dependencies": { 25 + "@mozilla/readability": "^0.6.0", 25 26 "@preact/signals": "^2.2.0", 26 27 "dexie": "^4.0.11", 27 28 "express": "^5.1.0", 28 29 "isomorphic-ws": "^5.0.0", 29 30 "jose": "^6.0.11", 30 31 "level": "^10.0.0", 32 + "linkedom": "^0.18.12", 31 33 "nanoid": "^5.1.5", 32 34 "preact": "^10.26.9", 33 35 "simple-peer": "^9.11.1",
+1 -1
src/client/page-app.tsx
··· 1 1 import {DatabaseProvider} from '#client/root/context-database' 2 2 import {SkypodProvider} from '#client/skypod/context' 3 - import {RealmConnectionManager} from '#realm/client/connection-manager' 3 + import {RealmConnectionManager} from '#realm/client/components/connection-manager' 4 4 import { 5 5 RealmConnectionFallbackProps, 6 6 RealmConnectionProvider,
+3 -3
src/realm/client/connection-manager.tsx src/realm/client/components/connection-manager.tsx
··· 6 6 import {jwtSchema} from '#common/crypto/jwts' 7 7 import {RealmBrand} from '#realm/protocol/index' 8 8 9 - import {useRealmConnection} from './context-connection' 10 - import {useRealmIdentity} from './context-identity' 9 + import {useRealmConnection} from '../context-connection' 10 + import {useRealmIdentity} from '../context-identity' 11 11 12 12 export const RealmConnectionManager: preact.FunctionComponent = () => { 13 13 const {identity} = useRealmIdentity() ··· 60 60 <div> 61 61 <pre> 62 62 {connection.connected.value ? ' 🟢 Connected: ' : ' 🔴 Disconnected: '} 63 - {connection.realm.value.realmid} 63 + {connection.realm.value.realmid} '/' {identity.identid} '/' {identity.latest} 64 64 </pre> 65 65 <textarea value={invitation.value} /> 66 66 <br />
+35
src/server/routes-api/middleware-cors.ts
··· 1 + import { RequestHandler } from "express" 2 + 3 + export const corsProxy: RequestHandler = async (req, res) => { 4 + const url = req.query.url 5 + if (typeof url !== 'string' || !url) { 6 + res.status(400).json({error: 'Missing or invalid url parameter'}) 7 + return 8 + } 9 + 10 + try { 11 + const response = await fetch(url, { 12 + headers: { 13 + 'User-Agent': 'Mozilla/5.0 (compatible; Skypod/1.0; +https://skypod.accidental.cc)', 14 + }, 15 + }) 16 + 17 + if (!response.ok) { 18 + res.status(response.status).json({error: `Failed to fetch feed: ${response.statusText}`}) 19 + return 20 + } 21 + 22 + const contentType = response.headers.get('content-type') || 'application/xml' 23 + const content = await response.text() 24 + 25 + res.setHeader('Content-Type', contentType) 26 + res.setHeader('Cache-Control', 'public, max-age=300') // 5 min cache 27 + res.send(content) 28 + } catch (error) { 29 + console.error('Feed proxy error:', error) 30 + res.status(500).json({ 31 + error: 'Failed to fetch feed', 32 + message: error instanceof Error ? error.message : 'Unknown error', 33 + }) 34 + } 35 + }
+56
src/server/routes-api/middleware-reader.ts
··· 1 + import {Readability} from '@mozilla/readability' 2 + import {RequestHandler} from "express" 3 + import {parseHTML} from 'linkedom' 4 + 5 + export const readabilityProxy: RequestHandler = async (req, res) => { 6 + const url = req.query.url 7 + if (typeof url !== 'string' || !url) { 8 + res.status(400).json({error: 'Missing or invalid url parameter'}) 9 + return 10 + } 11 + 12 + try { 13 + const response = await fetch(url, { 14 + headers: { 15 + 'User-Agent': 'Mozilla/5.0 (compatible; Skypod/1.0; +https://skypod.accidental.cc)', 16 + }, 17 + }) 18 + 19 + if (!response.ok) { 20 + res.status(response.status).json({error: `Failed to fetch page: ${response.statusText}`}) 21 + return 22 + } 23 + 24 + const html = await response.text() 25 + const {document} = parseHTML(html) 26 + 27 + const reader = new Readability(document, { 28 + keepClasses: false, 29 + }) 30 + 31 + const article = reader.parse() 32 + 33 + if (!article) { 34 + res.status(422).json({error: 'Could not extract readable content'}) 35 + return 36 + } 37 + 38 + res.setHeader('Content-Type', 'application/json; charset=utf-8') 39 + res.send(JSON.stringify({ 40 + title: article.title, 41 + byline: article.byline, 42 + content: article.content, 43 + textContent: article.textContent, 44 + excerpt: article.excerpt, 45 + siteName: article.siteName, 46 + length: article.length, 47 + url, 48 + })) 49 + } catch (error) { 50 + console.error('Reader mode error:', error) 51 + res.status(500).json({ 52 + error: 'Failed to extract content', 53 + message: error instanceof Error ? error.message : 'Unknown error', 54 + }) 55 + } 56 + }
+8
src/server/routes-api/middleware.ts
··· 1 1 import {Router} from 'express' 2 + import { corsProxy } from './middleware-cors' 3 + import { readabilityProxy } from './middleware-reader' 2 4 3 5 export const apiRouter = Router() 4 6 5 7 apiRouter.get('/', (_, res) => { 6 8 res.send('hi') 7 9 }) 10 + 11 + // TODO: we should take a signed jwt as a bearer token 12 + // just so we're not an open proxy - maybe that's a config option 13 + 14 + apiRouter.get('/cors', corsProxy) 15 + apiRouter.get('/reader', readabilityProxy)