this repo has no description
0
fork

Configure Feed

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

Switch from Express to Fastify

futur f4b1562a 4157d6b7

+350 -161
+2 -4
package.json
··· 27 27 }, 28 28 "devDependencies": { 29 29 "@types/better-sqlite3": "^7.6.11", 30 - "@types/express": "^4.17.21", 31 - "@types/express-ws": "^3.0.4", 32 30 "@types/node": "^20.11.19", 33 31 "@types/prompts": "^2.4.9", 34 32 "@types/ws": "^8.5.12", ··· 44 42 "@atproto/crypto": "^0.4.0", 45 43 "@atproto/identity": "^0.4.0", 46 44 "@atproto/xrpc-server": "^0.6.2", 45 + "@fastify/websocket": "^10.0.1", 47 46 "better-sqlite3": "^11.1.2", 48 - "express": "^4.19.2", 49 - "express-ws": "^5.0.2", 47 + "fastify": "^4.28.1", 50 48 "prompts": "^2.4.2", 51 49 "uint8arrays": "^5.1.0" 52 50 },
+288 -121
pnpm-lock.yaml
··· 23 23 '@atproto/xrpc-server': 24 24 specifier: ^0.6.2 25 25 version: 0.6.2 26 + '@fastify/websocket': 27 + specifier: ^10.0.1 28 + version: 10.0.1 26 29 better-sqlite3: 27 30 specifier: ^11.1.2 28 31 version: 11.1.2 29 - express: 30 - specifier: ^4.19.2 31 - version: 4.19.2 32 - express-ws: 33 - specifier: ^5.0.2 34 - version: 5.0.2(express@4.19.2) 32 + fastify: 33 + specifier: ^4.28.1 34 + version: 4.28.1 35 35 prompts: 36 36 specifier: ^2.4.2 37 37 version: 2.4.2 ··· 42 42 '@types/better-sqlite3': 43 43 specifier: ^7.6.11 44 44 version: 7.6.11 45 - '@types/express': 46 - specifier: ^4.17.21 47 - version: 4.17.21 48 - '@types/express-ws': 49 - specifier: ^3.0.4 50 - version: 3.0.4 51 45 '@types/node': 52 46 specifier: ^20.11.19 53 47 version: 20.11.19 ··· 196 190 resolution: {integrity: sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==} 197 191 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 198 192 193 + '@fastify/ajv-compiler@3.6.0': 194 + resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} 195 + 196 + '@fastify/error@3.4.1': 197 + resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} 198 + 199 + '@fastify/fast-json-stringify-compiler@4.3.0': 200 + resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} 201 + 202 + '@fastify/merge-json-schemas@0.1.1': 203 + resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} 204 + 205 + '@fastify/websocket@10.0.1': 206 + resolution: {integrity: sha512-8/pQIxTPRD8U94aILTeJ+2O3el/r19+Ej5z1O1mXlqplsUH7KzCjAI0sgd5DM/NoPjAi5qLFNIjgM5+9/rGSNw==} 207 + 199 208 '@humanwhocodes/config-array@0.11.14': 200 209 resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} 201 210 engines: {node: '>=10.10.0'} ··· 232 241 '@types/better-sqlite3@7.6.11': 233 242 resolution: {integrity: sha512-i8KcD3PgGtGBLl3+mMYA8PdKkButvPyARxA7IQAd6qeslht13qxb1zzO8dRCtE7U3IoJS782zDBAeoKiM695kg==} 234 243 235 - '@types/body-parser@1.19.5': 236 - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} 237 - 238 - '@types/connect@3.4.38': 239 - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} 240 - 241 - '@types/express-serve-static-core@4.19.5': 242 - resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} 243 - 244 - '@types/express-ws@3.0.4': 245 - resolution: {integrity: sha512-Yjj18CaivG5KndgcvzttWe8mPFinPCHJC2wvyQqVzA7hqeufM8EtWMj6mpp5omg3s8XALUexhOu8aXAyi/DyJQ==} 246 - 247 - '@types/express@4.17.21': 248 - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} 249 - 250 - '@types/http-errors@2.0.4': 251 - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} 252 - 253 244 '@types/json-schema@7.0.15': 254 245 resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 255 246 256 - '@types/mime@1.3.5': 257 - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} 258 - 259 247 '@types/node@20.11.19': 260 248 resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==} 261 249 262 250 '@types/prompts@2.4.9': 263 251 resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} 264 252 265 - '@types/qs@6.9.15': 266 - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} 267 - 268 - '@types/range-parser@1.2.7': 269 - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} 270 - 271 253 '@types/semver@7.5.7': 272 254 resolution: {integrity: sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==} 273 - 274 - '@types/send@0.17.4': 275 - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} 276 - 277 - '@types/serve-static@1.15.7': 278 - resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} 279 255 280 256 '@types/ws@8.5.12': 281 257 resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} ··· 342 318 resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} 343 319 engines: {node: '>=6.5'} 344 320 321 + abstract-logging@2.0.1: 322 + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} 323 + 345 324 accepts@1.3.8: 346 325 resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} 347 326 engines: {node: '>= 0.6'} ··· 356 335 engines: {node: '>=0.4.0'} 357 336 hasBin: true 358 337 338 + ajv-formats@2.1.1: 339 + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} 340 + peerDependencies: 341 + ajv: ^8.0.0 342 + peerDependenciesMeta: 343 + ajv: 344 + optional: true 345 + 346 + ajv-formats@3.0.1: 347 + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} 348 + peerDependencies: 349 + ajv: ^8.0.0 350 + peerDependenciesMeta: 351 + ajv: 352 + optional: true 353 + 359 354 ajv@6.12.6: 360 355 resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 356 + 357 + ajv@8.17.1: 358 + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} 361 359 362 360 ansi-regex@5.0.1: 363 361 resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} ··· 383 381 atomic-sleep@1.0.0: 384 382 resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} 385 383 engines: {node: '>=8.0.0'} 384 + 385 + avvio@8.4.0: 386 + resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} 386 387 387 388 await-lock@2.2.2: 388 389 resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} ··· 545 546 resolution: {integrity: sha512-9Ctv6EnwOy5Ai566DczI/QhAC6y+AhWDA2gFU8Zz4xezUy1BevHaIYhfdLWZQxh4Qf4H28lRu1Lq+hhIm1US9w==} 546 547 hasBin: true 547 548 549 + duplexify@4.1.3: 550 + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} 551 + 548 552 ee-first@1.1.1: 549 553 resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} 550 554 ··· 619 623 resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} 620 624 engines: {node: '>=6'} 621 625 622 - express-ws@5.0.2: 623 - resolution: {integrity: sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==} 624 - engines: {node: '>=4.5.0'} 625 - peerDependencies: 626 - express: ^4.0.0 || ^5.0.0-alpha.1 627 - 628 626 express@4.19.2: 629 627 resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} 630 628 engines: {node: '>= 0.10.0'} 631 629 630 + fast-content-type-parse@1.1.0: 631 + resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} 632 + 633 + fast-decode-uri-component@1.0.1: 634 + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} 635 + 632 636 fast-deep-equal@3.1.3: 633 637 resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 634 638 ··· 639 643 fast-json-stable-stringify@2.1.0: 640 644 resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 641 645 646 + fast-json-stringify@5.16.1: 647 + resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} 648 + 642 649 fast-levenshtein@2.0.6: 643 650 resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 644 651 652 + fast-querystring@1.1.2: 653 + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} 654 + 645 655 fast-redact@3.5.0: 646 656 resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} 647 657 engines: {node: '>=6'} 648 658 659 + fast-uri@2.4.0: 660 + resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} 661 + 662 + fast-uri@3.0.1: 663 + resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} 664 + 665 + fastify-plugin@4.5.1: 666 + resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} 667 + 668 + fastify@4.28.1: 669 + resolution: {integrity: sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==} 670 + 649 671 fastq@1.17.1: 650 672 resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 651 673 ··· 663 685 finalhandler@1.2.0: 664 686 resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} 665 687 engines: {node: '>= 0.8'} 688 + 689 + find-my-way@8.2.0: 690 + resolution: {integrity: sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==} 691 + engines: {node: '>=14'} 666 692 667 693 find-up@5.0.0: 668 694 resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} ··· 824 850 json-buffer@3.0.1: 825 851 resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 826 852 853 + json-schema-ref-resolver@1.0.1: 854 + resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} 855 + 827 856 json-schema-traverse@0.4.1: 828 857 resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 858 + 859 + json-schema-traverse@1.0.0: 860 + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} 829 861 830 862 json-stable-stringify-without-jsonify@1.0.1: 831 863 resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} ··· 840 872 levn@0.4.1: 841 873 resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 842 874 engines: {node: '>= 0.8.0'} 875 + 876 + light-my-request@5.13.0: 877 + resolution: {integrity: sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==} 843 878 844 879 locate-path@6.0.0: 845 880 resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} ··· 994 1029 pino-std-serializers@6.2.2: 995 1030 resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} 996 1031 1032 + pino-std-serializers@7.0.0: 1033 + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} 1034 + 997 1035 pino@8.21.0: 998 1036 resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} 1037 + hasBin: true 1038 + 1039 + pino@9.3.2: 1040 + resolution: {integrity: sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw==} 999 1041 hasBin: true 1000 1042 1001 1043 prebuild-install@7.1.2: ··· 1009 1051 1010 1052 process-warning@3.0.0: 1011 1053 resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} 1054 + 1055 + process-warning@4.0.0: 1056 + resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} 1012 1057 1013 1058 process@0.11.10: 1014 1059 resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} ··· 1066 1111 resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} 1067 1112 engines: {node: '>= 12.13.0'} 1068 1113 1114 + require-from-string@2.0.2: 1115 + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} 1116 + engines: {node: '>=0.10.0'} 1117 + 1069 1118 resolve-from@4.0.0: 1070 1119 resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1071 1120 engines: {node: '>=4'} 1072 1121 1122 + ret@0.4.3: 1123 + resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} 1124 + engines: {node: '>=10'} 1125 + 1073 1126 reusify@1.0.4: 1074 1127 resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1075 1128 engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1129 + 1130 + rfdc@1.4.1: 1131 + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} 1076 1132 1077 1133 rimraf@3.0.2: 1078 1134 resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} ··· 1083 1139 1084 1140 safe-buffer@5.2.1: 1085 1141 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 1142 + 1143 + safe-regex2@3.1.0: 1144 + resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} 1086 1145 1087 1146 safe-stable-stringify@2.4.3: 1088 1147 resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} ··· 1091 1150 safer-buffer@2.1.2: 1092 1151 resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 1093 1152 1153 + secure-json-parse@2.7.0: 1154 + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} 1155 + 1094 1156 semver@7.6.0: 1095 1157 resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} 1096 1158 engines: {node: '>=10'} ··· 1103 1165 serve-static@1.15.0: 1104 1166 resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} 1105 1167 engines: {node: '>= 0.8.0'} 1168 + 1169 + set-cookie-parser@2.7.0: 1170 + resolution: {integrity: sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==} 1106 1171 1107 1172 set-function-length@1.2.2: 1108 1173 resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} ··· 1139 1204 sonic-boom@3.8.1: 1140 1205 resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} 1141 1206 1207 + sonic-boom@4.0.1: 1208 + resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==} 1209 + 1142 1210 split2@4.2.0: 1143 1211 resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} 1144 1212 engines: {node: '>= 10.x'} ··· 1146 1214 statuses@2.0.1: 1147 1215 resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} 1148 1216 engines: {node: '>= 0.8'} 1217 + 1218 + stream-shift@1.0.3: 1219 + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} 1149 1220 1150 1221 string_decoder@1.3.0: 1151 1222 resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} ··· 1179 1250 thread-stream@2.7.0: 1180 1251 resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} 1181 1252 1253 + thread-stream@3.1.0: 1254 + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} 1255 + 1182 1256 tlds@1.254.0: 1183 1257 resolution: {integrity: sha512-YY4ei7K7gPGifqNSrfMaPdqTqiHcwYKUJ7zhLqQOK2ildlGgti5TSwJiXXN1YqG17I2GYZh5cZqv2r5fwBUM+w==} 1184 1258 hasBin: true ··· 1186 1260 to-regex-range@5.0.1: 1187 1261 resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1188 1262 engines: {node: '>=8.0'} 1263 + 1264 + toad-cache@3.7.0: 1265 + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} 1266 + engines: {node: '>=12'} 1189 1267 1190 1268 toidentifier@1.0.1: 1191 1269 resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} ··· 1252 1330 wrappy@1.0.2: 1253 1331 resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1254 1332 1255 - ws@7.5.10: 1256 - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} 1257 - engines: {node: '>=8.3.0'} 1258 - peerDependencies: 1259 - bufferutil: ^4.0.1 1260 - utf-8-validate: ^5.0.2 1261 - peerDependenciesMeta: 1262 - bufferutil: 1263 - optional: true 1264 - utf-8-validate: 1265 - optional: true 1266 - 1267 1333 ws@8.18.0: 1268 1334 resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} 1269 1335 engines: {node: '>=10.0.0'} ··· 1438 1504 1439 1505 '@eslint/js@8.50.0': {} 1440 1506 1507 + '@fastify/ajv-compiler@3.6.0': 1508 + dependencies: 1509 + ajv: 8.17.1 1510 + ajv-formats: 2.1.1(ajv@8.17.1) 1511 + fast-uri: 2.4.0 1512 + 1513 + '@fastify/error@3.4.1': {} 1514 + 1515 + '@fastify/fast-json-stringify-compiler@4.3.0': 1516 + dependencies: 1517 + fast-json-stringify: 5.16.1 1518 + 1519 + '@fastify/merge-json-schemas@0.1.1': 1520 + dependencies: 1521 + fast-deep-equal: 3.1.3 1522 + 1523 + '@fastify/websocket@10.0.1': 1524 + dependencies: 1525 + duplexify: 4.1.3 1526 + fastify-plugin: 4.5.1 1527 + ws: 8.18.0 1528 + transitivePeerDependencies: 1529 + - bufferutil 1530 + - utf-8-validate 1531 + 1441 1532 '@humanwhocodes/config-array@0.11.14': 1442 1533 dependencies: 1443 1534 '@humanwhocodes/object-schema': 2.0.2 ··· 1477 1568 dependencies: 1478 1569 '@types/node': 20.11.19 1479 1570 1480 - '@types/body-parser@1.19.5': 1481 - dependencies: 1482 - '@types/connect': 3.4.38 1483 - '@types/node': 20.11.19 1484 - 1485 - '@types/connect@3.4.38': 1486 - dependencies: 1487 - '@types/node': 20.11.19 1488 - 1489 - '@types/express-serve-static-core@4.19.5': 1490 - dependencies: 1491 - '@types/node': 20.11.19 1492 - '@types/qs': 6.9.15 1493 - '@types/range-parser': 1.2.7 1494 - '@types/send': 0.17.4 1495 - 1496 - '@types/express-ws@3.0.4': 1497 - dependencies: 1498 - '@types/express': 4.17.21 1499 - '@types/express-serve-static-core': 4.19.5 1500 - '@types/ws': 8.5.12 1501 - 1502 - '@types/express@4.17.21': 1503 - dependencies: 1504 - '@types/body-parser': 1.19.5 1505 - '@types/express-serve-static-core': 4.19.5 1506 - '@types/qs': 6.9.15 1507 - '@types/serve-static': 1.15.7 1508 - 1509 - '@types/http-errors@2.0.4': {} 1510 - 1511 1571 '@types/json-schema@7.0.15': {} 1512 - 1513 - '@types/mime@1.3.5': {} 1514 1572 1515 1573 '@types/node@20.11.19': 1516 1574 dependencies: ··· 1521 1579 '@types/node': 20.11.19 1522 1580 kleur: 3.0.3 1523 1581 1524 - '@types/qs@6.9.15': {} 1525 - 1526 - '@types/range-parser@1.2.7': {} 1527 - 1528 1582 '@types/semver@7.5.7': {} 1529 1583 1530 - '@types/send@0.17.4': 1531 - dependencies: 1532 - '@types/mime': 1.3.5 1533 - '@types/node': 20.11.19 1534 - 1535 - '@types/serve-static@1.15.7': 1536 - dependencies: 1537 - '@types/http-errors': 2.0.4 1538 - '@types/node': 20.11.19 1539 - '@types/send': 0.17.4 1540 - 1541 1584 '@types/ws@8.5.12': 1542 1585 dependencies: 1543 1586 '@types/node': 20.11.19 ··· 1631 1674 dependencies: 1632 1675 event-target-shim: 5.0.1 1633 1676 1677 + abstract-logging@2.0.1: {} 1678 + 1634 1679 accepts@1.3.8: 1635 1680 dependencies: 1636 1681 mime-types: 2.1.35 ··· 1642 1687 1643 1688 acorn@8.11.3: {} 1644 1689 1690 + ajv-formats@2.1.1(ajv@8.17.1): 1691 + optionalDependencies: 1692 + ajv: 8.17.1 1693 + 1694 + ajv-formats@3.0.1(ajv@8.17.1): 1695 + optionalDependencies: 1696 + ajv: 8.17.1 1697 + 1645 1698 ajv@6.12.6: 1646 1699 dependencies: 1647 1700 fast-deep-equal: 3.1.3 1648 1701 fast-json-stable-stringify: 2.1.0 1649 1702 json-schema-traverse: 0.4.1 1650 1703 uri-js: 4.4.1 1704 + 1705 + ajv@8.17.1: 1706 + dependencies: 1707 + fast-deep-equal: 3.1.3 1708 + fast-uri: 3.0.1 1709 + json-schema-traverse: 1.0.0 1710 + require-from-string: 2.0.2 1651 1711 1652 1712 ansi-regex@5.0.1: {} 1653 1713 ··· 1665 1725 1666 1726 atomic-sleep@1.0.0: {} 1667 1727 1728 + avvio@8.4.0: 1729 + dependencies: 1730 + '@fastify/error': 3.4.1 1731 + fastq: 1.17.1 1732 + 1668 1733 await-lock@2.2.2: {} 1669 1734 1670 1735 axios@0.27.2: ··· 1841 1906 '@dprint/linux-x64-musl': 0.41.0 1842 1907 '@dprint/win32-x64': 0.41.0 1843 1908 1909 + duplexify@4.1.3: 1910 + dependencies: 1911 + end-of-stream: 1.4.4 1912 + inherits: 2.0.4 1913 + readable-stream: 3.6.2 1914 + stream-shift: 1.0.3 1915 + 1844 1916 ee-first@1.1.1: {} 1845 1917 1846 1918 encodeurl@1.0.2: {} ··· 1934 2006 1935 2007 expand-template@2.0.3: {} 1936 2008 1937 - express-ws@5.0.2(express@4.19.2): 1938 - dependencies: 1939 - express: 4.19.2 1940 - ws: 7.5.10 1941 - transitivePeerDependencies: 1942 - - bufferutil 1943 - - utf-8-validate 1944 - 1945 2009 express@4.19.2: 1946 2010 dependencies: 1947 2011 accepts: 1.3.8 ··· 1978 2042 transitivePeerDependencies: 1979 2043 - supports-color 1980 2044 2045 + fast-content-type-parse@1.1.0: {} 2046 + 2047 + fast-decode-uri-component@1.0.1: {} 2048 + 1981 2049 fast-deep-equal@3.1.3: {} 1982 2050 1983 2051 fast-glob@3.3.2: ··· 1990 2058 1991 2059 fast-json-stable-stringify@2.1.0: {} 1992 2060 2061 + fast-json-stringify@5.16.1: 2062 + dependencies: 2063 + '@fastify/merge-json-schemas': 0.1.1 2064 + ajv: 8.17.1 2065 + ajv-formats: 3.0.1(ajv@8.17.1) 2066 + fast-deep-equal: 3.1.3 2067 + fast-uri: 2.4.0 2068 + json-schema-ref-resolver: 1.0.1 2069 + rfdc: 1.4.1 2070 + 1993 2071 fast-levenshtein@2.0.6: {} 1994 2072 2073 + fast-querystring@1.1.2: 2074 + dependencies: 2075 + fast-decode-uri-component: 1.0.1 2076 + 1995 2077 fast-redact@3.5.0: {} 1996 2078 2079 + fast-uri@2.4.0: {} 2080 + 2081 + fast-uri@3.0.1: {} 2082 + 2083 + fastify-plugin@4.5.1: {} 2084 + 2085 + fastify@4.28.1: 2086 + dependencies: 2087 + '@fastify/ajv-compiler': 3.6.0 2088 + '@fastify/error': 3.4.1 2089 + '@fastify/fast-json-stringify-compiler': 4.3.0 2090 + abstract-logging: 2.0.1 2091 + avvio: 8.4.0 2092 + fast-content-type-parse: 1.1.0 2093 + fast-json-stringify: 5.16.1 2094 + find-my-way: 8.2.0 2095 + light-my-request: 5.13.0 2096 + pino: 9.3.2 2097 + process-warning: 3.0.0 2098 + proxy-addr: 2.0.7 2099 + rfdc: 1.4.1 2100 + secure-json-parse: 2.7.0 2101 + semver: 7.6.0 2102 + toad-cache: 3.7.0 2103 + 1997 2104 fastq@1.17.1: 1998 2105 dependencies: 1999 2106 reusify: 1.0.4 ··· 2019 2126 unpipe: 1.0.0 2020 2127 transitivePeerDependencies: 2021 2128 - supports-color 2129 + 2130 + find-my-way@8.2.0: 2131 + dependencies: 2132 + fast-deep-equal: 3.1.3 2133 + fast-querystring: 1.1.2 2134 + safe-regex2: 3.1.0 2022 2135 2023 2136 find-up@5.0.0: 2024 2137 dependencies: ··· 2167 2280 2168 2281 json-buffer@3.0.1: {} 2169 2282 2283 + json-schema-ref-resolver@1.0.1: 2284 + dependencies: 2285 + fast-deep-equal: 3.1.3 2286 + 2170 2287 json-schema-traverse@0.4.1: {} 2288 + 2289 + json-schema-traverse@1.0.0: {} 2171 2290 2172 2291 json-stable-stringify-without-jsonify@1.0.1: {} 2173 2292 ··· 2182 2301 prelude-ls: 1.2.1 2183 2302 type-check: 0.4.0 2184 2303 2304 + light-my-request@5.13.0: 2305 + dependencies: 2306 + cookie: 0.6.0 2307 + process-warning: 3.0.0 2308 + set-cookie-parser: 2.7.0 2309 + 2185 2310 locate-path@6.0.0: 2186 2311 dependencies: 2187 2312 p-locate: 5.0.0 ··· 2302 2427 2303 2428 pino-std-serializers@6.2.2: {} 2304 2429 2430 + pino-std-serializers@7.0.0: {} 2431 + 2305 2432 pino@8.21.0: 2306 2433 dependencies: 2307 2434 atomic-sleep: 1.0.0 ··· 2316 2443 sonic-boom: 3.8.1 2317 2444 thread-stream: 2.7.0 2318 2445 2446 + pino@9.3.2: 2447 + dependencies: 2448 + atomic-sleep: 1.0.0 2449 + fast-redact: 3.5.0 2450 + on-exit-leak-free: 2.1.2 2451 + pino-abstract-transport: 1.2.0 2452 + pino-std-serializers: 7.0.0 2453 + process-warning: 4.0.0 2454 + quick-format-unescaped: 4.0.4 2455 + real-require: 0.2.0 2456 + safe-stable-stringify: 2.4.3 2457 + sonic-boom: 4.0.1 2458 + thread-stream: 3.1.0 2459 + 2319 2460 prebuild-install@7.1.2: 2320 2461 dependencies: 2321 2462 detect-libc: 2.0.3 ··· 2334 2475 prelude-ls@1.2.1: {} 2335 2476 2336 2477 process-warning@3.0.0: {} 2478 + 2479 + process-warning@4.0.0: {} 2337 2480 2338 2481 process@0.11.10: {} 2339 2482 ··· 2396 2539 2397 2540 real-require@0.2.0: {} 2398 2541 2542 + require-from-string@2.0.2: {} 2543 + 2399 2544 resolve-from@4.0.0: {} 2400 2545 2546 + ret@0.4.3: {} 2547 + 2401 2548 reusify@1.0.4: {} 2549 + 2550 + rfdc@1.4.1: {} 2402 2551 2403 2552 rimraf@3.0.2: 2404 2553 dependencies: ··· 2409 2558 queue-microtask: 1.2.3 2410 2559 2411 2560 safe-buffer@5.2.1: {} 2561 + 2562 + safe-regex2@3.1.0: 2563 + dependencies: 2564 + ret: 0.4.3 2412 2565 2413 2566 safe-stable-stringify@2.4.3: {} 2414 2567 2415 2568 safer-buffer@2.1.2: {} 2416 2569 2570 + secure-json-parse@2.7.0: {} 2571 + 2417 2572 semver@7.6.0: 2418 2573 dependencies: 2419 2574 lru-cache: 6.0.0 ··· 2444 2599 send: 0.18.0 2445 2600 transitivePeerDependencies: 2446 2601 - supports-color 2602 + 2603 + set-cookie-parser@2.7.0: {} 2447 2604 2448 2605 set-function-length@1.2.2: 2449 2606 dependencies: ··· 2485 2642 dependencies: 2486 2643 atomic-sleep: 1.0.0 2487 2644 2645 + sonic-boom@4.0.1: 2646 + dependencies: 2647 + atomic-sleep: 1.0.0 2648 + 2488 2649 split2@4.2.0: {} 2489 2650 2490 2651 statuses@2.0.1: {} 2652 + 2653 + stream-shift@1.0.3: {} 2491 2654 2492 2655 string_decoder@1.3.0: 2493 2656 dependencies: ··· 2526 2689 dependencies: 2527 2690 real-require: 0.2.0 2528 2691 2692 + thread-stream@3.1.0: 2693 + dependencies: 2694 + real-require: 0.2.0 2695 + 2529 2696 tlds@1.254.0: {} 2530 2697 2531 2698 to-regex-range@5.0.1: 2532 2699 dependencies: 2533 2700 is-number: 7.0.0 2701 + 2702 + toad-cache@3.7.0: {} 2534 2703 2535 2704 toidentifier@1.0.1: {} 2536 2705 ··· 2582 2751 isexe: 2.0.0 2583 2752 2584 2753 wrappy@1.0.2: {} 2585 - 2586 - ws@7.5.10: {} 2587 2754 2588 2755 ws@8.18.0: {} 2589 2756
+42 -36
src/LabelerServer.ts
··· 14 14 verifyJwt, 15 15 XRPCError, 16 16 } from "@atproto/xrpc-server"; 17 + import { fastifyWebsocket } from "@fastify/websocket"; 17 18 import Database, { type Database as SQLiteDatabase } from "better-sqlite3"; 18 - import express, { type RequestHandler } from "express"; 19 - import expressWs, { type Application, WebsocketRequestHandler } from "express-ws"; 20 - import { Server } from "node:http"; 19 + import fastify, { type FastifyInstance, type FastifyRequest } from "fastify"; 21 20 import { fromString as ui8FromString } from "uint8arrays"; 22 21 import type { WebSocket } from "ws"; 23 22 import { formatLabel, labelIsSigned, signLabel } from "./util/labels.js"; 24 - import { SignedLabel } from "./util/types.js"; 23 + import { GetMethod, SignedLabel, WebSocketMethod } from "./util/types.js"; 25 24 26 25 /** 27 26 * Options for the {@link LabelerServer} class. ··· 50 49 } 51 50 52 51 export class LabelerServer { 53 - /** The Express application instance. */ 54 - app: Application; 55 - 56 - /** The HTTP server instance. */ 57 - server?: Server; 52 + /** The Fastify application instance. */ 53 + app: FastifyInstance; 58 54 59 55 /** The SQLite database instance. */ 60 56 db: SQLiteDatabase; ··· 99 95 ); 100 96 `); 101 97 102 - this.app = expressWs(express().use(express.json())).app; 103 - this.app.get("/xrpc/com.atproto.label.queryLabels", this.queryLabelsHandler); 104 - this.app.ws("/xrpc/com.atproto.label.subscribeLabels", this.subscribeLabelsHandler); 105 - this.app.post("/xrpc/tools.ozone.moderation.emitEvent", this.emitEventHandler); 98 + this.app = fastify(); 99 + void this.app.register(fastifyWebsocket).then(() => { 100 + this.app.get("/xrpc/com.atproto.label.queryLabels", this.queryLabelsHandler); 101 + this.app.post("/xrpc/tools.ozone.moderation.emitEvent", this.emitEventHandler); 102 + this.app.get( 103 + "/xrpc/com.atproto.label.subscribeLabels", 104 + { websocket: true }, 105 + this.subscribeLabelsHandler, 106 + ); 107 + }); 106 108 } 107 109 108 110 /** ··· 110 112 * @param port The port to listen on. 111 113 * @param callback A callback to run when the server is started. 112 114 */ 113 - start(port = 443, callback?: () => void) { 114 - this.server = this.app.listen(port, callback); 115 + start(port: number, callback: () => void = () => {}) { 116 + this.app.listen({ port }, callback); 115 117 } 116 118 117 119 /** 118 120 * Stop the server. 119 121 * @param callback A callback to run when the server is stopped. 120 122 */ 121 - stop(callback?: () => void) { 122 - if (this.server?.listening) this.server?.close(callback); 123 + stop(callback: () => void = () => {}) { 124 + this.app.close(callback); 123 125 } 124 126 125 127 /** ··· 133 135 VALUES (?, ?, ?, ?, ?, ?, ?, ?) 134 136 `); 135 137 const { src, uri, cid, val, neg, cts, exp, sig } = signed; 136 - const result = stmt.run(src, uri, cid, val, neg, cts, exp, sig); 138 + const result = stmt.run(src, uri, cid, val, neg ? 1 : 0, cts, exp, sig); 137 139 if (!result.changes) throw new Error("Failed to insert label"); 138 140 this.emitLabel(signed); 139 141 return signed; ··· 191 193 * Parse a user DID from an Authorization header JWT. 192 194 * @param req The Express request object. 193 195 */ 194 - private async parseAuthHeaderDid(req: express.Request): Promise<string> { 195 - const authHeader = req.get("Authorization"); 196 + private async parseAuthHeaderDid(req: FastifyRequest): Promise<string> { 197 + const authHeader = req.headers.authorization; 196 198 if (!authHeader) throw new AuthRequiredError("Authorization header is required"); 197 199 198 200 const [type, token] = authHeader.split(" "); ··· 214 216 /** 215 217 * Handler for com.atproto.label.queryLabels. 216 218 */ 217 - queryLabelsHandler: RequestHandler = (req, res) => { 219 + queryLabelsHandler: GetMethod< 220 + { 221 + Querystring: { 222 + uriPatterns?: Array<string>; 223 + sources?: Array<string>; 224 + limit?: string; 225 + cursor?: string; 226 + }; 227 + } 228 + > = async (req, res) => { 218 229 try { 219 230 const { 220 231 uriPatterns = [], 221 232 sources = [], 222 233 limit: limitStr = "50", 223 234 cursor: cursorStr = "0", 224 - } = req.query as { 225 - uriPatterns?: Array<string>; 226 - sources?: Array<string>; 227 - limit?: string; 228 - cursor?: string; 229 - }; 235 + } = req.query; 230 236 231 237 const cursor = parseInt(cursorStr, 10); 232 238 if (cursor !== undefined && Number.isNaN(cursor)) { ··· 268 274 269 275 const nextCursor = rows[rows.length - 1]?.id ?? 0; 270 276 271 - res.json({ cursor: nextCursor, labels }); 277 + await res.send({ cursor: nextCursor, labels }); 272 278 } catch (e) { 273 279 if (e instanceof XRPCError) { 274 - res.status(e.type).json(e.payload); 280 + await res.status(e.type).send(e.payload); 275 281 } else { 276 282 console.error(e); 277 - res.status(500).json({ 283 + await res.status(500).send({ 278 284 error: "InternalServerError", 279 285 message: "An unknown error occurred", 280 286 }); ··· 285 291 /** 286 292 * Handler for com.atproto.label.subscribeLabels. 287 293 */ 288 - subscribeLabelsHandler: WebsocketRequestHandler = (ws, req) => { 289 - const cursor = parseInt(req.params.cursor); 294 + subscribeLabelsHandler: WebSocketMethod<{ Querystring: { cursor?: string } }> = (ws, req) => { 295 + const cursor = parseInt(req.query.cursor ?? "NaN", 10); 290 296 291 - if (cursor && !Number.isNaN(cursor)) { 297 + if (!Number.isNaN(cursor)) { 292 298 const latest = this.db.prepare(` 293 299 SELECT MAX(id) AS id FROM labels 294 300 `).get() as { id: number }; ··· 336 342 /** 337 343 * Handler for tools.ozone.moderation.emitEvent. 338 344 */ 339 - emitEventHandler: RequestHandler = async (req, res) => { 345 + emitEventHandler: GetMethod = async (req, res) => { 340 346 try { 341 347 const actorDid = await this.parseAuthHeaderDid(req); 342 348 const authed = await this.auth(actorDid); ··· 379 385 }); 380 386 } catch (e) { 381 387 if (e instanceof XRPCError) { 382 - res.status(e.type).json(e.payload); 388 + await res.status(e.type).send(e.payload); 383 389 } else { 384 390 console.error(e); 385 - res.status(500).json({ 391 + await res.status(500).send({ 386 392 error: "InternalServerError", 387 393 message: "An unknown error occurred", 388 394 });
+18
src/util/types.ts
··· 1 1 import type { ComAtprotoLabelDefs } from "@atproto/api"; 2 + import type { WebsocketHandler } from "@fastify/websocket"; 3 + import type { 4 + RawReplyDefaultExpression, 5 + RawRequestDefaultExpression, 6 + RawServerDefault, 7 + RequestGenericInterface, 8 + RouteGenericInterface, 9 + RouteHandlerMethod, 10 + } from "fastify"; 2 11 3 12 export type StrictPartial<T> = 4 13 & { [K in keyof T as undefined extends T[K] ? never : K]: T[K] } 5 14 & { [K in keyof T as undefined extends T[K] ? K : never]?: T[K] }; 6 15 7 16 export type SignedLabel = ComAtprotoLabelDefs.Label & { sig: Uint8Array }; 17 + 18 + export type GetMethod<T extends RouteGenericInterface = RouteGenericInterface> = RouteHandlerMethod< 19 + RawServerDefault, 20 + RawRequestDefaultExpression, 21 + RawReplyDefaultExpression, 22 + T 23 + >; 24 + export type WebSocketMethod<T extends RequestGenericInterface = RequestGenericInterface> = 25 + WebsocketHandler<RawServerDefault, RawRequestDefaultExpression, T>;