diff --git a/.example.env b/.example.env
index 9cf7365..d4aca5a 100644
--- a/.example.env
+++ b/.example.env
@@ -1,8 +1 @@
-# what to filter by. currently only supports one string.
-FILTER_BY=
-
-# cache location. sqlite db url. technically supports an external cache if you want.
-# https://bsky.app/profile/piss.beauty/post/3lkc3efbipc23
-# https://bsky.app/profile/nekomimi.pet/post/3m3losk3rys2n
-# usually either :memory: or file:path/to/file.db. defaults to ":memory:"
-CACHE_LOCATION=":memory:"
+DATABASE_URL=postgres://prism:prism@localhost:5432/prism
diff --git a/README.md b/README.md
index 87bf3a6..58d2975 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,13 @@
# Prism
-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.
+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.
-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.
+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.
-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.
+Prism implements endpoints for accessing the cache feed, which are `xrpc` compatible and the lexicons can be found in `lexicons/`.
-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/`
-
-Backfill coming soon (if you're crazy ig).
+Backfill batteries included. :3
diff --git a/migrations/20251104191300_create_pds_table.ts b/migrations/20251104191300_create_pds_table.ts
new file mode 100644
index 0000000..27a3ac8
--- /dev/null
+++ b/migrations/20251104191300_create_pds_table.ts
@@ -0,0 +1,16 @@
+import { Kysely, sql } from 'kysely';
+
+export async function up(db: Kysely): Promise {
+ await db.schema
+ .createTable('pds')
+ .addColumn('hostname', 'text', (col) => col.primaryKey())
+ .addColumn('added_at', 'timestamp', (col) =>
+ col.defaultTo(sql`now()`).notNull()
+ )
+ .addColumn('backfilled_at', 'timestamp')
+ .execute();
+}
+
+export async function down(db: Kysely): Promise {
+ await db.schema.dropTable('pds').execute();
+}
diff --git a/package.json b/package.json
index 639ea79..dd2a790 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,10 @@
"packageManager": "pnpm@10.20.0",
"dependencies": {
"@atproto/xrpc-server": "^0.9.5",
+ "@ipld/car": "^5.4.2",
+ "@ipld/dag-cbor": "^9.2.5",
"@skyware/firehose": "^0.5.2",
+ "biome": "^0.3.3",
"dotenv": "^17.2.3",
"kysely": "^0.28.8",
"pg": "^8.16.3",
@@ -25,8 +28,10 @@
"devDependencies": {
"@atcute/atproto": "^3.1.8",
"@types/node": "^24.9.2",
+ "@types/pg": "^8.15.6",
"@types/ws": "^8.18.1",
"ts-node": "^10.9.2",
+ "tsconfig-paths": "^4.2.0",
"tsx": "^4.20.6",
"typescript": "^5.9.3"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e2d9ca2..2a1140b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,9 +11,18 @@ importers:
'@atproto/xrpc-server':
specifier: ^0.9.5
version: 0.9.5
+ '@ipld/car':
+ specifier: ^5.4.2
+ version: 5.4.2
+ '@ipld/dag-cbor':
+ specifier: ^9.2.5
+ version: 9.2.5
'@skyware/firehose':
specifier: ^0.5.2
version: 0.5.2
+ biome:
+ specifier: ^0.3.3
+ version: 0.3.3
dotenv:
specifier: ^17.2.3
version: 17.2.3
@@ -33,12 +42,18 @@ importers:
'@types/node':
specifier: ^24.9.2
version: 24.9.2
+ '@types/pg':
+ specifier: ^8.15.6
+ version: 8.15.6
'@types/ws':
specifier: ^8.18.1
version: 8.18.1
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@24.9.2)(typescript@5.9.3)
+ tsconfig-paths:
+ specifier: ^4.2.0
+ version: 4.2.0
tsx:
specifier: ^4.20.6
version: 4.20.6
@@ -286,9 +301,17 @@ packages:
cpu: [x64]
os: [win32]
+ '@ipld/car@5.4.2':
+ resolution: {integrity: sha512-gfyrJvePyXnh2Fbj8mPg4JYvEZ3izhk8C9WgAle7xIYbrJNSXmNQ6BxAls8Gof97vvGbCROdxbTWRmHJtTCbcg==}
+ engines: {node: '>=16.0.0', npm: '>=7.0.0'}
+
'@ipld/dag-cbor@7.0.3':
resolution: {integrity: sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==}
+ '@ipld/dag-cbor@9.2.5':
+ resolution: {integrity: sha512-84wSr4jv30biui7endhobYhXBQzQE4c/wdoWlFrKcfiwH+ofaPg8fwsM8okX9cOzkkrsAsNdDyH3ou+kiLquwQ==}
+ engines: {node: '>=16.0.0', npm: '>=7.0.0'}
+
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
@@ -328,6 +351,9 @@ packages:
'@types/node@24.9.2':
resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==}
+ '@types/pg@8.15.6':
+ resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==}
+
'@types/ws@8.18.1':
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
@@ -348,23 +374,73 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
+ ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+
+ ansi-escapes@1.4.0:
+ resolution: {integrity: sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==}
+ engines: {node: '>=0.10.0'}
+
+ ansi-regex@2.1.1:
+ resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
+ engines: {node: '>=0.10.0'}
+
+ ansi-styles@2.2.1:
+ resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==}
+ engines: {node: '>=0.10.0'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
array-flatten@1.1.1:
resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
+ asn1@0.2.6:
+ resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
+
+ assert-plus@1.0.0:
+ resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
+ engines: {node: '>=0.8'}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
atomic-sleep@1.0.0:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
+ aws-sign2@0.7.0:
+ resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
+
+ aws4@1.13.2:
+ resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+ bcrypt-pbkdf@1.0.2:
+ resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
+
+ biome@0.3.3:
+ resolution: {integrity: sha512-4LXjrQYbn9iTXu9Y4SKT7ABzTV0WnLDHCVSd2fPUOKsy1gQ+E4xPFmlY1zcWexoi0j7fGHItlL6OWA2CZ/yYAQ==}
+ hasBin: true
+
+ bluebird@3.7.2:
+ resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
+
body-parser@1.20.3:
resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+ brace-expansion@1.1.12:
+ resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
+
buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
@@ -380,6 +456,9 @@ packages:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
engines: {node: '>= 0.4'}
+ caseless@0.12.0:
+ resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
+
cbor-extract@2.2.0:
resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==}
hasBin: true
@@ -391,6 +470,35 @@ packages:
resolution: {integrity: sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==}
hasBin: true
+ cborg@4.2.18:
+ resolution: {integrity: sha512-uzhkd5HOaLccokqeZa5B0Qz7/aa9C12pmUq5yU3vcy6I6OhTKdPHSzOuBPZfcoQHdcx8Emz/dWZbPNNfF/puvg==}
+ hasBin: true
+
+ chalk@1.1.3:
+ resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
+ engines: {node: '>=0.10.0'}
+
+ cli-cursor@1.0.2:
+ resolution: {integrity: sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==}
+ engines: {node: '>=0.10.0'}
+
+ cli-width@1.1.1:
+ resolution: {integrity: sha512-eMU2akIeEIkCxGXUNmDnJq1KzOIiPnJ+rKqRe6hcxE3vIOPvpMrBYOn/Bl7zNlYJj/zQxXquAnozHUCf9Whnsg==}
+
+ code-point-at@1.1.0:
+ resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==}
+ engines: {node: '>=0.10.0'}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@@ -406,9 +514,20 @@ packages:
resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
engines: {node: '>= 0.6'}
+ core-js@2.6.12:
+ resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==}
+ 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.
+
+ core-util-is@1.0.2:
+ resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
+
create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+ dashdash@1.14.1:
+ resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==}
+ engines: {node: '>=0.10'}
+
debug@2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
peerDependencies:
@@ -417,6 +536,10 @@ packages:
supports-color:
optional: true
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
@@ -441,6 +564,15 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
+ earlgrey-runtime@0.1.2:
+ resolution: {integrity: sha512-T4qoScXi5TwALDv8nlGTvOuCT8jXcKcxtO8qVdqv46IA2GHJfQzwoBPbkOmORnyhu3A98cVVuhWLsM2CzPljJg==}
+
+ ecc-jsbn@0.1.2:
+ resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
+
+ editor@1.0.0:
+ resolution: {integrity: sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw==}
+
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@@ -472,6 +604,10 @@ packages:
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+ escape-string-regexp@1.0.5:
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+ engines: {node: '>=0.8.0'}
+
esm-env@1.2.2:
resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==}
@@ -487,18 +623,46 @@ packages:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
+ exit-hook@1.1.1:
+ resolution: {integrity: sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==}
+ engines: {node: '>=0.10.0'}
+
express@4.21.2:
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
engines: {node: '>= 0.10.0'}
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ extsprintf@1.3.0:
+ resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==}
+ engines: {'0': node >=0.6.0}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
fast-redact@3.5.0:
resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==}
engines: {node: '>=6'}
+ figures@1.7.0:
+ resolution: {integrity: sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==}
+ engines: {node: '>=0.10.0'}
+
finalhandler@1.3.1:
resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
engines: {node: '>= 0.8'}
+ forever-agent@0.6.1:
+ resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
+
+ form-data@2.3.3:
+ resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==}
+ engines: {node: '>= 0.12'}
+
forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
@@ -507,6 +671,16 @@ packages:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
+ fs-extra@0.26.7:
+ resolution: {integrity: sha512-waKu+1KumRhYv8D8gMRCKJGAMI9pRnPuEb1mvgYD0f7wBscg+h6bW4FDTmEZhB9VKxvoTtxW+Y7bnIlB7zja6Q==}
+
+ fs-promise@0.5.0:
+ resolution: {integrity: sha512-Y+4F4ujhEcayCJt6JmzcOun9MYGQwz+bVUiuBmTkJImhBHKpBvmVPZR9wtfiF7k3ffwAOAuurygQe+cPLSFQhw==}
+ deprecated: Use mz or fs-extra^3.0 with Promise Support
+
+ fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -526,13 +700,36 @@ packages:
get-tsconfig@4.13.0:
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
+ getpass@0.1.7:
+ resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==}
+
+ glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Glob versions prior to v9 are no longer supported
+
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+ har-schema@2.0.0:
+ resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==}
+ engines: {node: '>=4'}
+
+ har-validator@5.1.5:
+ resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==}
+ engines: {node: '>=6'}
+ deprecated: this library is no longer supported
+
+ has-ansi@2.0.0:
+ resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==}
+ engines: {node: '>=0.10.0'}
+
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
@@ -545,6 +742,10 @@ packages:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
+ http-signature@1.2.0:
+ resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==}
+ engines: {node: '>=0.8', npm: '>=1.3.7'}
+
iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@@ -552,20 +753,76 @@ packages:
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+ inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ 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.
+
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ inquirer-promise@0.0.3:
+ resolution: {integrity: sha512-82CQX586JAV9GAgU9yXZsMDs+NorjA0nLhkfFx9+PReyOnuoHRbHrC1Z90sS95bFJI1Tm1gzMObuE0HabzkJpg==}
+
+ inquirer@0.11.4:
+ resolution: {integrity: sha512-QR+2TW90jnKk9LUUtbcA3yQXKt2rDEKMh6+BAZQIeumtzHexnwVLdPakSslGijXYLJCzFv7GMXbFCn0pA00EUw==}
+
ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
+ is-fullwidth-code-point@1.0.0:
+ resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==}
+ engines: {node: '>=0.10.0'}
+
+ is-typedarray@1.0.0:
+ resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
+
iso-datestring-validator@2.2.2:
resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==}
+ isstream@0.1.2:
+ resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
+
+ jsbn@0.1.1:
+ resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-schema@0.4.0:
+ resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
+
+ json-stringify-safe@5.0.1:
+ resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ jsonfile@2.4.0:
+ resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==}
+
+ jsprim@1.4.2:
+ resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==}
+ engines: {node: '>=0.6.0'}
+
+ kaiser@0.0.4:
+ resolution: {integrity: sha512-m8ju+rmBqvclZmyrOXgGGhOYSjKJK6RN1NhqEltemY87UqZOxEkizg9TOy1vQSyJ01Wx6SAPuuN0iO2Mgislvw==}
+
+ klaw@1.3.1:
+ resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==}
+
kysely@0.28.8:
resolution: {integrity: sha512-QUOgl5ZrS9IRuhq5FvOKFSsD/3+IA6MLE81/bOOTRA/YQpKDza2sFdN5g6JCB9BOpqMJDGefLCQ9F12hRS13TA==}
engines: {node: '>=20.0.0'}
+ lodash@3.10.1:
+ resolution: {integrity: sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==}
+
+ lodash@4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
@@ -597,15 +854,30 @@ packages:
engines: {node: '>=4'}
hasBin: true
+ minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
ms@2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ multiformats@13.4.1:
+ resolution: {integrity: sha512-VqO6OSvLrFVAYYjgsr8tyv62/rCQhPgsZUXLTqoFLSgdkgiUYKYeArbt1uWLlEpkjxQe+P0+sHlbPEte1Bi06Q==}
+
multiformats@9.9.0:
resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==}
+ mute-stream@0.0.5:
+ resolution: {integrity: sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
nanoevents@9.1.0:
resolution: {integrity: sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -618,6 +890,17 @@ packages:
resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==}
hasBin: true
+ number-is-nan@1.0.1:
+ resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
+ engines: {node: '>=0.10.0'}
+
+ oauth-sign@0.9.0:
+ resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
object-inspect@1.13.4:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
@@ -630,13 +913,31 @@ packages:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ onetime@1.1.0:
+ resolution: {integrity: sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==}
+ engines: {node: '>=0.10.0'}
+
+ os-homedir@1.0.2:
+ resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==}
+ engines: {node: '>=0.10.0'}
+
parseurl@1.3.3:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
path-to-regexp@0.1.12:
resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
+ performance-now@2.1.0:
+ resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
+
pg-cloudflare@1.2.7:
resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==}
@@ -708,10 +1009,21 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
+ psl@1.15.0:
+ resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
qs@6.13.0:
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
engines: {node: '>=0.6'}
+ qs@6.5.3:
+ resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
+ engines: {node: '>=0.6'}
+
quick-format-unescaped@4.0.4:
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
@@ -730,13 +1042,44 @@ packages:
resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ readline2@1.0.1:
+ resolution: {integrity: sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==}
+
real-require@0.2.0:
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
engines: {node: '>= 12.13.0'}
+ regenerator-runtime@0.9.6:
+ resolution: {integrity: sha512-D0Y/JJ4VhusyMOd/o25a3jdUqN/bC85EFsaoL9Oqmy/O4efCh+xhp7yj2EEOsj974qvMkcW8AwUzJ1jB/MbxCw==}
+
+ request-promise@3.0.0:
+ resolution: {integrity: sha512-wVGUX+BoKxYsavTA72i6qHcyLbjzM4LR4y/AmDCqlbuMAursZdDWO7PmgbGAUvD2SeEJ5iB99VSq/U51i/DNbw==}
+ engines: {node: '>=0.10.0'}
+ deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
+
+ request@2.88.2:
+ resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==}
+ engines: {node: '>= 6'}
+ deprecated: request has been deprecated, see https://github.com/request/request/issues/3142
+
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+ restore-cursor@1.0.1:
+ resolution: {integrity: sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==}
+ engines: {node: '>=0.10.0'}
+
+ rimraf@2.7.1:
+ resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
+ deprecated: Rimraf versions prior to v4 are no longer supported
+ hasBin: true
+
+ run-async@0.1.0:
+ resolution: {integrity: sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==}
+
+ rx-lite@3.1.2:
+ resolution: {integrity: sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==}
+
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
@@ -781,20 +1124,55 @@ packages:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
+ sshpk@1.18.0:
+ resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==}
+ engines: {node: '>=0.10.0'}
+ hasBin: true
+
statuses@2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
+ string-width@1.0.2:
+ resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==}
+ engines: {node: '>=0.10.0'}
+
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+ strip-ansi@3.0.1:
+ resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==}
+ engines: {node: '>=0.10.0'}
+
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ supports-color@2.0.0:
+ resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==}
+ engines: {node: '>=0.8.0'}
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
thread-stream@2.7.0:
resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==}
+ through@2.3.8:
+ resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
+
toidentifier@1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
+ tough-cookie@2.5.0:
+ resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==}
+ engines: {node: '>=0.8'}
+
ts-node@10.9.2:
resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
hasBin: true
@@ -809,11 +1187,21 @@ packages:
'@swc/wasm':
optional: true
+ tsconfig-paths@4.2.0:
+ resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
+ engines: {node: '>=6'}
+
tsx@4.20.6:
resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==}
engines: {node: '>=18.0.0'}
hasBin: true
+ tunnel-agent@0.6.0:
+ resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
+
+ tweetnacl@0.14.5:
+ resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
+
type-is@1.6.18:
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
engines: {node: '>= 0.6'}
@@ -833,17 +1221,43 @@ packages:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
+ untildify@3.0.3:
+ resolution: {integrity: sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==}
+ engines: {node: '>=4'}
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ user-home@2.0.0:
+ resolution: {integrity: sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==}
+ engines: {node: '>=0.10.0'}
+
utils-merge@1.0.1:
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
engines: {node: '>= 0.4.0'}
+ uuid@3.4.0:
+ resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
+ 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.
+ hasBin: true
+
v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+ varint@6.0.0:
+ resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
+
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
+ verror@1.10.0:
+ resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==}
+ engines: {'0': node >=0.6.0}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
ws@8.18.3:
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
engines: {node: '>=10.0.0'}
@@ -1065,11 +1479,23 @@ snapshots:
'@esbuild/win32-x64@0.25.11':
optional: true
+ '@ipld/car@5.4.2':
+ dependencies:
+ '@ipld/dag-cbor': 9.2.5
+ cborg: 4.2.18
+ multiformats: 13.4.1
+ varint: 6.0.0
+
'@ipld/dag-cbor@7.0.3':
dependencies:
cborg: 1.10.2
multiformats: 9.9.0
+ '@ipld/dag-cbor@9.2.5':
+ dependencies:
+ cborg: 4.2.18
+ multiformats: 13.4.1
+
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/sourcemap-codec@1.5.5': {}
@@ -1105,6 +1531,12 @@ snapshots:
dependencies:
undici-types: 7.16.0
+ '@types/pg@8.15.6':
+ dependencies:
+ '@types/node': 24.9.2
+ pg-protocol: 1.10.3
+ pg-types: 2.2.0
+
'@types/ws@8.18.1':
dependencies:
'@types/node': 24.9.2
@@ -1124,14 +1556,61 @@ snapshots:
acorn@8.15.0: {}
+ ajv@6.12.6:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ansi-escapes@1.4.0: {}
+
+ ansi-regex@2.1.1: {}
+
+ ansi-styles@2.2.1: {}
+
+ any-promise@1.3.0: {}
+
arg@4.1.3: {}
array-flatten@1.1.1: {}
+ asn1@0.2.6:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ assert-plus@1.0.0: {}
+
+ asynckit@0.4.0: {}
+
atomic-sleep@1.0.0: {}
+ aws-sign2@0.7.0: {}
+
+ aws4@1.13.2: {}
+
+ balanced-match@1.0.2: {}
+
base64-js@1.5.1: {}
+ bcrypt-pbkdf@1.0.2:
+ dependencies:
+ tweetnacl: 0.14.5
+
+ biome@0.3.3:
+ dependencies:
+ bluebird: 3.7.2
+ chalk: 1.1.3
+ commander: 2.20.3
+ editor: 1.0.0
+ fs-promise: 0.5.0
+ inquirer-promise: 0.0.3
+ request-promise: 3.0.0
+ untildify: 3.0.3
+ user-home: 2.0.0
+
+ bluebird@3.7.2: {}
+
body-parser@1.20.3:
dependencies:
bytes: 3.1.2
@@ -1149,6 +1628,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ brace-expansion@1.1.12:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
buffer@6.0.3:
dependencies:
base64-js: 1.5.1
@@ -1166,6 +1650,8 @@ snapshots:
call-bind-apply-helpers: 1.0.2
get-intrinsic: 1.3.0
+ caseless@0.12.0: {}
+
cbor-extract@2.2.0:
dependencies:
node-gyp-build-optional-packages: 5.1.1
@@ -1184,6 +1670,32 @@ snapshots:
cborg@1.10.2: {}
+ cborg@4.2.18: {}
+
+ chalk@1.1.3:
+ dependencies:
+ ansi-styles: 2.2.1
+ escape-string-regexp: 1.0.5
+ has-ansi: 2.0.0
+ strip-ansi: 3.0.1
+ supports-color: 2.0.0
+
+ cli-cursor@1.0.2:
+ dependencies:
+ restore-cursor: 1.0.1
+
+ cli-width@1.1.1: {}
+
+ code-point-at@1.1.0: {}
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ commander@2.20.3: {}
+
+ concat-map@0.0.1: {}
+
content-disposition@0.5.4:
dependencies:
safe-buffer: 5.2.1
@@ -1194,12 +1706,22 @@ snapshots:
cookie@0.7.1: {}
+ core-js@2.6.12: {}
+
+ core-util-is@1.0.2: {}
+
create-require@1.1.1: {}
+ dashdash@1.14.1:
+ dependencies:
+ assert-plus: 1.0.0
+
debug@2.6.9:
dependencies:
ms: 2.0.0
+ delayed-stream@1.0.0: {}
+
depd@2.0.0: {}
destroy@1.2.0: {}
@@ -1217,6 +1739,20 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
+ earlgrey-runtime@0.1.2:
+ dependencies:
+ core-js: 2.6.12
+ kaiser: 0.0.4
+ lodash: 4.17.21
+ regenerator-runtime: 0.9.6
+
+ ecc-jsbn@0.1.2:
+ dependencies:
+ jsbn: 0.1.1
+ safer-buffer: 2.1.2
+
+ editor@1.0.0: {}
+
ee-first@1.1.1: {}
encodeurl@1.0.2: {}
@@ -1262,6 +1798,8 @@ snapshots:
escape-html@1.0.3: {}
+ escape-string-regexp@1.0.5: {}
+
esm-env@1.2.2: {}
etag@1.8.1: {}
@@ -1270,6 +1808,8 @@ snapshots:
events@3.3.0: {}
+ exit-hook@1.1.1: {}
+
express@4.21.2:
dependencies:
accepts: 1.3.8
@@ -1306,8 +1846,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ extend@3.0.2: {}
+
+ extsprintf@1.3.0: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-json-stable-stringify@2.1.0: {}
+
fast-redact@3.5.0: {}
+ figures@1.7.0:
+ dependencies:
+ escape-string-regexp: 1.0.5
+ object-assign: 4.1.1
+
finalhandler@1.3.1:
dependencies:
debug: 2.6.9
@@ -1320,10 +1873,35 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ forever-agent@0.6.1: {}
+
+ form-data@2.3.3:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+
forwarded@0.2.0: {}
fresh@0.5.2: {}
+ fs-extra@0.26.7:
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 2.4.0
+ klaw: 1.3.1
+ path-is-absolute: 1.0.1
+ rimraf: 2.7.1
+
+ fs-promise@0.5.0:
+ dependencies:
+ any-promise: 1.3.0
+ fs-extra: 0.26.7
+ mz: 2.7.0
+ thenify-all: 1.6.0
+
+ fs.realpath@1.0.0: {}
+
fsevents@2.3.3:
optional: true
@@ -1351,10 +1929,36 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
+ getpass@0.1.7:
+ dependencies:
+ assert-plus: 1.0.0
+
+ glob@7.2.3:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
gopd@1.2.0: {}
+ graceful-fs@4.2.11: {}
+
graphemer@1.4.0: {}
+ har-schema@2.0.0: {}
+
+ har-validator@5.1.5:
+ dependencies:
+ ajv: 6.12.6
+ har-schema: 2.0.0
+
+ has-ansi@2.0.0:
+ dependencies:
+ ansi-regex: 2.1.1
+
has-symbols@1.1.0: {}
hasown@2.0.2:
@@ -1369,20 +1973,93 @@ snapshots:
statuses: 2.0.1
toidentifier: 1.0.1
+ http-signature@1.2.0:
+ dependencies:
+ assert-plus: 1.0.0
+ jsprim: 1.4.2
+ sshpk: 1.18.0
+
iconv-lite@0.4.24:
dependencies:
safer-buffer: 2.1.2
ieee754@1.2.1: {}
+ inflight@1.0.6:
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
inherits@2.0.4: {}
+ inquirer-promise@0.0.3:
+ dependencies:
+ earlgrey-runtime: 0.1.2
+ inquirer: 0.11.4
+
+ inquirer@0.11.4:
+ dependencies:
+ ansi-escapes: 1.4.0
+ ansi-regex: 2.1.1
+ chalk: 1.1.3
+ cli-cursor: 1.0.2
+ cli-width: 1.1.1
+ figures: 1.7.0
+ lodash: 3.10.1
+ readline2: 1.0.1
+ run-async: 0.1.0
+ rx-lite: 3.1.2
+ string-width: 1.0.2
+ strip-ansi: 3.0.1
+ through: 2.3.8
+
ipaddr.js@1.9.1: {}
+ is-fullwidth-code-point@1.0.0:
+ dependencies:
+ number-is-nan: 1.0.1
+
+ is-typedarray@1.0.0: {}
+
iso-datestring-validator@2.2.2: {}
+ isstream@0.1.2: {}
+
+ jsbn@0.1.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-schema@0.4.0: {}
+
+ json-stringify-safe@5.0.1: {}
+
+ json5@2.2.3: {}
+
+ jsonfile@2.4.0:
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
+ jsprim@1.4.2:
+ dependencies:
+ assert-plus: 1.0.0
+ extsprintf: 1.3.0
+ json-schema: 0.4.0
+ verror: 1.10.0
+
+ kaiser@0.0.4:
+ dependencies:
+ earlgrey-runtime: 0.1.2
+
+ klaw@1.3.1:
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
kysely@0.28.8: {}
+ lodash@3.10.1: {}
+
+ lodash@4.17.21: {}
+
make-error@1.3.6: {}
math-intrinsics@1.1.0: {}
@@ -1401,12 +2078,28 @@ snapshots:
mime@1.6.0: {}
+ minimatch@3.1.2:
+ dependencies:
+ brace-expansion: 1.1.12
+
+ minimist@1.2.8: {}
+
ms@2.0.0: {}
ms@2.1.3: {}
+ multiformats@13.4.1: {}
+
multiformats@9.9.0: {}
+ mute-stream@0.0.5: {}
+
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
nanoevents@9.1.0: {}
negotiator@0.6.3: {}
@@ -1416,6 +2109,12 @@ snapshots:
detect-libc: 2.1.2
optional: true
+ number-is-nan@1.0.1: {}
+
+ oauth-sign@0.9.0: {}
+
+ object-assign@4.1.1: {}
+
object-inspect@1.13.4: {}
on-exit-leak-free@2.1.2: {}
@@ -1424,10 +2123,22 @@ snapshots:
dependencies:
ee-first: 1.1.1
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ onetime@1.1.0: {}
+
+ os-homedir@1.0.2: {}
+
parseurl@1.3.3: {}
+ path-is-absolute@1.0.1: {}
+
path-to-regexp@0.1.12: {}
+ performance-now@2.1.0: {}
+
pg-cloudflare@1.2.7:
optional: true
@@ -1503,10 +2214,18 @@ snapshots:
forwarded: 0.2.0
ipaddr.js: 1.9.1
+ psl@1.15.0:
+ dependencies:
+ punycode: 2.3.1
+
+ punycode@2.3.1: {}
+
qs@6.13.0:
dependencies:
side-channel: 1.1.0
+ qs@6.5.3: {}
+
quick-format-unescaped@4.0.4: {}
range-parser@1.2.1: {}
@@ -1528,10 +2247,62 @@ snapshots:
process: 0.11.10
string_decoder: 1.3.0
+ readline2@1.0.1:
+ dependencies:
+ code-point-at: 1.1.0
+ is-fullwidth-code-point: 1.0.0
+ mute-stream: 0.0.5
+
real-require@0.2.0: {}
+ regenerator-runtime@0.9.6: {}
+
+ request-promise@3.0.0:
+ dependencies:
+ bluebird: 3.7.2
+ lodash: 4.17.21
+ request: 2.88.2
+
+ request@2.88.2:
+ dependencies:
+ aws-sign2: 0.7.0
+ aws4: 1.13.2
+ caseless: 0.12.0
+ combined-stream: 1.0.8
+ extend: 3.0.2
+ forever-agent: 0.6.1
+ form-data: 2.3.3
+ har-validator: 5.1.5
+ http-signature: 1.2.0
+ is-typedarray: 1.0.0
+ isstream: 0.1.2
+ json-stringify-safe: 5.0.1
+ mime-types: 2.1.35
+ oauth-sign: 0.9.0
+ performance-now: 2.1.0
+ qs: 6.5.3
+ safe-buffer: 5.2.1
+ tough-cookie: 2.5.0
+ tunnel-agent: 0.6.0
+ uuid: 3.4.0
+
resolve-pkg-maps@1.0.0: {}
+ restore-cursor@1.0.1:
+ dependencies:
+ exit-hook: 1.1.1
+ onetime: 1.1.0
+
+ rimraf@2.7.1:
+ dependencies:
+ glob: 7.2.3
+
+ run-async@0.1.0:
+ dependencies:
+ once: 1.4.0
+
+ rx-lite@3.1.2: {}
+
safe-buffer@5.2.1: {}
safe-stable-stringify@2.5.0: {}
@@ -1601,18 +2372,59 @@ snapshots:
split2@4.2.0: {}
+ sshpk@1.18.0:
+ dependencies:
+ asn1: 0.2.6
+ assert-plus: 1.0.0
+ bcrypt-pbkdf: 1.0.2
+ dashdash: 1.14.1
+ ecc-jsbn: 0.1.2
+ getpass: 0.1.7
+ jsbn: 0.1.1
+ safer-buffer: 2.1.2
+ tweetnacl: 0.14.5
+
statuses@2.0.1: {}
+ string-width@1.0.2:
+ dependencies:
+ code-point-at: 1.1.0
+ is-fullwidth-code-point: 1.0.0
+ strip-ansi: 3.0.1
+
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1
+ strip-ansi@3.0.1:
+ dependencies:
+ ansi-regex: 2.1.1
+
+ strip-bom@3.0.0: {}
+
+ supports-color@2.0.0: {}
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
thread-stream@2.7.0:
dependencies:
real-require: 0.2.0
+ through@2.3.8: {}
+
toidentifier@1.0.1: {}
+ tough-cookie@2.5.0:
+ dependencies:
+ psl: 1.15.0
+ punycode: 2.3.1
+
ts-node@10.9.2(@types/node@24.9.2)(typescript@5.9.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
@@ -1631,6 +2443,12 @@ snapshots:
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
+ tsconfig-paths@4.2.0:
+ dependencies:
+ json5: 2.2.3
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+
tsx@4.20.6:
dependencies:
esbuild: 0.25.11
@@ -1638,6 +2456,12 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
+ tunnel-agent@0.6.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ tweetnacl@0.14.5: {}
+
type-is@1.6.18:
dependencies:
media-typer: 0.3.0
@@ -1653,12 +2477,34 @@ snapshots:
unpipe@1.0.0: {}
+ untildify@3.0.3: {}
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ user-home@2.0.0:
+ dependencies:
+ os-homedir: 1.0.2
+
utils-merge@1.0.1: {}
+ uuid@3.4.0: {}
+
v8-compile-cache-lib@3.0.1: {}
+ varint@6.0.0: {}
+
vary@1.1.2: {}
+ verror@1.10.0:
+ dependencies:
+ assert-plus: 1.0.0
+ core-util-is: 1.0.2
+ extsprintf: 1.3.0
+
+ wrappy@1.0.2: {}
+
ws@8.18.3: {}
xtend@4.0.2: {}
diff --git a/src/firehose.ts b/src/firehose.ts
index eb00d82..3a1c409 100644
--- a/src/firehose.ts
+++ b/src/firehose.ts
@@ -4,31 +4,15 @@ import { db } from "./db";
import { Insertable } from "kysely";
import { FirehoseEventTable } from "./db";
-const pretty_print = (event_type: string, data: object) => {
- const colors = {
- commit: "\x1b[34m",
- identity: "\x1b[32m",
- account: "\x1b[33m",
- reset: "\x1b[0m",
- };
- const color = colors[event_type.toLowerCase()] || colors.reset;
- console.debug(`\n${color}## RECEIVED [${event_type.toUpperCase()}] EVENT ##${colors.reset}`);
- console.debug(JSON.stringify(
- data,
- (key, value) => typeof value === 'bigint' ? value.toString() : value,
- 2
- ));
-};
-
const saveEvent = async (type: 'commit' | 'identity' | 'account', data: any) => {
- try {
- await db.insertInto('firehose_event').values({
- event_type: type,
- event_data: data
- }).execute();
- } catch (error) {
- console.error("\nFailed to save event to database:", error);
- }
+ try {
+ await db.insertInto('firehose_event').values({
+ event_type: type,
+ event_data: data
+ }).execute();
+ } catch (error) {
+ console.error("\nFailed to save event to database:", error);
+ }
};
const main = () => {
@@ -38,31 +22,29 @@ const main = () => {
ws: WebSocket,
});
- firehose.on("commit", (commit: CommitEvent) => {
- saveEvent('commit', commit);
+ firehose.on("commit", async (commit: CommitEvent) => {
const createOps = commit.ops.filter(op => op.action === 'create');
+ const relevantOps = [];
for (const op of createOps) {
const recordType = op.record['$type'];
if (recordType && (recordType.startsWith('com.atproto.') || recordType.startsWith('systems.gmstn.'))) {
- pretty_print(`COMMIT - ${recordType}`, {
- repo: commit.repo,
- path: op.path,
- record: op.record
- });
+ relevantOps.push(op);
}
}
+
+ if (relevantOps.length > 0) {
+ await saveEvent('commit', commit);
+ }
});
- firehose.on("identity", (identity: IdentityEvent) => {
- saveEvent('identity', identity);
- pretty_print("IDENTITY", identity);
+ firehose.on("identity", async (identity: IdentityEvent) => {
+ await saveEvent('identity', identity);
});
- firehose.on("account", (account: AccountEvent) => {
- saveEvent('account', account);
- pretty_print("ACCOUNT", account);
+ firehose.on("account", async (account: AccountEvent) => {
+ await saveEvent('account', account);
});
firehose.on("open", () => {
@@ -70,7 +52,8 @@ const main = () => {
});
firehose.on("close", (cursor) => {
- console.log(`\nConnection closed. Last cursor was: ${cursor}`);
+ console.log(`\nConnection closed. Last cursor was: ${cursor}. Restarting.`);
+ firehose.start();
});
firehose.on("error", ({ error, cursor }) => {
diff --git a/src/index.ts b/src/index.ts
index d48ee7a..d432e40 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,6 +3,16 @@ import path from 'path';
console.log('Main app starting...');
+const pdsListSyncPath = path.resolve(__dirname, 'pds-list-sync.ts');
+const pdsListSyncProcess = fork(pdsListSyncPath);
+
+console.log(`pdsListSync process started with PID: ${pdsListSyncProcess.pid}`);
+
+const pdsBackfillPath = path.resolve(__dirname, 'pds-backfill.ts');
+const pdsBackfillProcess = fork(pdsBackfillPath);
+
+console.log(`pdsBackfill process started with PID: ${pdsBackfillProcess.pid}`);
+
const firehosePath = path.resolve(__dirname, 'firehose.ts');
const firehoseProcess = fork(firehosePath);
diff --git a/src/pds-backfill.ts b/src/pds-backfill.ts
new file mode 100644
index 0000000..b6e2f16
--- /dev/null
+++ b/src/pds-backfill.ts
@@ -0,0 +1,182 @@
+import { db } from './db';
+
+export interface FirehoseEventTable {
+ timestamp: ColumnType;
+ event_type: string;
+ event_data: Record;
+}
+export type FirehoseEvent = Selectable;
+export type NewFirehoseEvent = Insertable;
+
+interface AtpRecord {
+ $type: string;
+ createdAt: string;
+ [key: string]: any;
+}
+
+async function processSingleRepo(pdsHostname: string, did: string) {
+ const pdsBaseUrl = `https://` + pdsHostname;
+ const getRepoUrl = new URL(`/xrpc/com.atproto.sync.getRepo`, pdsBaseUrl);
+ getRepoUrl.searchParams.set('did', did);
+
+ let car: any;
+ try {
+ const { CarReader } = await import('@ipld/car');
+
+ const response = await fetch(getRepoUrl.href);
+ if (!response.ok) {
+ throw new Error(`Failed to getRepo for ${did}: ${response.status} ${response.statusText}`);
+ }
+ const carBytes = new Uint8Array(await response.arrayBuffer());
+ car = await CarReader.fromBytes(carBytes);
+ } catch (e: any) {
+ console.error(`[${did}] Failed to fetch or parse CAR: ${e.message}`);
+ return;
+ }
+
+ const recordsToInsert: NewFirehoseEvent[] = [];
+
+ try {
+ const cbor = await import('@ipld/dag-cbor');
+
+ for await (const block of car.blocks()) {
+ const record = cbor.decode(block.bytes) as AtpRecord;
+
+ if (
+ record &&
+ record.$type &&
+ typeof record.$type === 'string' &&
+ record.$type.startsWith('systems.gmstn.')
+ ) {
+ if (!record.createdAt || typeof record.createdAt !== 'string') {
+ console.warn(`[${did}] Found matching record without valid 'createdAt', skipping.`);
+ continue;
+ }
+
+ recordsToInsert.push({
+ timestamp: record.createdAt,
+ event_type: record.$type,
+ event_data: record,
+ });
+ }
+ }
+ } catch (e: any) {
+ console.error(`[${did}] Error parsing CAR blocks: ${e.message}. Skipping rest of repo.`);
+ return;
+ }
+
+ if (recordsToInsert.length > 0) {
+ try {
+ await db.insertInto('firehose_event').values(recordsToInsert).execute();
+ console.log(`[${did}] Inserted ${recordsToInsert.length} 'systems.gmstn.*' records.`);
+ } catch (e: any) {
+ console.error(`[${did}] Failed to insert records into DB: ${e.message}`);
+ }
+ }
+}
+
+async function backfillPds(pdsHostname: string) {
+ console.log(`Starting backfill for: ${pdsHostname}`);
+ const pdsBaseUrl = `https://` + pdsHostname;
+ let cursor: string | undefined;
+ let totalReposProcessed = 0;
+
+ try {
+ do {
+ const listReposUrl = new URL('/xrpc/com.atproto.sync.listRepos', pdsBaseUrl);
+ if (cursor) {
+ listReposUrl.searchParams.set('cursor', cursor);
+ }
+
+ const response = await fetch(listReposUrl.href);
+ if (!response.ok) {
+ throw new Error(`Failed to listRepos: ${response.status} ${response.statusText}`);
+ }
+
+ const data = await response.json();
+ cursor = data.cursor;
+ const dids: string[] = data.repos.map((r: { did: string }) => r.did);
+
+ if (dids.length === 0) {
+ break;
+ }
+
+ console.log(`Fetched ${dids.length} repos. Cursor: ${cursor}`);
+
+ const BATCH_SIZE = 10;
+ for (let i = 0; i < dids.length; i += BATCH_SIZE) {
+ const batch = dids.slice(i, i + BATCH_SIZE);
+ const tasks = batch.map(did => processSingleRepo(pdsHostname, did));
+ await Promise.allSettled(tasks);
+ }
+
+ totalReposProcessed += dids.length;
+
+ } while (cursor);
+
+ console.log(`[${pdsHostname}] Finished paginating repos.`);
+
+ await db
+ .updateTable('pds')
+ .set({ backfilled_at: new Date() })
+ .where('hostname', '=', pdsHostname)
+ .execute();
+
+ console.log(`Successfully completed backfill for ${pdsHostname}. Total repos: ${totalReposProcessed}`);
+
+ } catch (error) {
+ console.error(`[${pdsHostname}] Fatal error during backfill:`, error);
+ throw error;
+ }
+}
+
+async function main() {
+ let pdsesToBackfill: { hostname: string }[] = [];
+
+ try {
+ pdsesToBackfill = await db
+ .selectFrom('pds')
+ .select('hostname')
+ .where('backfilled_at', 'is', null)
+ .orderBy(
+ (eb) => eb
+ .case()
+ .when('hostname', 'like', '%.bsky.network')
+ .then(1)
+ .else(0)
+ .end(),
+ 'asc'
+ )
+ .orderBy('added_at', 'asc')
+ .execute();
+
+ if (pdsesToBackfill.length === 0) {
+ console.log('No PDSs to backfill. All caught up! Exiting.');
+ await db.destroy();
+ return;
+ }
+
+ console.log(`Found ${pdsesToBackfill.length} PDS(s) to backfill. Starting job...`);
+
+ } catch (e: any) {
+ console.error('Failed to fetch PDS list from database:', e.message);
+ process.exit(1);
+ }
+
+ for (const pds of pdsesToBackfill) {
+ try {
+ await backfillPds(pds.hostname);
+ } catch (e) {
+ console.error(`---`);
+ console.error(`Job for ${pds.hostname} failed. Moving to next PDS.`);
+ console.error(`---`);
+ }
+ }
+
+ console.log('All backfill jobs complete. Closing database connection.');
+ await db.destroy();
+}
+
+if (require.main === module) {
+ main();
+}
diff --git a/src/pds-list-sync.ts b/src/pds-list-sync.ts
new file mode 100644
index 0000000..e4eeadf
--- /dev/null
+++ b/src/pds-list-sync.ts
@@ -0,0 +1,75 @@
+import { db } from './db';
+
+const PDS_LIST_URL = 'https://raw.githubusercontent.com/mary-ext/atproto-scraping/refs/heads/trunk/state.json';
+
+interface StateJson {
+ pdses: {
+ [url: string]: {
+ inviteCodeRequired?: boolean;
+ version?: string;
+ }
+ }
+}
+
+async function syncPdsList() {
+ console.log('Starting PDS list sync...');
+
+ try {
+ const response = await fetch(PDS_LIST_URL);
+ if (!response.ok) {
+ throw new Error(`Failed to fetch PDS list: ${response.statusText}`);
+ }
+
+ const data = (await response.json()) as StateJson;
+ const pdsUrls = Object.keys(data?.pdses || {});
+
+ if (pdsUrls.length === 0) {
+ console.warn('No PDS hosts found in the upstream list.');
+ return;
+ }
+
+ const pdsToInsert = pdsUrls
+ .map(url => {
+ try {
+ return { hostname: new URL(url).hostname };
+ } catch (e) {
+ console.warn(`Invalid URL format in PDS list, skipping: ${url}`);
+ return null;
+ }
+ })
+ .filter(Boolean) as { hostname: string }[];
+
+ if (pdsToInsert.length === 0) {
+ console.log('No new valid PDS hosts to insert.');
+ return;
+ }
+
+ const result = await db
+ .insertInto('pds')
+ .values(pdsToInsert)
+ .onConflict((oc) => oc
+ .column('hostname')
+ .doNothing()
+ )
+ .execute();
+
+ console.log(`PDS list sync complete. Checked ${pdsToInsert.length} hosts.`);
+
+ } catch (error) {
+ console.error('Error during PDS list sync:', error);
+ process.exit(1);
+ }
+}
+
+if (require.main === module) {
+ syncPdsList()
+ .then(() => {
+ console.log('Sync finished successfully.');
+ db.destroy();
+ })
+ .catch((err) => {
+ console.error('Unhandled error in syncPdsList:', err);
+ db.destroy();
+ process.exit(1);
+ });
+}