From 62e3906333cc9e0f7aedddbb9a8877151dd053de Mon Sep 17 00:00:00 2001 From: Essential Randomness Date: Tue, 19 May 2026 04:11:50 -0700 Subject: [PATCH] Create opensocial lex client --- package-lock.json | 1056 +++++++++++++++++++++++++++++++++++- package.json | 1 + src/lib/opensocial/keys.ts | 97 +++- src/lib/opensocial/xrpc.ts | 52 ++ 4 files changed, 1182 insertions(+), 24 deletions(-) create mode 100644 src/lib/opensocial/xrpc.ts diff --git a/package-lock.json b/package-lock.json index 00433e0..2cfd691 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@astrojs/node": "^10.0.5", "@atproto/api": "^0.17.3", "@atproto/identity": "^0.4.8", + "@atproto/lex": "^0.1.0", "@atproto/syntax": "^0.4.3", "@fujocoded/astro-atproto-loader": "^0.2.1", "@fujocoded/authproto": "^0.3.1", @@ -364,6 +365,22 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/@atproto/common": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@atproto/common/-/common-0.6.0.tgz", + "integrity": "sha512-uXjByIhaFWN6gjwpmtx2E0aTA/6jt98LQy5flzlNI4O1PBsZmG6NVmWRycCuDf3n2PsFjE34jUWcVrg1ST6JJQ==", + "license": "MIT", + "dependencies": { + "@atproto/common-web": "^0.5.0", + "@atproto/lex-cbor": "^0.1.0", + "@atproto/lex-data": "^0.1.0", + "multiformats": "^13.0.0", + "pino": "^8.21.0" + }, + "engines": { + "node": ">=22" + } + }, "node_modules/@atproto/common-web": { "version": "0.4.21", "resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.21.tgz", @@ -394,6 +411,85 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/@atproto/common/node_modules/@atproto/common-web": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.5.0.tgz", + "integrity": "sha512-ReWnkuZdDU/74/I47gaI26uxQjHmpq4edp41NnZZQ5vIIKGb7Ei6pZHzDTUD9JURo109SKrPx9RMP2IQm0fOKA==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "@atproto/lex-json": "^0.1.0", + "@atproto/syntax": "^0.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/common/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", + "tslib": "^2.8.1", + "uint8arrays": "^5.0.0", + "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/common/node_modules/@atproto/lex-json": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.1.0.tgz", + "integrity": "sha512-oWUrRMwFyWpmi/5k1Se3xBTbP06XdxBS5iFuUz9LmqItaPXwrWRD87a9ldPvINQ/A2/mn7J6/qug8sDVlhD+vQ==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/common/node_modules/@atproto/syntax": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.6.0.tgz", + "integrity": "sha512-Z3Zrj4y/HLAF1SKVm4Fyhv/JUhrAMDyWqB5PJKvKA5/A8jxwZXpupFC6sNFRh4rlLS9Sl07L8gtvLO3RMG5jxQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/common/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/common/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@atproto/common/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/@atproto/crypto": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/@atproto/crypto/-/crypto-0.4.5.tgz", @@ -488,26 +584,506 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/@atproto/lex": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex/-/lex-0.1.0.tgz", + "integrity": "sha512-/JjJ3tHxIHJ6JiG++OjpJClz1PriMh3Nm6cle7JBuyfTTarQ6i6fc4w0RP6mDmL9hyC/5iBOce7pxRo5dhUJ/A==", + "license": "MIT", + "dependencies": { + "@atproto/lex-builder": "^0.1.0", + "@atproto/lex-client": "^0.1.0", + "@atproto/lex-data": "^0.1.0", + "@atproto/lex-installer": "^0.1.0", + "@atproto/lex-json": "^0.1.0", + "@atproto/lex-schema": "^0.1.0", + "tslib": "^2.8.1", + "yargs": "^17.0.0" + }, + "bin": { + "lex": "bin/lex", + "ts-lex": "bin/lex" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-builder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-builder/-/lex-builder-0.1.0.tgz", + "integrity": "sha512-VSInstmDWVJRdka5/dNE1CRWeyhZvfAx7rSThohLPX1/nneTBGbxTh6JYVXBUqrwJPLmPM+DiHZA2H+ITYK3og==", + "license": "MIT", + "dependencies": { + "@atproto/lex-document": "^0.1.0", + "@atproto/lex-schema": "^0.1.0", + "prettier": "^3.2.5", + "ts-morph": "^27.0.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-cbor": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-cbor/-/lex-cbor-0.1.0.tgz", + "integrity": "sha512-SGL7BHPYN0OmvtnVixieYWyh2ghxI7iHADTLfz52Xp5zR+BZY3QggIKJ32KfyYN9Ss2tduaqsY5aclEki2Aq0A==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "cborg": "^4.5.8", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-cbor/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", + "tslib": "^2.8.1", + "uint8arrays": "^5.0.0", + "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-cbor/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/lex-cbor/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@atproto/lex-client": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-client/-/lex-client-0.1.0.tgz", + "integrity": "sha512-0ITic31rCx6ZXDnYZQDGwD6+OKCF92s5wwQ1Y2acYgQZdSoCD2Z/okk/40r+v97U5Gk8nE8mmzaAVWxcsmeSTQ==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "@atproto/lex-json": "^0.1.0", + "@atproto/lex-schema": "^0.1.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-client/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", + "tslib": "^2.8.1", + "uint8arrays": "^5.0.0", + "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-client/node_modules/@atproto/lex-json": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.1.0.tgz", + "integrity": "sha512-oWUrRMwFyWpmi/5k1Se3xBTbP06XdxBS5iFuUz9LmqItaPXwrWRD87a9ldPvINQ/A2/mn7J6/qug8sDVlhD+vQ==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-client/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/lex-client/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, "node_modules/@atproto/lex-data": { "version": "0.0.15", "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.0.15.tgz", "integrity": "sha512-ZsbGiaM5S3CnGrcTMbDGON3bLZzCi/Mx9UvcMREKSRujnF68eHgMiXxJqvykP7+QpOX6tYCK93axZkuJVhtSEw==", "license": "MIT", "dependencies": { - "multiformats": "^9.9.0", + "multiformats": "^9.9.0", + "tslib": "^2.8.1", + "uint8arrays": "3.0.0", + "unicode-segmenter": "^0.14.0" + } + }, + "node_modules/@atproto/lex-document": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-document/-/lex-document-0.1.0.tgz", + "integrity": "sha512-I2q2iwK8RnSHkBeAj5xdJNYdHiUQqlkbbleBSJKJXlYOYy5y86dWRo9IfE0l9E3qZ3/zvy1ydlEZmZupEt0FGg==", + "license": "MIT", + "dependencies": { + "@atproto/lex-schema": "^0.1.0", + "core-js": "^3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-installer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-installer/-/lex-installer-0.1.0.tgz", + "integrity": "sha512-NXrJNe2qY4YreC82VgPE7stXnzSnI+xMeNXvgJDiMZj4MeSQeQn5ElFVd1yzRRV9sZREf6Y/HE+y1ffb2uewXA==", + "license": "MIT", + "dependencies": { + "@atproto/lex-builder": "^0.1.0", + "@atproto/lex-cbor": "^0.1.0", + "@atproto/lex-data": "^0.1.0", + "@atproto/lex-document": "^0.1.0", + "@atproto/lex-resolver": "^0.1.0", + "@atproto/lex-schema": "^0.1.0", + "@atproto/syntax": "^0.6.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-installer/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", + "tslib": "^2.8.1", + "uint8arrays": "^5.0.0", + "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-installer/node_modules/@atproto/syntax": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.6.0.tgz", + "integrity": "sha512-Z3Zrj4y/HLAF1SKVm4Fyhv/JUhrAMDyWqB5PJKvKA5/A8jxwZXpupFC6sNFRh4rlLS9Sl07L8gtvLO3RMG5jxQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-installer/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/lex-installer/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@atproto/lex-json": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.0.16.tgz", + "integrity": "sha512-IgLgQ0krshVlrIYZ+heTBDbCnM3LmAgWvsaYn5MxvKA3LcBot3PG3ptdO8VOweVZ+WgCLuo39cz9EbUmIbqdtg==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.0.15", + "tslib": "^2.8.1" + } + }, + "node_modules/@atproto/lex-resolver": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-resolver/-/lex-resolver-0.1.0.tgz", + "integrity": "sha512-zliMiRW4ttSNFreKxyvSpaYQjeWrKpV/lutnXI9BNE8Ysgnw8Rltm0bR7kG/y0OlyClxhhU/vAG+OR8NpjhU1Q==", + "license": "MIT", + "dependencies": { + "@atproto-labs/did-resolver": "^0.3.0", + "@atproto/crypto": "^0.5.0", + "@atproto/lex-client": "^0.1.0", + "@atproto/lex-data": "^0.1.0", + "@atproto/lex-document": "^0.1.0", + "@atproto/lex-schema": "^0.1.0", + "@atproto/repo": "^0.10.0", + "@atproto/syntax": "^0.6.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto-labs/did-resolver": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@atproto-labs/did-resolver/-/did-resolver-0.3.0.tgz", + "integrity": "sha512-6w8UxJQVj40TqKJm+D5s6pcH45eWH/KvfAR+gYC6KOux/mM7ZI3IKOhI1Gq7GIte1eOp9WXwASN1RQAFYZ4MFw==", + "license": "MIT", + "dependencies": { + "@atproto-labs/fetch": "^0.3.0", + "@atproto-labs/pipe": "^0.2.0", + "@atproto-labs/simple-store": "^0.4.0", + "@atproto-labs/simple-store-memory": "^0.2.0", + "@atproto/did": "^0.4.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto-labs/fetch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@atproto-labs/fetch/-/fetch-0.3.0.tgz", + "integrity": "sha512-yZhNsRZyqhjmzHlXmE9k6XU0f6+ynfNyrHhB4FlEyUjkBvf5vNLjdJyBq+Jp7ISGMigA1fn2lAgaE/qkrVo9iw==", + "license": "MIT", + "dependencies": { + "@atproto-labs/pipe": "^0.2.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto-labs/pipe": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@atproto-labs/pipe/-/pipe-0.2.0.tgz", + "integrity": "sha512-89X6gv+8/SiZYwJ4+Hw8iaU1WymbElZO6LsMgHd+c1XFs/78KhsIL4xp0RCs7/W8izK9BxaTEnYN5csRmwQ99Q==", + "license": "MIT", + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto-labs/simple-store": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@atproto-labs/simple-store/-/simple-store-0.4.0.tgz", + "integrity": "sha512-sbPEju2QXzN6lGWfr5p2Kg82ZeaG1UyVFOrMQc4eCjUvxGOjIxuYOVIiTuPTFOC5Rsvsb8jMOmLjLi8FR/CMYw==", + "license": "MIT", + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto-labs/simple-store-memory": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@atproto-labs/simple-store-memory/-/simple-store-memory-0.2.0.tgz", + "integrity": "sha512-nDZIS6vOBvR8NqObGmj0GFSdz3N6gyQ7ny3l/uiezwuCWShsxtA9OkYcjaQ7Kw3hydXTe4iEGu/BDOACncnxDg==", + "license": "MIT", + "dependencies": { + "@atproto-labs/simple-store": "^0.4.0", + "lru-cache": "^10.2.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto/crypto": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@atproto/crypto/-/crypto-0.5.0.tgz", + "integrity": "sha512-HBfq6z+tzkiBzPhHOvRFkQU3inTQIUJAkb1UEyGx+pdPTnFFtnfIoo9Kr1ZV/FzMIgnHOA8H2UJC3dxxFl1eVg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "^1.7.0", + "@noble/hashes": "^1.6.1", + "uint8arrays": "^5.0.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto/did": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@atproto/did/-/did-0.4.0.tgz", + "integrity": "sha512-OADX1NXCkScMkNJmSQnTUfPoDJ2IoOUTtqVfuY4z+a8//JDIsY6FDygv3GR8Sh2laz5qodlCA7XM+u6XVine3g==", + "license": "MIT", + "dependencies": { + "zod": "^3.23.8" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", + "tslib": "^2.8.1", + "uint8arrays": "^5.0.0", + "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/@atproto/syntax": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.6.0.tgz", + "integrity": "sha512-Z3Zrj4y/HLAF1SKVm4Fyhv/JUhrAMDyWqB5PJKvKA5/A8jxwZXpupFC6sNFRh4rlLS9Sl07L8gtvLO3RMG5jxQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/@atproto/lex-resolver/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/lex-resolver/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@atproto/lex-resolver/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@atproto/lex-schema": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-schema/-/lex-schema-0.1.0.tgz", + "integrity": "sha512-YU9vq3RbqG9+OZcHYVUviPQodAWupUmamqNYa5Bd0Rx3XDuQE8S34b3gMXX3XA6qsTBq3WCe16Racj9QHMl+sg==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "@atproto/syntax": "^0.6.0", + "@standard-schema/spec": "^1.1.0", + "iso-datestring-validator": "^2.2.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-schema/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", + "tslib": "^2.8.1", + "uint8arrays": "^5.0.0", + "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-schema/node_modules/@atproto/syntax": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.6.0.tgz", + "integrity": "sha512-Z3Zrj4y/HLAF1SKVm4Fyhv/JUhrAMDyWqB5PJKvKA5/A8jxwZXpupFC6sNFRh4rlLS9Sl07L8gtvLO3RMG5jxQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex-schema/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/lex-schema/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@atproto/lex/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", "tslib": "^2.8.1", - "uint8arrays": "3.0.0", + "uint8arrays": "^5.0.0", "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" } }, - "node_modules/@atproto/lex-json": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.0.16.tgz", - "integrity": "sha512-IgLgQ0krshVlrIYZ+heTBDbCnM3LmAgWvsaYn5MxvKA3LcBot3PG3ptdO8VOweVZ+WgCLuo39cz9EbUmIbqdtg==", + "node_modules/@atproto/lex/node_modules/@atproto/lex-json": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.1.0.tgz", + "integrity": "sha512-oWUrRMwFyWpmi/5k1Se3xBTbP06XdxBS5iFuUz9LmqItaPXwrWRD87a9ldPvINQ/A2/mn7J6/qug8sDVlhD+vQ==", "license": "MIT", "dependencies": { - "@atproto/lex-data": "^0.0.15", + "@atproto/lex-data": "^0.1.0", "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/lex/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/lex/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" } }, "node_modules/@atproto/lexicon": { @@ -602,6 +1178,118 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/@atproto/repo": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@atproto/repo/-/repo-0.10.0.tgz", + "integrity": "sha512-dGnU3R+geXepOZFIn3YUu6WaXLuT1NxqNvusR/JmAqPjjT6dT4tjouZeDPrumSnZm2f5Z8xMeDfVxpMWQ4stFw==", + "license": "MIT", + "dependencies": { + "@atproto/common": "^0.6.0", + "@atproto/common-web": "^0.5.0", + "@atproto/crypto": "^0.5.0", + "@atproto/lex-cbor": "^0.1.0", + "@atproto/lex-data": "^0.1.0", + "@atproto/syntax": "^0.6.0", + "varint": "^6.0.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/repo/node_modules/@atproto/common-web": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.5.0.tgz", + "integrity": "sha512-ReWnkuZdDU/74/I47gaI26uxQjHmpq4edp41NnZZQ5vIIKGb7Ei6pZHzDTUD9JURo109SKrPx9RMP2IQm0fOKA==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "@atproto/lex-json": "^0.1.0", + "@atproto/syntax": "^0.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/repo/node_modules/@atproto/crypto": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@atproto/crypto/-/crypto-0.5.0.tgz", + "integrity": "sha512-HBfq6z+tzkiBzPhHOvRFkQU3inTQIUJAkb1UEyGx+pdPTnFFtnfIoo9Kr1ZV/FzMIgnHOA8H2UJC3dxxFl1eVg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "^1.7.0", + "@noble/hashes": "^1.6.1", + "uint8arrays": "^5.0.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/repo/node_modules/@atproto/lex-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.1.0.tgz", + "integrity": "sha512-xFEUWNo+qEC9oNK55ly5MJoljIWZBMmokXIEyrgf7IFn4d5HthN6GdWVFuxqvKXDvzq2ConkHioOH3wiWpDh8w==", + "license": "MIT", + "dependencies": { + "multiformats": "^13.0.0", + "tslib": "^2.8.1", + "uint8arrays": "^5.0.0", + "unicode-segmenter": "^0.14.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/repo/node_modules/@atproto/lex-json": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.1.0.tgz", + "integrity": "sha512-oWUrRMwFyWpmi/5k1Se3xBTbP06XdxBS5iFuUz9LmqItaPXwrWRD87a9ldPvINQ/A2/mn7J6/qug8sDVlhD+vQ==", + "license": "MIT", + "dependencies": { + "@atproto/lex-data": "^0.1.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/repo/node_modules/@atproto/syntax": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.6.0.tgz", + "integrity": "sha512-Z3Zrj4y/HLAF1SKVm4Fyhv/JUhrAMDyWqB5PJKvKA5/A8jxwZXpupFC6sNFRh4rlLS9Sl07L8gtvLO3RMG5jxQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@atproto/repo/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@atproto/repo/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@atproto/repo/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/@atproto/syntax": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.3.tgz", @@ -2206,6 +2894,23 @@ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", "license": "MIT" }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@ts-morph/common": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.28.1.tgz", + "integrity": "sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==", + "license": "MIT", + "dependencies": { + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1", + "tinyglobby": "^0.2.14" + } + }, "node_modules/@types/debug": { "version": "4.1.13", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", @@ -2373,6 +3078,18 @@ "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", "license": "MIT" }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/ajv": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", @@ -2567,6 +3284,15 @@ "astro": "^4.14.0 || ^5.0.0 || ^6.0.0" } }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/await-lock": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.2.2.tgz", @@ -2592,12 +3318,86 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "license": "ISC" }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/cborg": { + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.5.8.tgz", + "integrity": "sha512-6/viltD51JklRhq4L7jC3zgy6gryuG5xfZ3kzpE+PravtyeQLeQmCYLREhQH7pWENg5pY4Yu/XCd6a7dKScVlw==", + "license": "Apache-2.0", + "bin": { + "cborg": "lib/bin.js" + } + }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -2691,6 +3491,12 @@ "node": ">=6" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "license": "MIT" + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3168,12 +3974,30 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3186,6 +4010,15 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/fast-string-truncated-width": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-1.2.1.tgz", @@ -3547,6 +4380,26 @@ "url": "https://opencollective.com/express" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -4556,6 +5409,21 @@ "url": "https://opencollective.com/express" } }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -4683,6 +5551,15 @@ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", "license": "MIT" }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -4827,6 +5704,44 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pino": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.21.0.tgz", + "integrity": "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.6.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "license": "MIT", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", + "license": "MIT" + }, "node_modules/postcss": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", @@ -4879,6 +5794,21 @@ "node": ">=6" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", + "license": "MIT" + }, "node_modules/property-information": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", @@ -4889,6 +5819,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, "node_modules/radix3": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", @@ -4904,6 +5840,22 @@ "node": ">= 0.6" } }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/readdirp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", @@ -4917,6 +5869,15 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", @@ -5228,6 +6189,35 @@ "fsevents": "~2.3.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/sax": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", @@ -5369,6 +6359,15 @@ "url": "https://github.com/sponsors/cyyynthia" } }, + "node_modules/sonic-boom": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -5388,6 +6387,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -5397,6 +6405,15 @@ "node": ">= 0.8" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -5462,6 +6479,15 @@ "url": "https://opencollective.com/svgo" } }, + "node_modules/thread-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz", + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/tiny-inflate": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", @@ -5540,6 +6566,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-morph": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-27.0.2.tgz", + "integrity": "sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.28.1", + "code-block-writer": "^13.0.3" + } + }, "node_modules/tsconfck": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", @@ -5892,6 +6928,12 @@ } } }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", + "license": "MIT" + }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", diff --git a/package.json b/package.json index 41d6e57..9eda5e8 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@astrojs/node": "^10.0.5", "@atproto/api": "^0.17.3", "@atproto/identity": "^0.4.8", + "@atproto/lex": "^0.1.0", "@atproto/syntax": "^0.4.3", "@fujocoded/astro-atproto-loader": "^0.2.1", "@fujocoded/authproto": "^0.3.1", diff --git a/src/lib/opensocial/keys.ts b/src/lib/opensocial/keys.ts index 336ae50..3be1764 100644 --- a/src/lib/opensocial/keys.ts +++ b/src/lib/opensocial/keys.ts @@ -1,13 +1,27 @@ -import { createPrivateKey, createPublicKey, type KeyObject } from "node:crypto"; +import { + createHash, + createPrivateKey, + createPublicKey, + sign as cryptoSign, + type KeyObject, +} from "node:crypto"; const DEFAULT_KID = "opensocial-cimd-1"; +/** Truthy when the configured value exists and is non-empty. */ +export function hasPrivateKey(): boolean { + return ( + !!import.meta.env.OPENSOCIAL_CIMD_PRIVATE_KEY_BASE64 || + !!import.meta.env.OPENSOCIAL_CIMD_PRIVATE_KEY_PEM + ); +} + function loadPrivatePem(): string { - const b64 = process.env.OPENSOCIAL_CIMD_PRIVATE_KEY_BASE64; + const b64 = import.meta.env.OPENSOCIAL_CIMD_PRIVATE_KEY_BASE64; if (b64 && b64.length > 0) { return Buffer.from(b64, "base64").toString("utf-8"); } - const pem = process.env.OPENSOCIAL_CIMD_PRIVATE_KEY_PEM; + const pem = import.meta.env.OPENSOCIAL_CIMD_PRIVATE_KEY_PEM; if (pem && pem.length > 0) { return pem.includes("\\n") ? pem.replaceAll("\\n", "\n") : pem; } @@ -18,13 +32,19 @@ function loadPrivatePem(): string { } let cachedPrivate: KeyObject | null = null; -export function getPrivateKey(): KeyObject { +function getPrivateKey(): KeyObject { if (!cachedPrivate) cachedPrivate = createPrivateKey(loadPrivatePem()); return cachedPrivate; } -let cachedPublicJwk: PublicJwk | null = null; -export function getPublicJwk(): PublicJwk { +let cachedPublicJwk: { + kty: string; + crv?: string; + x?: string; + kid: string; + use: "sig"; +} | null = null; +export function getPublicJwk() { if (cachedPublicJwk) return cachedPublicJwk; const pub = createPublicKey(getPrivateKey()); const jwk = pub.export({ format: "jwk" }) as { @@ -34,21 +54,64 @@ export function getPublicJwk(): PublicJwk { }; cachedPublicJwk = { ...jwk, - kid: getKid(), + kid: import.meta.env.OPENSOCIAL_CIMD_KID || DEFAULT_KID, use: "sig", - } as PublicJwk; + }; return cachedPublicJwk; } -export function getKid(): string { - const kid = process.env.OPENSOCIAL_CIMD_KID; - return kid && kid.length > 0 ? kid : DEFAULT_KID; +/** + * The registered open-social app id, used as the `keyid` parameter in HTTP + * Message Signatures so the server can resolve our CIMD document. Distinct + * from `kid`: kid identifies which key inside our JWKS; appId identifies us. + */ +export function getAppId(): string | null { + const id = import.meta.env.OPENSOCIAL_APP_ID; + return id && id.length > 0 ? id : null; } -export interface PublicJwk { - kty: string; - crv?: string; - x?: string; - kid: string; - use: "sig"; +export function signRequest(opts: { + method: string; + url: string; + body?: string | null; + appId: string; + /** Override clock for tests. Seconds since epoch. */ + nowSeconds?: number; + /** Override the private key for tests. Defaults to getPrivateKey(). */ + privateKey?: KeyObject; +}) { + const method = opts.method.toUpperCase(); + const created = opts.nowSeconds ?? Math.floor(Date.now() / 1000); + const hasBody = method !== "GET" && method !== "HEAD"; + + const components: string[] = ['"@method"', '"@target-uri"']; + const lines: string[] = [ + `"@method": ${method}`, + `"@target-uri": ${opts.url}`, + ]; + + let digestValue: string | undefined = undefined; + if (hasBody) { + const body = opts.body ?? ""; + digestValue = `sha-256=:${createHash("sha256") + .update(body) + .digest("base64")}:`; + components.push('"content-digest"'); + lines.push(`"content-digest": ${digestValue}`); + } + + const signatureParams = `(${components.join(" ")});created=${created};keyid="${opts.appId}"`; + lines.push(`"@signature-params": ${signatureParams}`); + + const signature = cryptoSign( + null, + Buffer.from(lines.join("\n"), "utf-8"), + opts.privateKey ?? getPrivateKey(), + ); + + return { + "Signature-Input": `sig1=${signatureParams}`, + Signature: `sig1=:${signature.toString("base64")}:`, + "Content-Digest": digestValue, + }; } diff --git a/src/lib/opensocial/xrpc.ts b/src/lib/opensocial/xrpc.ts new file mode 100644 index 0000000..8fd65a0 --- /dev/null +++ b/src/lib/opensocial/xrpc.ts @@ -0,0 +1,52 @@ +// Minimum signed Lexicon client. Server-only: this wraps @atproto/lex's Client +// with the CIMD HTTP Message Signature fetch hook. + +import { Client } from "@atproto/lex"; + +import { signRequest } from "./keys.js"; + +export function createSignedLexClient(opts: { + /** Service origin for XRPC calls, for example `https://api.example.com`. */ + service: string | URL; + /** Registered app id, used as the `keyid` in HTTP signatures. */ + appId: string; + /** Override for tests. Defaults to global `fetch`. */ + fetchImpl?: typeof fetch; + /** Defaults to false so callers can start without generated schemas. */ + validateResponse?: boolean; +}): Client { + return new Client( + { + service: opts.service, + fetch: createSignedFetch(opts.appId, opts.fetchImpl ?? fetch), + }, + { validateResponse: opts.validateResponse ?? false }, + ); +} + +function createSignedFetch(appId: string, fetchImpl: typeof fetch): typeof fetch { + return async (input, init) => { + const url = input instanceof Request ? input.url : input.toString(); + const method = ( + init?.method ?? + (input instanceof Request ? input.method : "GET") + ).toUpperCase(); + const body = bodyToString(init?.body); + const headers = new Headers(init?.headers); + const signed = signRequest({ method, url, body, appId }); + + for (const [key, value] of Object.entries(signed)) { + if (value) headers.set(key, value); + } + + return fetchImpl(input, { ...init, headers }); + }; +} + +function bodyToString(body: BodyInit | null | undefined): string | null { + if (body === undefined || body === null) return null; + if (typeof body === "string") return body; + throw new TypeError( + "Signed Lexicon requests require string bodies before signing", + ); +} -- 2.51.2