Initial backfill idea #2

merged
opened by lewis.moe targeting main

This adds a couple of new forked processes which go and grab all PDSes (in a horrible way) from mary's scraper, then for all pdses go through and get repo history checking for systems.gmstn events. This PR aims to show the idea rather than being polished code, so that we don't waste time polishing a poop!

+1 -8
.example.env
··· 1 - # what to filter by. currently only supports one string. 2 - FILTER_BY= 3 - 4 - # cache location. sqlite db url. technically supports an external cache if you want. 5 - # https://bsky.app/profile/piss.beauty/post/3lkc3efbipc23 6 - # https://bsky.app/profile/nekomimi.pet/post/3m3losk3rys2n 7 - # usually either :memory: or file:path/to/file.db. defaults to ":memory:" 8 - CACHE_LOCATION=":memory:"
··· 1 + DATABASE_URL=postgres://prism:prism@localhost:5432/prism
+4 -6
README.md
··· 1 # Prism 2 3 - Prism is a simple [ATProto](https://atproto.com/) [Relay](https://docs.bsky.app/docs/advanced-guides/firehose) filtering service. Point it to a relay, give it some NSID, partial NSID, or domain authority, and it'll filter relay events for you and store/cache them for future retrieval if you want to. 4 5 <a href="https://docs.bsky.app/docs/advanced-guides/federation-architecture#app-views"> 6 <img src="https://docs.bsky.app/assets/images/app-view-prism-e90e1bf6093bafcb6df2e5c592be1bc6.png" width="400" alt="appview-prism-pinkfloyd"/> 7 </a> 8 9 - For example, if you want to only filter all events relating to `sh.tangled.*`, simply configure your `.env` file with `FILTER_BY="sh.tangled"` and it'll monitor the relay for those records. 10 11 - Other services may subscribe to a Prism instance as though it is a relay itself and receive the filtered events as they are played from the parent relay. 12 13 - Prism also implements a very minimal cache (24h, configurable). Endpoints for accessing the cache are `xrpc` compatible and the lexicons can be found in `lexicons/` 14 - 15 - Backfill coming soon (if you're crazy ig).
··· 1 # Prism 2 3 + Prism is a simple [ATProto](https://atproto.com/) AppView service for gmstn. Point it to a relay and it'll filter relay events for you and store/cache them for future retrieval so that queries aren't so heavy on other PDSes directly. 4 5 <a href="https://docs.bsky.app/docs/advanced-guides/federation-architecture#app-views"> 6 <img src="https://docs.bsky.app/assets/images/app-view-prism-e90e1bf6093bafcb6df2e5c592be1bc6.png" width="400" alt="appview-prism-pinkfloyd"/> 7 </a> 8 9 + Other services may subscribe to a Prism instance as though it is a relay itself and receive the filtered gmstn events as they are played from the parent relay. 10 11 + Prism implements endpoints for accessing the cache feed, which are `xrpc` compatible and the lexicons can be found in `lexicons/`. 12 13 + Backfill batteries included. :3
+16
migrations/20251104191300_create_pds_table.ts
···
··· 1 + import { Kysely, sql } from 'kysely'; 2 + 3 + export async function up(db: Kysely<any>): Promise<void> { 4 + await db.schema 5 + .createTable('pds') 6 + .addColumn('hostname', 'text', (col) => col.primaryKey()) 7 + .addColumn('added_at', 'timestamp', (col) => 8 + col.defaultTo(sql`now()`).notNull() 9 + ) 10 + .addColumn('backfilled_at', 'timestamp') 11 + .execute(); 12 + } 13 + 14 + export async function down(db: Kysely<any>): Promise<void> { 15 + await db.schema.dropTable('pds').execute(); 16 + }
+5
package.json
··· 16 "packageManager": "pnpm@10.20.0", 17 "dependencies": { 18 "@atproto/xrpc-server": "^0.9.5", 19 "@skyware/firehose": "^0.5.2", 20 "dotenv": "^17.2.3", 21 "kysely": "^0.28.8", 22 "pg": "^8.16.3", ··· 25 "devDependencies": { 26 "@atcute/atproto": "^3.1.8", 27 "@types/node": "^24.9.2", 28 "@types/ws": "^8.18.1", 29 "ts-node": "^10.9.2", 30 "tsx": "^4.20.6", 31 "typescript": "^5.9.3" 32 }
··· 16 "packageManager": "pnpm@10.20.0", 17 "dependencies": { 18 "@atproto/xrpc-server": "^0.9.5", 19 + "@ipld/car": "^5.4.2", 20 + "@ipld/dag-cbor": "^9.2.5", 21 "@skyware/firehose": "^0.5.2", 22 + "biome": "^0.3.3", 23 "dotenv": "^17.2.3", 24 "kysely": "^0.28.8", 25 "pg": "^8.16.3", ··· 28 "devDependencies": { 29 "@atcute/atproto": "^3.1.8", 30 "@types/node": "^24.9.2", 31 + "@types/pg": "^8.15.6", 32 "@types/ws": "^8.18.1", 33 "ts-node": "^10.9.2", 34 + "tsconfig-paths": "^4.2.0", 35 "tsx": "^4.20.6", 36 "typescript": "^5.9.3" 37 }
+846
pnpm-lock.yaml
··· 11 '@atproto/xrpc-server': 12 specifier: ^0.9.5 13 version: 0.9.5 14 '@skyware/firehose': 15 specifier: ^0.5.2 16 version: 0.5.2 17 dotenv: 18 specifier: ^17.2.3 19 version: 17.2.3 ··· 33 '@types/node': 34 specifier: ^24.9.2 35 version: 24.9.2 36 '@types/ws': 37 specifier: ^8.18.1 38 version: 8.18.1 39 ts-node: 40 specifier: ^10.9.2 41 version: 10.9.2(@types/node@24.9.2)(typescript@5.9.3) 42 tsx: 43 specifier: ^4.20.6 44 version: 4.20.6 ··· 286 cpu: [x64] 287 os: [win32] 288 289 '@ipld/dag-cbor@7.0.3': 290 resolution: {integrity: sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==} 291 292 '@jridgewell/resolve-uri@3.1.2': 293 resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 294 engines: {node: '>=6.0.0'} ··· 328 '@types/node@24.9.2': 329 resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==} 330 331 '@types/ws@8.18.1': 332 resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} 333 ··· 348 engines: {node: '>=0.4.0'} 349 hasBin: true 350 351 arg@4.1.3: 352 resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} 353 354 array-flatten@1.1.1: 355 resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} 356 357 atomic-sleep@1.0.0: 358 resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} 359 engines: {node: '>=8.0.0'} 360 361 base64-js@1.5.1: 362 resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 363 364 body-parser@1.20.3: 365 resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} 366 engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} 367 368 buffer@6.0.3: 369 resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} 370 ··· 380 resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} 381 engines: {node: '>= 0.4'} 382 383 cbor-extract@2.2.0: 384 resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} 385 hasBin: true ··· 391 resolution: {integrity: sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==} 392 hasBin: true 393 394 content-disposition@0.5.4: 395 resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} 396 engines: {node: '>= 0.6'} ··· 406 resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} 407 engines: {node: '>= 0.6'} 408 409 create-require@1.1.1: 410 resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} 411 412 debug@2.6.9: 413 resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} 414 peerDependencies: ··· 417 supports-color: 418 optional: true 419 420 depd@2.0.0: 421 resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} 422 engines: {node: '>= 0.8'} ··· 441 resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} 442 engines: {node: '>= 0.4'} 443 444 ee-first@1.1.1: 445 resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} 446 ··· 472 escape-html@1.0.3: 473 resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} 474 475 esm-env@1.2.2: 476 resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} 477 ··· 487 resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 488 engines: {node: '>=0.8.x'} 489 490 express@4.21.2: 491 resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} 492 engines: {node: '>= 0.10.0'} 493 494 fast-redact@3.5.0: 495 resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} 496 engines: {node: '>=6'} 497 498 finalhandler@1.3.1: 499 resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} 500 engines: {node: '>= 0.8'} 501 502 forwarded@0.2.0: 503 resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} 504 engines: {node: '>= 0.6'} ··· 507 resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} 508 engines: {node: '>= 0.6'} 509 510 fsevents@2.3.3: 511 resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 512 engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} ··· 526 get-tsconfig@4.13.0: 527 resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} 528 529 gopd@1.2.0: 530 resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} 531 engines: {node: '>= 0.4'} 532 533 graphemer@1.4.0: 534 resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 535 536 has-symbols@1.1.0: 537 resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} 538 engines: {node: '>= 0.4'} ··· 545 resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} 546 engines: {node: '>= 0.8'} 547 548 iconv-lite@0.4.24: 549 resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} 550 engines: {node: '>=0.10.0'} ··· 552 ieee754@1.2.1: 553 resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 554 555 inherits@2.0.4: 556 resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 557 558 ipaddr.js@1.9.1: 559 resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} 560 engines: {node: '>= 0.10'} 561 562 iso-datestring-validator@2.2.2: 563 resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} 564 565 kysely@0.28.8: 566 resolution: {integrity: sha512-QUOgl5ZrS9IRuhq5FvOKFSsD/3+IA6MLE81/bOOTRA/YQpKDza2sFdN5g6JCB9BOpqMJDGefLCQ9F12hRS13TA==} 567 engines: {node: '>=20.0.0'} 568 569 make-error@1.3.6: 570 resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} 571 ··· 597 engines: {node: '>=4'} 598 hasBin: true 599 600 ms@2.0.0: 601 resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} 602 603 ms@2.1.3: 604 resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 605 606 multiformats@9.9.0: 607 resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} 608 609 nanoevents@9.1.0: 610 resolution: {integrity: sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==} 611 engines: {node: ^18.0.0 || >=20.0.0} ··· 618 resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} 619 hasBin: true 620 621 object-inspect@1.13.4: 622 resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} 623 engines: {node: '>= 0.4'} ··· 630 resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} 631 engines: {node: '>= 0.8'} 632 633 parseurl@1.3.3: 634 resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} 635 engines: {node: '>= 0.8'} 636 637 path-to-regexp@0.1.12: 638 resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} 639 640 pg-cloudflare@1.2.7: 641 resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} 642 ··· 708 resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} 709 engines: {node: '>= 0.10'} 710 711 qs@6.13.0: 712 resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} 713 engines: {node: '>=0.6'} 714 715 quick-format-unescaped@4.0.4: 716 resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} 717 ··· 730 resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} 731 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 732 733 real-require@0.2.0: 734 resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} 735 engines: {node: '>= 12.13.0'} 736 737 resolve-pkg-maps@1.0.0: 738 resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 739 740 safe-buffer@5.2.1: 741 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 742 ··· 781 resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} 782 engines: {node: '>= 10.x'} 783 784 statuses@2.0.1: 785 resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} 786 engines: {node: '>= 0.8'} 787 788 string_decoder@1.3.0: 789 resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 790 791 thread-stream@2.7.0: 792 resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} 793 794 toidentifier@1.0.1: 795 resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} 796 engines: {node: '>=0.6'} 797 798 ts-node@10.9.2: 799 resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} 800 hasBin: true ··· 809 '@swc/wasm': 810 optional: true 811 812 tsx@4.20.6: 813 resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} 814 engines: {node: '>=18.0.0'} 815 hasBin: true 816 817 type-is@1.6.18: 818 resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} 819 engines: {node: '>= 0.6'} ··· 833 resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} 834 engines: {node: '>= 0.8'} 835 836 utils-merge@1.0.1: 837 resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} 838 engines: {node: '>= 0.4.0'} 839 840 v8-compile-cache-lib@3.0.1: 841 resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} 842 843 vary@1.1.2: 844 resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} 845 engines: {node: '>= 0.8'} 846 847 ws@8.18.3: 848 resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} 849 engines: {node: '>=10.0.0'} ··· 1065 '@esbuild/win32-x64@0.25.11': 1066 optional: true 1067 1068 '@ipld/dag-cbor@7.0.3': 1069 dependencies: 1070 cborg: 1.10.2 1071 multiformats: 9.9.0 1072 1073 '@jridgewell/resolve-uri@3.1.2': {} 1074 1075 '@jridgewell/sourcemap-codec@1.5.5': {} ··· 1105 dependencies: 1106 undici-types: 7.16.0 1107 1108 '@types/ws@8.18.1': 1109 dependencies: 1110 '@types/node': 24.9.2 ··· 1124 1125 acorn@8.15.0: {} 1126 1127 arg@4.1.3: {} 1128 1129 array-flatten@1.1.1: {} 1130 1131 atomic-sleep@1.0.0: {} 1132 1133 base64-js@1.5.1: {} 1134 1135 body-parser@1.20.3: 1136 dependencies: 1137 bytes: 3.1.2 ··· 1149 transitivePeerDependencies: 1150 - supports-color 1151 1152 buffer@6.0.3: 1153 dependencies: 1154 base64-js: 1.5.1 ··· 1166 call-bind-apply-helpers: 1.0.2 1167 get-intrinsic: 1.3.0 1168 1169 cbor-extract@2.2.0: 1170 dependencies: 1171 node-gyp-build-optional-packages: 5.1.1 ··· 1184 1185 cborg@1.10.2: {} 1186 1187 content-disposition@0.5.4: 1188 dependencies: 1189 safe-buffer: 5.2.1 ··· 1194 1195 cookie@0.7.1: {} 1196 1197 create-require@1.1.1: {} 1198 1199 debug@2.6.9: 1200 dependencies: 1201 ms: 2.0.0 1202 1203 depd@2.0.0: {} 1204 1205 destroy@1.2.0: {} ··· 1217 es-errors: 1.3.0 1218 gopd: 1.2.0 1219 1220 ee-first@1.1.1: {} 1221 1222 encodeurl@1.0.2: {} ··· 1262 1263 escape-html@1.0.3: {} 1264 1265 esm-env@1.2.2: {} 1266 1267 etag@1.8.1: {} ··· 1270 1271 events@3.3.0: {} 1272 1273 express@4.21.2: 1274 dependencies: 1275 accepts: 1.3.8 ··· 1306 transitivePeerDependencies: 1307 - supports-color 1308 1309 fast-redact@3.5.0: {} 1310 1311 finalhandler@1.3.1: 1312 dependencies: 1313 debug: 2.6.9 ··· 1320 transitivePeerDependencies: 1321 - supports-color 1322 1323 forwarded@0.2.0: {} 1324 1325 fresh@0.5.2: {} 1326 1327 fsevents@2.3.3: 1328 optional: true 1329 ··· 1351 dependencies: 1352 resolve-pkg-maps: 1.0.0 1353 1354 gopd@1.2.0: {} 1355 1356 graphemer@1.4.0: {} 1357 1358 has-symbols@1.1.0: {} 1359 1360 hasown@2.0.2: ··· 1369 statuses: 2.0.1 1370 toidentifier: 1.0.1 1371 1372 iconv-lite@0.4.24: 1373 dependencies: 1374 safer-buffer: 2.1.2 1375 1376 ieee754@1.2.1: {} 1377 1378 inherits@2.0.4: {} 1379 1380 ipaddr.js@1.9.1: {} 1381 1382 iso-datestring-validator@2.2.2: {} 1383 1384 kysely@0.28.8: {} 1385 1386 make-error@1.3.6: {} 1387 1388 math-intrinsics@1.1.0: {} ··· 1401 1402 mime@1.6.0: {} 1403 1404 ms@2.0.0: {} 1405 1406 ms@2.1.3: {} 1407 1408 multiformats@9.9.0: {} 1409 1410 nanoevents@9.1.0: {} 1411 1412 negotiator@0.6.3: {} ··· 1416 detect-libc: 2.1.2 1417 optional: true 1418 1419 object-inspect@1.13.4: {} 1420 1421 on-exit-leak-free@2.1.2: {} ··· 1424 dependencies: 1425 ee-first: 1.1.1 1426 1427 parseurl@1.3.3: {} 1428 1429 path-to-regexp@0.1.12: {} 1430 1431 pg-cloudflare@1.2.7: 1432 optional: true 1433 ··· 1503 forwarded: 0.2.0 1504 ipaddr.js: 1.9.1 1505 1506 qs@6.13.0: 1507 dependencies: 1508 side-channel: 1.1.0 1509 1510 quick-format-unescaped@4.0.4: {} 1511 1512 range-parser@1.2.1: {} ··· 1528 process: 0.11.10 1529 string_decoder: 1.3.0 1530 1531 real-require@0.2.0: {} 1532 1533 resolve-pkg-maps@1.0.0: {} 1534 1535 safe-buffer@5.2.1: {} 1536 1537 safe-stable-stringify@2.5.0: {} ··· 1601 1602 split2@4.2.0: {} 1603 1604 statuses@2.0.1: {} 1605 1606 string_decoder@1.3.0: 1607 dependencies: 1608 safe-buffer: 5.2.1 1609 1610 thread-stream@2.7.0: 1611 dependencies: 1612 real-require: 0.2.0 1613 1614 toidentifier@1.0.1: {} 1615 1616 ts-node@10.9.2(@types/node@24.9.2)(typescript@5.9.3): 1617 dependencies: 1618 '@cspotcode/source-map-support': 0.8.1 ··· 1631 v8-compile-cache-lib: 3.0.1 1632 yn: 3.1.1 1633 1634 tsx@4.20.6: 1635 dependencies: 1636 esbuild: 0.25.11 ··· 1638 optionalDependencies: 1639 fsevents: 2.3.3 1640 1641 type-is@1.6.18: 1642 dependencies: 1643 media-typer: 0.3.0 ··· 1653 1654 unpipe@1.0.0: {} 1655 1656 utils-merge@1.0.1: {} 1657 1658 v8-compile-cache-lib@3.0.1: {} 1659 1660 vary@1.1.2: {} 1661 1662 ws@8.18.3: {} 1663 1664 xtend@4.0.2: {}
··· 11 '@atproto/xrpc-server': 12 specifier: ^0.9.5 13 version: 0.9.5 14 + '@ipld/car': 15 + specifier: ^5.4.2 16 + version: 5.4.2 17 + '@ipld/dag-cbor': 18 + specifier: ^9.2.5 19 + version: 9.2.5 20 '@skyware/firehose': 21 specifier: ^0.5.2 22 version: 0.5.2 23 + biome: 24 + specifier: ^0.3.3 25 + version: 0.3.3 26 dotenv: 27 specifier: ^17.2.3 28 version: 17.2.3 ··· 42 '@types/node': 43 specifier: ^24.9.2 44 version: 24.9.2 45 + '@types/pg': 46 + specifier: ^8.15.6 47 + version: 8.15.6 48 '@types/ws': 49 specifier: ^8.18.1 50 version: 8.18.1 51 ts-node: 52 specifier: ^10.9.2 53 version: 10.9.2(@types/node@24.9.2)(typescript@5.9.3) 54 + tsconfig-paths: 55 + specifier: ^4.2.0 56 + version: 4.2.0 57 tsx: 58 specifier: ^4.20.6 59 version: 4.20.6 ··· 301 cpu: [x64] 302 os: [win32] 303 304 + '@ipld/car@5.4.2': 305 + resolution: {integrity: sha512-gfyrJvePyXnh2Fbj8mPg4JYvEZ3izhk8C9WgAle7xIYbrJNSXmNQ6BxAls8Gof97vvGbCROdxbTWRmHJtTCbcg==} 306 + engines: {node: '>=16.0.0', npm: '>=7.0.0'} 307 + 308 '@ipld/dag-cbor@7.0.3': 309 resolution: {integrity: sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==} 310 311 + '@ipld/dag-cbor@9.2.5': 312 + resolution: {integrity: sha512-84wSr4jv30biui7endhobYhXBQzQE4c/wdoWlFrKcfiwH+ofaPg8fwsM8okX9cOzkkrsAsNdDyH3ou+kiLquwQ==} 313 + engines: {node: '>=16.0.0', npm: '>=7.0.0'} 314 + 315 '@jridgewell/resolve-uri@3.1.2': 316 resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 317 engines: {node: '>=6.0.0'} ··· 351 '@types/node@24.9.2': 352 resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==} 353 354 + '@types/pg@8.15.6': 355 + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} 356 + 357 '@types/ws@8.18.1': 358 resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} 359 ··· 374 engines: {node: '>=0.4.0'} 375 hasBin: true 376 377 + ajv@6.12.6: 378 + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 379 + 380 + ansi-escapes@1.4.0: 381 + resolution: {integrity: sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==} 382 + engines: {node: '>=0.10.0'} 383 + 384 + ansi-regex@2.1.1: 385 + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} 386 + engines: {node: '>=0.10.0'} 387 + 388 + ansi-styles@2.2.1: 389 + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} 390 + engines: {node: '>=0.10.0'} 391 + 392 + any-promise@1.3.0: 393 + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 394 + 395 arg@4.1.3: 396 resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} 397 398 array-flatten@1.1.1: 399 resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} 400 401 + asn1@0.2.6: 402 + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} 403 + 404 + assert-plus@1.0.0: 405 + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} 406 + engines: {node: '>=0.8'} 407 + 408 + asynckit@0.4.0: 409 + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} 410 + 411 atomic-sleep@1.0.0: 412 resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} 413 engines: {node: '>=8.0.0'} 414 415 + aws-sign2@0.7.0: 416 + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} 417 + 418 + aws4@1.13.2: 419 + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} 420 + 421 + balanced-match@1.0.2: 422 + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 423 + 424 base64-js@1.5.1: 425 resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 426 427 + bcrypt-pbkdf@1.0.2: 428 + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} 429 + 430 + biome@0.3.3: 431 + resolution: {integrity: sha512-4LXjrQYbn9iTXu9Y4SKT7ABzTV0WnLDHCVSd2fPUOKsy1gQ+E4xPFmlY1zcWexoi0j7fGHItlL6OWA2CZ/yYAQ==} 432 + hasBin: true 433 + 434 + bluebird@3.7.2: 435 + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} 436 + 437 body-parser@1.20.3: 438 resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} 439 engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} 440 441 + brace-expansion@1.1.12: 442 + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} 443 + 444 buffer@6.0.3: 445 resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} 446 ··· 456 resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} 457 engines: {node: '>= 0.4'} 458 459 + caseless@0.12.0: 460 + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} 461 + 462 cbor-extract@2.2.0: 463 resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} 464 hasBin: true ··· 470 resolution: {integrity: sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==} 471 hasBin: true 472 473 + cborg@4.2.18: 474 + resolution: {integrity: sha512-uzhkd5HOaLccokqeZa5B0Qz7/aa9C12pmUq5yU3vcy6I6OhTKdPHSzOuBPZfcoQHdcx8Emz/dWZbPNNfF/puvg==} 475 + hasBin: true 476 + 477 + chalk@1.1.3: 478 + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} 479 + engines: {node: '>=0.10.0'} 480 + 481 + cli-cursor@1.0.2: 482 + resolution: {integrity: sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==} 483 + engines: {node: '>=0.10.0'} 484 + 485 + cli-width@1.1.1: 486 + resolution: {integrity: sha512-eMU2akIeEIkCxGXUNmDnJq1KzOIiPnJ+rKqRe6hcxE3vIOPvpMrBYOn/Bl7zNlYJj/zQxXquAnozHUCf9Whnsg==} 487 + 488 + code-point-at@1.1.0: 489 + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} 490 + engines: {node: '>=0.10.0'} 491 + 492 + combined-stream@1.0.8: 493 + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} 494 + engines: {node: '>= 0.8'} 495 + 496 + commander@2.20.3: 497 + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 498 + 499 + concat-map@0.0.1: 500 + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 501 + 502 content-disposition@0.5.4: 503 resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} 504 engines: {node: '>= 0.6'} ··· 514 resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} 515 engines: {node: '>= 0.6'} 516 517 + core-js@2.6.12: 518 + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} 519 + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. 520 + 521 + core-util-is@1.0.2: 522 + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} 523 + 524 create-require@1.1.1: 525 resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} 526 527 + dashdash@1.14.1: 528 + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} 529 + engines: {node: '>=0.10'} 530 + 531 debug@2.6.9: 532 resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} 533 peerDependencies: ··· 536 supports-color: 537 optional: true 538 539 + delayed-stream@1.0.0: 540 + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} 541 + engines: {node: '>=0.4.0'} 542 + 543 depd@2.0.0: 544 resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} 545 engines: {node: '>= 0.8'} ··· 564 resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} 565 engines: {node: '>= 0.4'} 566 567 + earlgrey-runtime@0.1.2: 568 + resolution: {integrity: sha512-T4qoScXi5TwALDv8nlGTvOuCT8jXcKcxtO8qVdqv46IA2GHJfQzwoBPbkOmORnyhu3A98cVVuhWLsM2CzPljJg==} 569 + 570 + ecc-jsbn@0.1.2: 571 + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} 572 + 573 + editor@1.0.0: 574 + resolution: {integrity: sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw==} 575 + 576 ee-first@1.1.1: 577 resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} 578 ··· 604 escape-html@1.0.3: 605 resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} 606 607 + escape-string-regexp@1.0.5: 608 + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 609 + engines: {node: '>=0.8.0'} 610 + 611 esm-env@1.2.2: 612 resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} 613 ··· 623 resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 624 engines: {node: '>=0.8.x'} 625 626 + exit-hook@1.1.1: 627 + resolution: {integrity: sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==} 628 + engines: {node: '>=0.10.0'} 629 + 630 express@4.21.2: 631 resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} 632 engines: {node: '>= 0.10.0'} 633 634 + extend@3.0.2: 635 + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} 636 + 637 + extsprintf@1.3.0: 638 + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} 639 + engines: {'0': node >=0.6.0} 640 + 641 + fast-deep-equal@3.1.3: 642 + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 643 + 644 + fast-json-stable-stringify@2.1.0: 645 + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 646 + 647 fast-redact@3.5.0: 648 resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} 649 engines: {node: '>=6'} 650 651 + figures@1.7.0: 652 + resolution: {integrity: sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==} 653 + engines: {node: '>=0.10.0'} 654 + 655 finalhandler@1.3.1: 656 resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} 657 engines: {node: '>= 0.8'} 658 659 + forever-agent@0.6.1: 660 + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} 661 + 662 + form-data@2.3.3: 663 + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} 664 + engines: {node: '>= 0.12'} 665 + 666 forwarded@0.2.0: 667 resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} 668 engines: {node: '>= 0.6'} ··· 671 resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} 672 engines: {node: '>= 0.6'} 673 674 + fs-extra@0.26.7: 675 + resolution: {integrity: sha512-waKu+1KumRhYv8D8gMRCKJGAMI9pRnPuEb1mvgYD0f7wBscg+h6bW4FDTmEZhB9VKxvoTtxW+Y7bnIlB7zja6Q==} 676 + 677 + fs-promise@0.5.0: 678 + resolution: {integrity: sha512-Y+4F4ujhEcayCJt6JmzcOun9MYGQwz+bVUiuBmTkJImhBHKpBvmVPZR9wtfiF7k3ffwAOAuurygQe+cPLSFQhw==} 679 + deprecated: Use mz or fs-extra^3.0 with Promise Support 680 + 681 + fs.realpath@1.0.0: 682 + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 683 + 684 fsevents@2.3.3: 685 resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 686 engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} ··· 700 get-tsconfig@4.13.0: 701 resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} 702 703 + getpass@0.1.7: 704 + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} 705 + 706 + glob@7.2.3: 707 + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 708 + deprecated: Glob versions prior to v9 are no longer supported 709 + 710 gopd@1.2.0: 711 resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} 712 engines: {node: '>= 0.4'} 713 714 + graceful-fs@4.2.11: 715 + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 716 + 717 graphemer@1.4.0: 718 resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 719 720 + har-schema@2.0.0: 721 + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} 722 + engines: {node: '>=4'} 723 + 724 + har-validator@5.1.5: 725 + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} 726 + engines: {node: '>=6'} 727 + deprecated: this library is no longer supported 728 + 729 + has-ansi@2.0.0: 730 + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} 731 + engines: {node: '>=0.10.0'} 732 + 733 has-symbols@1.1.0: 734 resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} 735 engines: {node: '>= 0.4'} ··· 742 resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} 743 engines: {node: '>= 0.8'} 744 745 + http-signature@1.2.0: 746 + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} 747 + engines: {node: '>=0.8', npm: '>=1.3.7'} 748 + 749 iconv-lite@0.4.24: 750 resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} 751 engines: {node: '>=0.10.0'} ··· 753 ieee754@1.2.1: 754 resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 755 756 + inflight@1.0.6: 757 + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 758 + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. 759 + 760 inherits@2.0.4: 761 resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 762 763 + inquirer-promise@0.0.3: 764 + resolution: {integrity: sha512-82CQX586JAV9GAgU9yXZsMDs+NorjA0nLhkfFx9+PReyOnuoHRbHrC1Z90sS95bFJI1Tm1gzMObuE0HabzkJpg==} 765 + 766 + inquirer@0.11.4: 767 + resolution: {integrity: sha512-QR+2TW90jnKk9LUUtbcA3yQXKt2rDEKMh6+BAZQIeumtzHexnwVLdPakSslGijXYLJCzFv7GMXbFCn0pA00EUw==} 768 + 769 ipaddr.js@1.9.1: 770 resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} 771 engines: {node: '>= 0.10'} 772 773 + is-fullwidth-code-point@1.0.0: 774 + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} 775 + engines: {node: '>=0.10.0'} 776 + 777 + is-typedarray@1.0.0: 778 + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} 779 + 780 iso-datestring-validator@2.2.2: 781 resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} 782 783 + isstream@0.1.2: 784 + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} 785 + 786 + jsbn@0.1.1: 787 + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} 788 + 789 + json-schema-traverse@0.4.1: 790 + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 791 + 792 + json-schema@0.4.0: 793 + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} 794 + 795 + json-stringify-safe@5.0.1: 796 + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} 797 + 798 + json5@2.2.3: 799 + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 800 + engines: {node: '>=6'} 801 + hasBin: true 802 + 803 + jsonfile@2.4.0: 804 + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} 805 + 806 + jsprim@1.4.2: 807 + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} 808 + engines: {node: '>=0.6.0'} 809 + 810 + kaiser@0.0.4: 811 + resolution: {integrity: sha512-m8ju+rmBqvclZmyrOXgGGhOYSjKJK6RN1NhqEltemY87UqZOxEkizg9TOy1vQSyJ01Wx6SAPuuN0iO2Mgislvw==} 812 + 813 + klaw@1.3.1: 814 + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} 815 + 816 kysely@0.28.8: 817 resolution: {integrity: sha512-QUOgl5ZrS9IRuhq5FvOKFSsD/3+IA6MLE81/bOOTRA/YQpKDza2sFdN5g6JCB9BOpqMJDGefLCQ9F12hRS13TA==} 818 engines: {node: '>=20.0.0'} 819 820 + lodash@3.10.1: 821 + resolution: {integrity: sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==} 822 + 823 + lodash@4.17.21: 824 + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 825 + 826 make-error@1.3.6: 827 resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} 828 ··· 854 engines: {node: '>=4'} 855 hasBin: true 856 857 + minimatch@3.1.2: 858 + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 859 + 860 + minimist@1.2.8: 861 + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 862 + 863 ms@2.0.0: 864 resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} 865 866 ms@2.1.3: 867 resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 868 869 + multiformats@13.4.1: 870 + resolution: {integrity: sha512-VqO6OSvLrFVAYYjgsr8tyv62/rCQhPgsZUXLTqoFLSgdkgiUYKYeArbt1uWLlEpkjxQe+P0+sHlbPEte1Bi06Q==} 871 + 872 multiformats@9.9.0: 873 resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} 874 875 + mute-stream@0.0.5: 876 + resolution: {integrity: sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==} 877 + 878 + mz@2.7.0: 879 + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 880 + 881 nanoevents@9.1.0: 882 resolution: {integrity: sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==} 883 engines: {node: ^18.0.0 || >=20.0.0} ··· 890 resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} 891 hasBin: true 892 893 + number-is-nan@1.0.1: 894 + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} 895 + engines: {node: '>=0.10.0'} 896 + 897 + oauth-sign@0.9.0: 898 + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} 899 + 900 + object-assign@4.1.1: 901 + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 902 + engines: {node: '>=0.10.0'} 903 + 904 object-inspect@1.13.4: 905 resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} 906 engines: {node: '>= 0.4'} ··· 913 resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} 914 engines: {node: '>= 0.8'} 915 916 + once@1.4.0: 917 + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 918 + 919 + onetime@1.1.0: 920 + resolution: {integrity: sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==} 921 + engines: {node: '>=0.10.0'} 922 + 923 + os-homedir@1.0.2: 924 + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} 925 + engines: {node: '>=0.10.0'} 926 + 927 parseurl@1.3.3: 928 resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} 929 engines: {node: '>= 0.8'} 930 931 + path-is-absolute@1.0.1: 932 + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 933 + engines: {node: '>=0.10.0'} 934 + 935 path-to-regexp@0.1.12: 936 resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} 937 938 + performance-now@2.1.0: 939 + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} 940 + 941 pg-cloudflare@1.2.7: 942 resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} 943 ··· 1009 resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} 1010 engines: {node: '>= 0.10'} 1011 1012 + psl@1.15.0: 1013 + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} 1014 + 1015 + punycode@2.3.1: 1016 + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 1017 + engines: {node: '>=6'} 1018 + 1019 qs@6.13.0: 1020 resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} 1021 engines: {node: '>=0.6'} 1022 1023 + qs@6.5.3: 1024 + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} 1025 + engines: {node: '>=0.6'} 1026 + 1027 quick-format-unescaped@4.0.4: 1028 resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} 1029 ··· 1042 resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} 1043 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 1044 1045 + readline2@1.0.1: 1046 + resolution: {integrity: sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==} 1047 + 1048 real-require@0.2.0: 1049 resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} 1050 engines: {node: '>= 12.13.0'} 1051 1052 + regenerator-runtime@0.9.6: 1053 + resolution: {integrity: sha512-D0Y/JJ4VhusyMOd/o25a3jdUqN/bC85EFsaoL9Oqmy/O4efCh+xhp7yj2EEOsj974qvMkcW8AwUzJ1jB/MbxCw==} 1054 + 1055 + request-promise@3.0.0: 1056 + resolution: {integrity: sha512-wVGUX+BoKxYsavTA72i6qHcyLbjzM4LR4y/AmDCqlbuMAursZdDWO7PmgbGAUvD2SeEJ5iB99VSq/U51i/DNbw==} 1057 + engines: {node: '>=0.10.0'} 1058 + deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 1059 + 1060 + request@2.88.2: 1061 + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} 1062 + engines: {node: '>= 6'} 1063 + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 1064 + 1065 resolve-pkg-maps@1.0.0: 1066 resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 1067 1068 + restore-cursor@1.0.1: 1069 + resolution: {integrity: sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==} 1070 + engines: {node: '>=0.10.0'} 1071 + 1072 + rimraf@2.7.1: 1073 + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} 1074 + deprecated: Rimraf versions prior to v4 are no longer supported 1075 + hasBin: true 1076 + 1077 + run-async@0.1.0: 1078 + resolution: {integrity: sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==} 1079 + 1080 + rx-lite@3.1.2: 1081 + resolution: {integrity: sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==} 1082 + 1083 safe-buffer@5.2.1: 1084 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 1085 ··· 1124 resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} 1125 engines: {node: '>= 10.x'} 1126 1127 + sshpk@1.18.0: 1128 + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} 1129 + engines: {node: '>=0.10.0'} 1130 + hasBin: true 1131 + 1132 statuses@2.0.1: 1133 resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} 1134 engines: {node: '>= 0.8'} 1135 1136 + string-width@1.0.2: 1137 + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} 1138 + engines: {node: '>=0.10.0'} 1139 + 1140 string_decoder@1.3.0: 1141 resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 1142 1143 + strip-ansi@3.0.1: 1144 + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} 1145 + engines: {node: '>=0.10.0'} 1146 + 1147 + strip-bom@3.0.0: 1148 + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 1149 + engines: {node: '>=4'} 1150 + 1151 + supports-color@2.0.0: 1152 + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} 1153 + engines: {node: '>=0.8.0'} 1154 + 1155 + thenify-all@1.6.0: 1156 + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 1157 + engines: {node: '>=0.8'} 1158 + 1159 + thenify@3.3.1: 1160 + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} 1161 + 1162 thread-stream@2.7.0: 1163 resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} 1164 1165 + through@2.3.8: 1166 + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} 1167 + 1168 toidentifier@1.0.1: 1169 resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} 1170 engines: {node: '>=0.6'} 1171 1172 + tough-cookie@2.5.0: 1173 + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} 1174 + engines: {node: '>=0.8'} 1175 + 1176 ts-node@10.9.2: 1177 resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} 1178 hasBin: true ··· 1187 '@swc/wasm': 1188 optional: true 1189 1190 + tsconfig-paths@4.2.0: 1191 + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} 1192 + engines: {node: '>=6'} 1193 + 1194 tsx@4.20.6: 1195 resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} 1196 engines: {node: '>=18.0.0'} 1197 hasBin: true 1198 1199 + tunnel-agent@0.6.0: 1200 + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} 1201 + 1202 + tweetnacl@0.14.5: 1203 + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} 1204 + 1205 type-is@1.6.18: 1206 resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} 1207 engines: {node: '>= 0.6'} ··· 1221 resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} 1222 engines: {node: '>= 0.8'} 1223 1224 + untildify@3.0.3: 1225 + resolution: {integrity: sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==} 1226 + engines: {node: '>=4'} 1227 + 1228 + uri-js@4.4.1: 1229 + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1230 + 1231 + user-home@2.0.0: 1232 + resolution: {integrity: sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==} 1233 + engines: {node: '>=0.10.0'} 1234 + 1235 utils-merge@1.0.1: 1236 resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} 1237 engines: {node: '>= 0.4.0'} 1238 1239 + uuid@3.4.0: 1240 + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} 1241 + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. 1242 + hasBin: true 1243 + 1244 v8-compile-cache-lib@3.0.1: 1245 resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} 1246 1247 + varint@6.0.0: 1248 + resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} 1249 + 1250 vary@1.1.2: 1251 resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} 1252 engines: {node: '>= 0.8'} 1253 1254 + verror@1.10.0: 1255 + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} 1256 + engines: {'0': node >=0.6.0} 1257 + 1258 + wrappy@1.0.2: 1259 + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1260 + 1261 ws@8.18.3: 1262 resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} 1263 engines: {node: '>=10.0.0'} ··· 1479 '@esbuild/win32-x64@0.25.11': 1480 optional: true 1481 1482 + '@ipld/car@5.4.2': 1483 + dependencies: 1484 + '@ipld/dag-cbor': 9.2.5 1485 + cborg: 4.2.18 1486 + multiformats: 13.4.1 1487 + varint: 6.0.0 1488 + 1489 '@ipld/dag-cbor@7.0.3': 1490 dependencies: 1491 cborg: 1.10.2 1492 multiformats: 9.9.0 1493 1494 + '@ipld/dag-cbor@9.2.5': 1495 + dependencies: 1496 + cborg: 4.2.18 1497 + multiformats: 13.4.1 1498 + 1499 '@jridgewell/resolve-uri@3.1.2': {} 1500 1501 '@jridgewell/sourcemap-codec@1.5.5': {} ··· 1531 dependencies: 1532 undici-types: 7.16.0 1533 1534 + '@types/pg@8.15.6': 1535 + dependencies: 1536 + '@types/node': 24.9.2 1537 + pg-protocol: 1.10.3 1538 + pg-types: 2.2.0 1539 + 1540 '@types/ws@8.18.1': 1541 dependencies: 1542 '@types/node': 24.9.2 ··· 1556 1557 acorn@8.15.0: {} 1558 1559 + ajv@6.12.6: 1560 + dependencies: 1561 + fast-deep-equal: 3.1.3 1562 + fast-json-stable-stringify: 2.1.0 1563 + json-schema-traverse: 0.4.1 1564 + uri-js: 4.4.1 1565 + 1566 + ansi-escapes@1.4.0: {} 1567 + 1568 + ansi-regex@2.1.1: {} 1569 + 1570 + ansi-styles@2.2.1: {} 1571 + 1572 + any-promise@1.3.0: {} 1573 + 1574 arg@4.1.3: {} 1575 1576 array-flatten@1.1.1: {} 1577 1578 + asn1@0.2.6: 1579 + dependencies: 1580 + safer-buffer: 2.1.2 1581 + 1582 + assert-plus@1.0.0: {} 1583 + 1584 + asynckit@0.4.0: {} 1585 + 1586 atomic-sleep@1.0.0: {} 1587 1588 + aws-sign2@0.7.0: {} 1589 + 1590 + aws4@1.13.2: {} 1591 + 1592 + balanced-match@1.0.2: {} 1593 + 1594 base64-js@1.5.1: {} 1595 1596 + bcrypt-pbkdf@1.0.2: 1597 + dependencies: 1598 + tweetnacl: 0.14.5 1599 + 1600 + biome@0.3.3: 1601 + dependencies: 1602 + bluebird: 3.7.2 1603 + chalk: 1.1.3 1604 + commander: 2.20.3 1605 + editor: 1.0.0 1606 + fs-promise: 0.5.0 1607 + inquirer-promise: 0.0.3 1608 + request-promise: 3.0.0 1609 + untildify: 3.0.3 1610 + user-home: 2.0.0 1611 + 1612 + bluebird@3.7.2: {} 1613 + 1614 body-parser@1.20.3: 1615 dependencies: 1616 bytes: 3.1.2 ··· 1628 transitivePeerDependencies: 1629 - supports-color 1630 1631 + brace-expansion@1.1.12: 1632 + dependencies: 1633 + balanced-match: 1.0.2 1634 + concat-map: 0.0.1 1635 + 1636 buffer@6.0.3: 1637 dependencies: 1638 base64-js: 1.5.1 ··· 1650 call-bind-apply-helpers: 1.0.2 1651 get-intrinsic: 1.3.0 1652 1653 + caseless@0.12.0: {} 1654 + 1655 cbor-extract@2.2.0: 1656 dependencies: 1657 node-gyp-build-optional-packages: 5.1.1 ··· 1670 1671 cborg@1.10.2: {} 1672 1673 + cborg@4.2.18: {} 1674 + 1675 + chalk@1.1.3: 1676 + dependencies: 1677 + ansi-styles: 2.2.1 1678 + escape-string-regexp: 1.0.5 1679 + has-ansi: 2.0.0 1680 + strip-ansi: 3.0.1 1681 + supports-color: 2.0.0 1682 + 1683 + cli-cursor@1.0.2: 1684 + dependencies: 1685 + restore-cursor: 1.0.1 1686 + 1687 + cli-width@1.1.1: {} 1688 + 1689 + code-point-at@1.1.0: {} 1690 + 1691 + combined-stream@1.0.8: 1692 + dependencies: 1693 + delayed-stream: 1.0.0 1694 + 1695 + commander@2.20.3: {} 1696 + 1697 + concat-map@0.0.1: {} 1698 + 1699 content-disposition@0.5.4: 1700 dependencies: 1701 safe-buffer: 5.2.1 ··· 1706 1707 cookie@0.7.1: {} 1708 1709 + core-js@2.6.12: {} 1710 + 1711 + core-util-is@1.0.2: {} 1712 + 1713 create-require@1.1.1: {} 1714 1715 + dashdash@1.14.1: 1716 + dependencies: 1717 + assert-plus: 1.0.0 1718 + 1719 debug@2.6.9: 1720 dependencies: 1721 ms: 2.0.0 1722 1723 + delayed-stream@1.0.0: {} 1724 + 1725 depd@2.0.0: {} 1726 1727 destroy@1.2.0: {} ··· 1739 es-errors: 1.3.0 1740 gopd: 1.2.0 1741 1742 + earlgrey-runtime@0.1.2: 1743 + dependencies: 1744 + core-js: 2.6.12 1745 + kaiser: 0.0.4 1746 + lodash: 4.17.21 1747 + regenerator-runtime: 0.9.6 1748 + 1749 + ecc-jsbn@0.1.2: 1750 + dependencies: 1751 + jsbn: 0.1.1 1752 + safer-buffer: 2.1.2 1753 + 1754 + editor@1.0.0: {} 1755 + 1756 ee-first@1.1.1: {} 1757 1758 encodeurl@1.0.2: {} ··· 1798 1799 escape-html@1.0.3: {} 1800 1801 + escape-string-regexp@1.0.5: {} 1802 + 1803 esm-env@1.2.2: {} 1804 1805 etag@1.8.1: {} ··· 1808 1809 events@3.3.0: {} 1810 1811 + exit-hook@1.1.1: {} 1812 + 1813 express@4.21.2: 1814 dependencies: 1815 accepts: 1.3.8 ··· 1846 transitivePeerDependencies: 1847 - supports-color 1848 1849 + extend@3.0.2: {} 1850 + 1851 + extsprintf@1.3.0: {} 1852 + 1853 + fast-deep-equal@3.1.3: {} 1854 + 1855 + fast-json-stable-stringify@2.1.0: {} 1856 + 1857 fast-redact@3.5.0: {} 1858 1859 + figures@1.7.0: 1860 + dependencies: 1861 + escape-string-regexp: 1.0.5 1862 + object-assign: 4.1.1 1863 + 1864 finalhandler@1.3.1: 1865 dependencies: 1866 debug: 2.6.9 ··· 1873 transitivePeerDependencies: 1874 - supports-color 1875 1876 + forever-agent@0.6.1: {} 1877 + 1878 + form-data@2.3.3: 1879 + dependencies: 1880 + asynckit: 0.4.0 1881 + combined-stream: 1.0.8 1882 + mime-types: 2.1.35 1883 + 1884 forwarded@0.2.0: {} 1885 1886 fresh@0.5.2: {} 1887 1888 + fs-extra@0.26.7: 1889 + dependencies: 1890 + graceful-fs: 4.2.11 1891 + jsonfile: 2.4.0 1892 + klaw: 1.3.1 1893 + path-is-absolute: 1.0.1 1894 + rimraf: 2.7.1 1895 + 1896 + fs-promise@0.5.0: 1897 + dependencies: 1898 + any-promise: 1.3.0 1899 + fs-extra: 0.26.7 1900 + mz: 2.7.0 1901 + thenify-all: 1.6.0 1902 + 1903 + fs.realpath@1.0.0: {} 1904 + 1905 fsevents@2.3.3: 1906 optional: true 1907 ··· 1929 dependencies: 1930 resolve-pkg-maps: 1.0.0 1931 1932 + getpass@0.1.7: 1933 + dependencies: 1934 + assert-plus: 1.0.0 1935 + 1936 + glob@7.2.3: 1937 + dependencies: 1938 + fs.realpath: 1.0.0 1939 + inflight: 1.0.6 1940 + inherits: 2.0.4 1941 + minimatch: 3.1.2 1942 + once: 1.4.0 1943 + path-is-absolute: 1.0.1 1944 + 1945 gopd@1.2.0: {} 1946 1947 + graceful-fs@4.2.11: {} 1948 + 1949 graphemer@1.4.0: {} 1950 1951 + har-schema@2.0.0: {} 1952 + 1953 + har-validator@5.1.5: 1954 + dependencies: 1955 + ajv: 6.12.6 1956 + har-schema: 2.0.0 1957 + 1958 + has-ansi@2.0.0: 1959 + dependencies: 1960 + ansi-regex: 2.1.1 1961 + 1962 has-symbols@1.1.0: {} 1963 1964 hasown@2.0.2: ··· 1973 statuses: 2.0.1 1974 toidentifier: 1.0.1 1975 1976 + http-signature@1.2.0: 1977 + dependencies: 1978 + assert-plus: 1.0.0 1979 + jsprim: 1.4.2 1980 + sshpk: 1.18.0 1981 + 1982 iconv-lite@0.4.24: 1983 dependencies: 1984 safer-buffer: 2.1.2 1985 1986 ieee754@1.2.1: {} 1987 1988 + inflight@1.0.6: 1989 + dependencies: 1990 + once: 1.4.0 1991 + wrappy: 1.0.2 1992 + 1993 inherits@2.0.4: {} 1994 1995 + inquirer-promise@0.0.3: 1996 + dependencies: 1997 + earlgrey-runtime: 0.1.2 1998 + inquirer: 0.11.4 1999 + 2000 + inquirer@0.11.4: 2001 + dependencies: 2002 + ansi-escapes: 1.4.0 2003 + ansi-regex: 2.1.1 2004 + chalk: 1.1.3 2005 + cli-cursor: 1.0.2 2006 + cli-width: 1.1.1 2007 + figures: 1.7.0 2008 + lodash: 3.10.1 2009 + readline2: 1.0.1 2010 + run-async: 0.1.0 2011 + rx-lite: 3.1.2 2012 + string-width: 1.0.2 2013 + strip-ansi: 3.0.1 2014 + through: 2.3.8 2015 + 2016 ipaddr.js@1.9.1: {} 2017 2018 + is-fullwidth-code-point@1.0.0: 2019 + dependencies: 2020 + number-is-nan: 1.0.1 2021 + 2022 + is-typedarray@1.0.0: {} 2023 + 2024 iso-datestring-validator@2.2.2: {} 2025 2026 + isstream@0.1.2: {} 2027 + 2028 + jsbn@0.1.1: {} 2029 + 2030 + json-schema-traverse@0.4.1: {} 2031 + 2032 + json-schema@0.4.0: {} 2033 + 2034 + json-stringify-safe@5.0.1: {} 2035 + 2036 + json5@2.2.3: {} 2037 + 2038 + jsonfile@2.4.0: 2039 + optionalDependencies: 2040 + graceful-fs: 4.2.11 2041 + 2042 + jsprim@1.4.2: 2043 + dependencies: 2044 + assert-plus: 1.0.0 2045 + extsprintf: 1.3.0 2046 + json-schema: 0.4.0 2047 + verror: 1.10.0 2048 + 2049 + kaiser@0.0.4: 2050 + dependencies: 2051 + earlgrey-runtime: 0.1.2 2052 + 2053 + klaw@1.3.1: 2054 + optionalDependencies: 2055 + graceful-fs: 4.2.11 2056 + 2057 kysely@0.28.8: {} 2058 2059 + lodash@3.10.1: {} 2060 + 2061 + lodash@4.17.21: {} 2062 + 2063 make-error@1.3.6: {} 2064 2065 math-intrinsics@1.1.0: {} ··· 2078 2079 mime@1.6.0: {} 2080 2081 + minimatch@3.1.2: 2082 + dependencies: 2083 + brace-expansion: 1.1.12 2084 + 2085 + minimist@1.2.8: {} 2086 + 2087 ms@2.0.0: {} 2088 2089 ms@2.1.3: {} 2090 2091 + multiformats@13.4.1: {} 2092 + 2093 multiformats@9.9.0: {} 2094 2095 + mute-stream@0.0.5: {} 2096 + 2097 + mz@2.7.0: 2098 + dependencies: 2099 + any-promise: 1.3.0 2100 + object-assign: 4.1.1 2101 + thenify-all: 1.6.0 2102 + 2103 nanoevents@9.1.0: {} 2104 2105 negotiator@0.6.3: {} ··· 2109 detect-libc: 2.1.2 2110 optional: true 2111 2112 + number-is-nan@1.0.1: {} 2113 + 2114 + oauth-sign@0.9.0: {} 2115 + 2116 + object-assign@4.1.1: {} 2117 + 2118 object-inspect@1.13.4: {} 2119 2120 on-exit-leak-free@2.1.2: {} ··· 2123 dependencies: 2124 ee-first: 1.1.1 2125 2126 + once@1.4.0: 2127 + dependencies: 2128 + wrappy: 1.0.2 2129 + 2130 + onetime@1.1.0: {} 2131 + 2132 + os-homedir@1.0.2: {} 2133 + 2134 parseurl@1.3.3: {} 2135 2136 + path-is-absolute@1.0.1: {} 2137 + 2138 path-to-regexp@0.1.12: {} 2139 2140 + performance-now@2.1.0: {} 2141 + 2142 pg-cloudflare@1.2.7: 2143 optional: true 2144 ··· 2214 forwarded: 0.2.0 2215 ipaddr.js: 1.9.1 2216 2217 + psl@1.15.0: 2218 + dependencies: 2219 + punycode: 2.3.1 2220 + 2221 + punycode@2.3.1: {} 2222 + 2223 qs@6.13.0: 2224 dependencies: 2225 side-channel: 1.1.0 2226 2227 + qs@6.5.3: {} 2228 + 2229 quick-format-unescaped@4.0.4: {} 2230 2231 range-parser@1.2.1: {} ··· 2247 process: 0.11.10 2248 string_decoder: 1.3.0 2249 2250 + readline2@1.0.1: 2251 + dependencies: 2252 + code-point-at: 1.1.0 2253 + is-fullwidth-code-point: 1.0.0 2254 + mute-stream: 0.0.5 2255 + 2256 real-require@0.2.0: {} 2257 2258 + regenerator-runtime@0.9.6: {} 2259 + 2260 + request-promise@3.0.0: 2261 + dependencies: 2262 + bluebird: 3.7.2 2263 + lodash: 4.17.21 2264 + request: 2.88.2 2265 + 2266 + request@2.88.2: 2267 + dependencies: 2268 + aws-sign2: 0.7.0 2269 + aws4: 1.13.2 2270 + caseless: 0.12.0 2271 + combined-stream: 1.0.8 2272 + extend: 3.0.2 2273 + forever-agent: 0.6.1 2274 + form-data: 2.3.3 2275 + har-validator: 5.1.5 2276 + http-signature: 1.2.0 2277 + is-typedarray: 1.0.0 2278 + isstream: 0.1.2 2279 + json-stringify-safe: 5.0.1 2280 + mime-types: 2.1.35 2281 + oauth-sign: 0.9.0 2282 + performance-now: 2.1.0 2283 + qs: 6.5.3 2284 + safe-buffer: 5.2.1 2285 + tough-cookie: 2.5.0 2286 + tunnel-agent: 0.6.0 2287 + uuid: 3.4.0 2288 + 2289 resolve-pkg-maps@1.0.0: {} 2290 2291 + restore-cursor@1.0.1: 2292 + dependencies: 2293 + exit-hook: 1.1.1 2294 + onetime: 1.1.0 2295 + 2296 + rimraf@2.7.1: 2297 + dependencies: 2298 + glob: 7.2.3 2299 + 2300 + run-async@0.1.0: 2301 + dependencies: 2302 + once: 1.4.0 2303 + 2304 + rx-lite@3.1.2: {} 2305 + 2306 safe-buffer@5.2.1: {} 2307 2308 safe-stable-stringify@2.5.0: {} ··· 2372 2373 split2@4.2.0: {} 2374 2375 + sshpk@1.18.0: 2376 + dependencies: 2377 + asn1: 0.2.6 2378 + assert-plus: 1.0.0 2379 + bcrypt-pbkdf: 1.0.2 2380 + dashdash: 1.14.1 2381 + ecc-jsbn: 0.1.2 2382 + getpass: 0.1.7 2383 + jsbn: 0.1.1 2384 + safer-buffer: 2.1.2 2385 + tweetnacl: 0.14.5 2386 + 2387 statuses@2.0.1: {} 2388 2389 + string-width@1.0.2: 2390 + dependencies: 2391 + code-point-at: 1.1.0 2392 + is-fullwidth-code-point: 1.0.0 2393 + strip-ansi: 3.0.1 2394 + 2395 string_decoder@1.3.0: 2396 dependencies: 2397 safe-buffer: 5.2.1 2398 2399 + strip-ansi@3.0.1: 2400 + dependencies: 2401 + ansi-regex: 2.1.1 2402 + 2403 + strip-bom@3.0.0: {} 2404 + 2405 + supports-color@2.0.0: {} 2406 + 2407 + thenify-all@1.6.0: 2408 + dependencies: 2409 + thenify: 3.3.1 2410 + 2411 + thenify@3.3.1: 2412 + dependencies: 2413 + any-promise: 1.3.0 2414 + 2415 thread-stream@2.7.0: 2416 dependencies: 2417 real-require: 0.2.0 2418 2419 + through@2.3.8: {} 2420 + 2421 toidentifier@1.0.1: {} 2422 2423 + tough-cookie@2.5.0: 2424 + dependencies: 2425 + psl: 1.15.0 2426 + punycode: 2.3.1 2427 + 2428 ts-node@10.9.2(@types/node@24.9.2)(typescript@5.9.3): 2429 dependencies: 2430 '@cspotcode/source-map-support': 0.8.1 ··· 2443 v8-compile-cache-lib: 3.0.1 2444 yn: 3.1.1 2445 2446 + tsconfig-paths@4.2.0: 2447 + dependencies: 2448 + json5: 2.2.3 2449 + minimist: 1.2.8 2450 + strip-bom: 3.0.0 2451 + 2452 tsx@4.20.6: 2453 dependencies: 2454 esbuild: 0.25.11 ··· 2456 optionalDependencies: 2457 fsevents: 2.3.3 2458 2459 + tunnel-agent@0.6.0: 2460 + dependencies: 2461 + safe-buffer: 5.2.1 2462 + 2463 + tweetnacl@0.14.5: {} 2464 + 2465 type-is@1.6.18: 2466 dependencies: 2467 media-typer: 0.3.0 ··· 2477 2478 unpipe@1.0.0: {} 2479 2480 + untildify@3.0.3: {} 2481 + 2482 + uri-js@4.4.1: 2483 + dependencies: 2484 + punycode: 2.3.1 2485 + 2486 + user-home@2.0.0: 2487 + dependencies: 2488 + os-homedir: 1.0.2 2489 + 2490 utils-merge@1.0.1: {} 2491 2492 + uuid@3.4.0: {} 2493 + 2494 v8-compile-cache-lib@3.0.1: {} 2495 2496 + varint@6.0.0: {} 2497 + 2498 vary@1.1.2: {} 2499 2500 + verror@1.10.0: 2501 + dependencies: 2502 + assert-plus: 1.0.0 2503 + core-util-is: 1.0.2 2504 + extsprintf: 1.3.0 2505 + 2506 + wrappy@1.0.2: {} 2507 + 2508 ws@8.18.3: {} 2509 2510 xtend@4.0.2: {}
+21 -38
src/firehose.ts
··· 4 import { Insertable } from "kysely"; 5 import { FirehoseEventTable } from "./db"; 6 7 - const pretty_print = (event_type: string, data: object) => { 8 -     const colors = { 9 -         commit: "\x1b[34m", 10 -         identity: "\x1b[32m", 11 -         account: "\x1b[33m", 12 -         reset: "\x1b[0m", 13 -     }; 14 -     const color = colors[event_type.toLowerCase()] || colors.reset; 15 -     console.debug(`\n${color}## RECEIVED [${event_type.toUpperCase()}] EVENT ##${colors.reset}`); 16 -     console.debug(JSON.stringify( 17 -         data, 18 -         (key, value) => typeof value === 'bigint' ? value.toString() : value, 19 -         2 20 -     )); 21 - }; 22 - 23 const saveEvent = async (type: 'commit' | 'identity' | 'account', data: any) => { 24 - try { 25 - await db.insertInto('firehose_event').values({ 26 - event_type: type, 27 - event_data: data 28 - }).execute(); 29 - } catch (error) { 30 - console.error("\nFailed to save event to database:", error); 31 - } 32 }; 33 34 const main = () => { ··· 38         ws: WebSocket, 39     }); 40 41 -     firehose.on("commit", (commit: CommitEvent) => { 42 - saveEvent('commit', commit); 43         const createOps = commit.ops.filter(op => op.action === 'create'); 44 45         for (const op of createOps) { 46             const recordType = op.record['$type']; 47 48             if (recordType && (recordType.startsWith('com.atproto.') || recordType.startsWith('systems.gmstn.'))) { 49 -                 pretty_print(`COMMIT - ${recordType}`, { 50 -                     repo: commit.repo, 51 -                     path: op.path, 52 -                     record: op.record 53 -                 }); 54             } 55         } 56     }); 57 58 -     firehose.on("identity", (identity: IdentityEvent) => { 59 - saveEvent('identity', identity); 60 -         pretty_print("IDENTITY", identity); 61     }); 62 63 -     firehose.on("account", (account: AccountEvent) => { 64 - saveEvent('account', account); 65 -         pretty_print("ACCOUNT", account); 66     }); 67 68     firehose.on("open", () => { ··· 70     }); 71 72     firehose.on("close", (cursor) => { 73 -         console.log(`\nConnection closed. Last cursor was: ${cursor}`); 74     }); 75 76     firehose.on("error", ({ error, cursor }) => {
··· 4 import { Insertable } from "kysely"; 5 import { FirehoseEventTable } from "./db"; 6 7 const saveEvent = async (type: 'commit' | 'identity' | 'account', data: any) => { 8 +     try { 9 +         await db.insertInto('firehose_event').values({ 10 +             event_type: type, 11 +             event_data: data 12 +         }).execute(); 13 +     } catch (error) { 14 +         console.error("\nFailed to save event to database:", error); 15 +     } 16 }; 17 18 const main = () => { ··· 22         ws: WebSocket, 23     }); 24 25 +     firehose.on("commit", async (commit: CommitEvent) => { 26         const createOps = commit.ops.filter(op => op.action === 'create'); 27 +         const relevantOps = []; 28 29         for (const op of createOps) { 30             const recordType = op.record['$type']; 31 32             if (recordType && (recordType.startsWith('com.atproto.') || recordType.startsWith('systems.gmstn.'))) { 33 +                 relevantOps.push(op); 34             } 35         } 36 + 37 +         if (relevantOps.length > 0) { 38 +             await saveEvent('commit', commit); 39 +         } 40     }); 41 42 +     firehose.on("identity", async (identity: IdentityEvent) => { 43 +         await saveEvent('identity', identity); 44     }); 45 46 +     firehose.on("account", async (account: AccountEvent) => { 47 +         await saveEvent('account', account); 48     }); 49 50     firehose.on("open", () => { ··· 52     }); 53 54     firehose.on("close", (cursor) => { 55 +         console.log(`\nConnection closed. Last cursor was: ${cursor}. Restarting.`); 56 +         firehose.start(); 57     }); 58 59     firehose.on("error", ({ error, cursor }) => {
+10
src/index.ts
··· 3 4 console.log('Main app starting...'); 5 6 const firehosePath = path.resolve(__dirname, 'firehose.ts'); 7 const firehoseProcess = fork(firehosePath); 8
··· 3 4 console.log('Main app starting...'); 5 6 + const pdsListSyncPath = path.resolve(__dirname, 'pds-list-sync.ts'); 7 + const pdsListSyncProcess = fork(pdsListSyncPath); 8 + 9 + console.log(`pdsListSync process started with PID: ${pdsListSyncProcess.pid}`); 10 + 11 + const pdsBackfillPath = path.resolve(__dirname, 'pds-backfill.ts'); 12 + const pdsBackfillProcess = fork(pdsBackfillPath); 13 + 14 + console.log(`pdsBackfill process started with PID: ${pdsBackfillProcess.pid}`); 15 + 16 const firehosePath = path.resolve(__dirname, 'firehose.ts'); 17 const firehoseProcess = fork(firehosePath); 18
+182
src/pds-backfill.ts
···
··· 1 + import { db } from './db'; 2 + 3 + export interface FirehoseEventTable { 4 + timestamp: ColumnType<Date, string | Date, never>; 5 + event_type: string; 6 + event_data: Record<string, any>; 7 + } 8 + export type FirehoseEvent = Selectable<FirehoseEventTable>; 9 + export type NewFirehoseEvent = Insertable<FirehoseEventTable>; 10 + 11 + interface AtpRecord { 12 + $type: string; 13 + createdAt: string; 14 + [key: string]: any; 15 + } 16 + 17 + async function processSingleRepo(pdsHostname: string, did: string) { 18 + const pdsBaseUrl = `https://` + pdsHostname; 19 + const getRepoUrl = new URL(`/xrpc/com.atproto.sync.getRepo`, pdsBaseUrl); 20 + getRepoUrl.searchParams.set('did', did); 21 + 22 + let car: any; 23 + try { 24 + const { CarReader } = await import('@ipld/car'); 25 + 26 + const response = await fetch(getRepoUrl.href); 27 + if (!response.ok) { 28 + throw new Error(`Failed to getRepo for ${did}: ${response.status} ${response.statusText}`); 29 + } 30 + const carBytes = new Uint8Array(await response.arrayBuffer()); 31 + car = await CarReader.fromBytes(carBytes); 32 + } catch (e: any) { 33 + console.error(`[${did}] Failed to fetch or parse CAR: ${e.message}`); 34 + return; 35 + } 36 + 37 + const recordsToInsert: NewFirehoseEvent[] = []; 38 + 39 + try { 40 + const cbor = await import('@ipld/dag-cbor'); 41 + 42 + for await (const block of car.blocks()) { 43 + const record = cbor.decode(block.bytes) as AtpRecord; 44 + 45 + if ( 46 + record && 47 + record.$type && 48 + typeof record.$type === 'string' && 49 + record.$type.startsWith('systems.gmstn.') 50 + ) { 51 + if (!record.createdAt || typeof record.createdAt !== 'string') { 52 + console.warn(`[${did}] Found matching record without valid 'createdAt', skipping.`); 53 + continue; 54 + } 55 + 56 + recordsToInsert.push({ 57 + timestamp: record.createdAt, 58 + event_type: record.$type, 59 + event_data: record, 60 + }); 61 + } 62 + } 63 + } catch (e: any) { 64 + console.error(`[${did}] Error parsing CAR blocks: ${e.message}. Skipping rest of repo.`); 65 + return; 66 + } 67 + 68 + if (recordsToInsert.length > 0) { 69 + try { 70 + await db.insertInto('firehose_event').values(recordsToInsert).execute(); 71 + console.log(`[${did}] Inserted ${recordsToInsert.length} 'systems.gmstn.*' records.`); 72 + } catch (e: any) { 73 + console.error(`[${did}] Failed to insert records into DB: ${e.message}`); 74 + } 75 + } 76 + } 77 + 78 + async function backfillPds(pdsHostname: string) { 79 + console.log(`Starting backfill for: ${pdsHostname}`); 80 + const pdsBaseUrl = `https://` + pdsHostname; 81 + let cursor: string | undefined; 82 + let totalReposProcessed = 0; 83 + 84 + try { 85 + do { 86 + const listReposUrl = new URL('/xrpc/com.atproto.sync.listRepos', pdsBaseUrl); 87 + if (cursor) { 88 + listReposUrl.searchParams.set('cursor', cursor); 89 + } 90 + 91 + const response = await fetch(listReposUrl.href); 92 + if (!response.ok) { 93 + throw new Error(`Failed to listRepos: ${response.status} ${response.statusText}`); 94 + } 95 + 96 + const data = await response.json(); 97 + cursor = data.cursor; 98 + const dids: string[] = data.repos.map((r: { did: string }) => r.did); 99 + 100 + if (dids.length === 0) { 101 + break; 102 + } 103 + 104 + console.log(`Fetched ${dids.length} repos. Cursor: ${cursor}`); 105 + 106 + const BATCH_SIZE = 10; 107 + for (let i = 0; i < dids.length; i += BATCH_SIZE) { 108 + const batch = dids.slice(i, i + BATCH_SIZE); 109 + const tasks = batch.map(did => processSingleRepo(pdsHostname, did)); 110 + await Promise.allSettled(tasks); 111 + } 112 + 113 + totalReposProcessed += dids.length; 114 + 115 + } while (cursor); 116 + 117 + console.log(`[${pdsHostname}] Finished paginating repos.`); 118 + 119 + await db 120 + .updateTable('pds') 121 + .set({ backfilled_at: new Date() }) 122 + .where('hostname', '=', pdsHostname) 123 + .execute(); 124 + 125 + console.log(`Successfully completed backfill for ${pdsHostname}. Total repos: ${totalReposProcessed}`); 126 + 127 + } catch (error) { 128 + console.error(`[${pdsHostname}] Fatal error during backfill:`, error); 129 + throw error; 130 + } 131 + } 132 + 133 + async function main() { 134 + let pdsesToBackfill: { hostname: string }[] = []; 135 + 136 + try { 137 + pdsesToBackfill = await db 138 + .selectFrom('pds') 139 + .select('hostname') 140 + .where('backfilled_at', 'is', null) 141 + .orderBy( 142 + (eb) => eb 143 + .case() 144 + .when('hostname', 'like', '%.bsky.network') 145 + .then(1) 146 + .else(0) 147 + .end(), 148 + 'asc' 149 + ) 150 + .orderBy('added_at', 'asc') 151 + .execute(); 152 + 153 + if (pdsesToBackfill.length === 0) { 154 + console.log('No PDSs to backfill. All caught up! Exiting.'); 155 + await db.destroy(); 156 + return; 157 + } 158 + 159 + console.log(`Found ${pdsesToBackfill.length} PDS(s) to backfill. Starting job...`); 160 + 161 + } catch (e: any) { 162 + console.error('Failed to fetch PDS list from database:', e.message); 163 + process.exit(1); 164 + } 165 + 166 + for (const pds of pdsesToBackfill) { 167 + try { 168 + await backfillPds(pds.hostname); 169 + } catch (e) { 170 + console.error(`---`); 171 + console.error(`Job for ${pds.hostname} failed. Moving to next PDS.`); 172 + console.error(`---`); 173 + } 174 + } 175 + 176 + console.log('All backfill jobs complete. Closing database connection.'); 177 + await db.destroy(); 178 + } 179 + 180 + if (require.main === module) { 181 + main(); 182 + }
+75
src/pds-list-sync.ts
···
··· 1 + import { db } from './db'; 2 + 3 + const PDS_LIST_URL = 'https://raw.githubusercontent.com/mary-ext/atproto-scraping/refs/heads/trunk/state.json'; 4 + 5 + interface StateJson { 6 + pdses: { 7 + [url: string]: { 8 + inviteCodeRequired?: boolean; 9 + version?: string; 10 + } 11 + } 12 + } 13 + 14 + async function syncPdsList() { 15 + console.log('Starting PDS list sync...'); 16 + 17 + try { 18 + const response = await fetch(PDS_LIST_URL); 19 + if (!response.ok) { 20 + throw new Error(`Failed to fetch PDS list: ${response.statusText}`); 21 + } 22 + 23 + const data = (await response.json()) as StateJson; 24 + const pdsUrls = Object.keys(data?.pdses || {}); 25 + 26 + if (pdsUrls.length === 0) { 27 + console.warn('No PDS hosts found in the upstream list.'); 28 + return; 29 + } 30 + 31 + const pdsToInsert = pdsUrls 32 + .map(url => { 33 + try { 34 + return { hostname: new URL(url).hostname }; 35 + } catch (e) { 36 + console.warn(`Invalid URL format in PDS list, skipping: ${url}`); 37 + return null; 38 + } 39 + }) 40 + .filter(Boolean) as { hostname: string }[]; 41 + 42 + if (pdsToInsert.length === 0) { 43 + console.log('No new valid PDS hosts to insert.'); 44 + return; 45 + } 46 + 47 + const result = await db 48 + .insertInto('pds') 49 + .values(pdsToInsert) 50 + .onConflict((oc) => oc 51 + .column('hostname') 52 + .doNothing() 53 + ) 54 + .execute(); 55 + 56 + console.log(`PDS list sync complete. Checked ${pdsToInsert.length} hosts.`); 57 + 58 + } catch (error) { 59 + console.error('Error during PDS list sync:', error); 60 + process.exit(1); 61 + } 62 + } 63 + 64 + if (require.main === module) { 65 + syncPdsList() 66 + .then(() => { 67 + console.log('Sync finished successfully.'); 68 + db.destroy(); 69 + }) 70 + .catch((err) => { 71 + console.error('Unhandled error in syncPdsList:', err); 72 + db.destroy(); 73 + process.exit(1); 74 + }); 75 + }