example restaurant review app on atproto

init

besaid.zone 9678d2c2

+4
.gitignore
··· 1 + # deps 2 + node_modules/ 3 + foodz.db 4 + .env
+1
README.md
··· 1 + # Fooodz (example restaurant review app on atproto)
+11
drizzle.config.ts
··· 1 + import { defineConfig } from "drizzle-kit"; 2 + 3 + export default defineConfig({ 4 + out: "./src/drizzle/migrations", 5 + dialect: "sqlite", 6 + schema: "./src/drizzle/schema.ts", 7 + dbCredentials: { 8 + url: "file:./foodz.db", 9 + }, 10 + verbose: true, 11 + });
+6
lex.config.js
··· 1 + import { defineLexiconConfig } from "@atcute/lex-cli"; 2 + 3 + export default defineLexiconConfig({ 4 + files: ["lexicons/**/*.json"], 5 + outdir: "src/lexicons/", 6 + });
+39
lexicons/review.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.fooodz.review", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A user's review/rating of a restaurant", 8 + "record": { 9 + "type": "object", 10 + "required": ["place", "review", "rating", "createdAt"], 11 + "properties": { 12 + "place": { 13 + "type": "string", 14 + "description": "The name of the place that the review is for", 15 + "maxLength": 200, 16 + "maxGraphemes": 20 17 + }, 18 + "review": { 19 + "type": "string", 20 + "description": "review of food place", 21 + "maxLength": 3000, 22 + "maxGraphemes": 300 23 + }, 24 + "rating": { 25 + "type": "integer", 26 + "minimum": 1, 27 + "maximum": 5, 28 + "description": "The rating for the restaurant on a scale of 1 to 5" 29 + }, 30 + "createdAt": { 31 + "type": "string", 32 + "format": "datetime", 33 + "description": "When the review was written" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + }
+30
package.json
··· 1 + { 2 + "name": "foooodz", 3 + "type": "module", 4 + "scripts": { 5 + "dev": "NODE_ENV=development tsx watch src/index.tsx", 6 + "lexgen": "pnpm exec lex-cli generate -c ./lex.config.js", 7 + "push": "drizzle-kit push", 8 + "studio": "drizzle-kit studio --port=3001" 9 + }, 10 + "dependencies": { 11 + "@atcute/lex-cli": "^2.2.0", 12 + "@atcute/lexicons": "^1.1.1", 13 + "@atproto/api": "^0.16.7", 14 + "@atproto/common": "^0.4.11", 15 + "@atproto/oauth-client-node": "^0.3.7", 16 + "@hono/node-server": "^1.19.1", 17 + "@skyware/jetstream": "^0.2.5", 18 + "better-sqlite3": "^12.2.0", 19 + "dotenv": "^17.2.2", 20 + "drizzle-orm": "^0.44.5", 21 + "hono": "^4.9.6" 22 + }, 23 + "devDependencies": { 24 + "@types/better-sqlite3": "^7.6.13", 25 + "@types/node": "^24.3.1", 26 + "drizzle-kit": "^0.31.4", 27 + "tsx": "^4.20.5", 28 + "typescript": "^5.9.2" 29 + } 30 + }
+1719
pnpm-lock.yaml
··· 1 + lockfileVersion: '9.0' 2 + 3 + settings: 4 + autoInstallPeers: true 5 + excludeLinksFromLockfile: false 6 + 7 + importers: 8 + 9 + .: 10 + dependencies: 11 + '@atcute/lex-cli': 12 + specifier: ^2.2.0 13 + version: 2.2.0 14 + '@atcute/lexicons': 15 + specifier: ^1.1.1 16 + version: 1.1.1 17 + '@atproto/api': 18 + specifier: ^0.16.7 19 + version: 0.16.7 20 + '@atproto/common': 21 + specifier: ^0.4.11 22 + version: 0.4.11 23 + '@atproto/oauth-client-node': 24 + specifier: ^0.3.7 25 + version: 0.3.7 26 + '@hono/node-server': 27 + specifier: ^1.19.1 28 + version: 1.19.1(hono@4.9.6) 29 + '@skyware/jetstream': 30 + specifier: ^0.2.5 31 + version: 0.2.5 32 + better-sqlite3: 33 + specifier: ^12.2.0 34 + version: 12.2.0 35 + dotenv: 36 + specifier: ^17.2.2 37 + version: 17.2.2 38 + drizzle-orm: 39 + specifier: ^0.44.5 40 + version: 0.44.5(@types/better-sqlite3@7.6.13)(better-sqlite3@12.2.0)(bun-types@1.2.21(@types/react@19.1.12)) 41 + hono: 42 + specifier: ^4.9.6 43 + version: 4.9.6 44 + devDependencies: 45 + '@types/better-sqlite3': 46 + specifier: ^7.6.13 47 + version: 7.6.13 48 + '@types/node': 49 + specifier: ^24.3.1 50 + version: 24.3.1 51 + drizzle-kit: 52 + specifier: ^0.31.4 53 + version: 0.31.4 54 + tsx: 55 + specifier: ^4.20.5 56 + version: 4.20.5 57 + typescript: 58 + specifier: ^5.9.2 59 + version: 5.9.2 60 + 61 + packages: 62 + 63 + '@atcute/atproto@3.1.3': 64 + resolution: {integrity: sha512-+5u0l+8E7h6wZO7MM1HLXIPoUEbdwRtr28ZRTgsURp+Md9gkoBj9e5iMx/xM8F2Exfyb65J5RchW/WlF2mw/RQ==} 65 + 66 + '@atcute/bluesky@3.2.2': 67 + resolution: {integrity: sha512-L8RrMNeRLGvSHMq2KDIAGXrpuNGA87YOXpXHY1yhmovVCjQ5n55FrR6JoQaxhprdXdKKQiefxNwQQQybDrfgFQ==} 68 + 69 + '@atcute/lex-cli@2.2.0': 70 + resolution: {integrity: sha512-noikZui2a7zeGGp0KdQQqCkhfrgXORZ5RiFI9lyxD/SoL+g1LZBZ2vOo92kcbZT1j37Guj4+DmpFC4pWbxhuUA==} 71 + hasBin: true 72 + 73 + '@atcute/lexicon-doc@1.1.1': 74 + resolution: {integrity: sha512-/6M4K34ICZWa9rRiM9YWSsDZs0Vjv05SFJBb03mD+x14W01gIVLPK2UXiP0yIodgzWHhPQ79LLdyMJ8LirC84w==} 75 + 76 + '@atcute/lexicons@1.1.1': 77 + resolution: {integrity: sha512-k6qy5p3j9fJJ6ekaMPfEfp3ni4TW/XNuH9ZmsuwC0fi0tOjp+Fa8ZQakHwnqOzFt/cVBfGcmYE/lKNAbeTjgUg==} 78 + 79 + '@atproto-labs/did-resolver@0.2.1': 80 + resolution: {integrity: sha512-zSoHyqwwRYUtMNLW+RrWsImt1U5S47nJv5FfmAXTmon6wVKjxKD/PFrD1pg/4G6THqJmQHTs1Hj+54XVupYnvQ==} 81 + 82 + '@atproto-labs/fetch-node@0.1.10': 83 + resolution: {integrity: sha512-o7hGaonA71A6p7O107VhM6UBUN/g9tTyYohMp1q0Kf6xQ4npnuZYRSHSf2g6reSfGQJ1GoFNjBObETTT1ge/jQ==} 84 + engines: {node: '>=18.7.0'} 85 + 86 + '@atproto-labs/fetch@0.2.3': 87 + resolution: {integrity: sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==} 88 + 89 + '@atproto-labs/handle-resolver-node@0.1.19': 90 + resolution: {integrity: sha512-nNVCfiKudvMYfDcWCa9koOMOpCYaC0wG4Uys5dZev99s/Nka7tRlIZIV+u+GWivnG9lqCupKATkoyCd6Per8Gw==} 91 + engines: {node: '>=18.7.0'} 92 + 93 + '@atproto-labs/handle-resolver@0.3.1': 94 + resolution: {integrity: sha512-mLZdMNvwomgnn9sffKO1/xr02ctgeiT0FUVw7JekbchTckub2RM7qMu8Rw1mC4bpCpW+i7DXDiOxpoajkppwYQ==} 95 + 96 + '@atproto-labs/identity-resolver@0.3.1': 97 + resolution: {integrity: sha512-jCgotRRqPykPwh4gh0FBLOqeofv1G8OH/DZ5s88HWm7biUZeksZwDrEvL5TnqEFUpXT3O9Hcyp/XEpfCAplRoQ==} 98 + 99 + '@atproto-labs/pipe@0.1.1': 100 + resolution: {integrity: sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg==} 101 + 102 + '@atproto-labs/simple-store-memory@0.1.4': 103 + resolution: {integrity: sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw==} 104 + 105 + '@atproto-labs/simple-store@0.3.0': 106 + resolution: {integrity: sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ==} 107 + 108 + '@atproto/api@0.16.7': 109 + resolution: {integrity: sha512-EdVWkEgaEQm1LEiiP1fW/XXXpMNmtvT5c9+cZVRiwYc4rTB66WIJJWqmaMT/tB7nccMkFjr6FtwObq5LewWfgw==} 110 + 111 + '@atproto/common-web@0.4.2': 112 + resolution: {integrity: sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==} 113 + 114 + '@atproto/common@0.4.11': 115 + resolution: {integrity: sha512-Knv0viYXNMfCdIE7jLUiWJKnnMfEwg+vz2epJQi8WOjqtqCFb3W/3Jn72ZiuovIfpdm13MaOiny6w2NErUQC6g==} 116 + engines: {node: '>=18.7.0'} 117 + 118 + '@atproto/did@0.2.0': 119 + resolution: {integrity: sha512-BskT39KYbwY1DUsWekkHh47xS+wvJpFq5F9acsicNfYniinyAMnNTzGKQEhnjQuG7K0qQItg/SnmC+y0tJXV7Q==} 120 + 121 + '@atproto/jwk-jose@0.1.10': 122 + resolution: {integrity: sha512-Eiu/u4tZHz3IIhHZt0zneYEffSAO3Oqk/ToKwlu1TqKte6sjtPs/4uquSiAAGFYozqgo92JC/AQclWzzkHI5QQ==} 123 + 124 + '@atproto/jwk-webcrypto@0.1.10': 125 + resolution: {integrity: sha512-JZsavs6JiSmw5rgcjkGDwzr1aCJGdybZOjVfYH+m9sXRU1BrUCA30uwNfZY7eFyWXyRAnCFiYiGVZgypXyKotw==} 126 + 127 + '@atproto/jwk@0.5.0': 128 + resolution: {integrity: sha512-Qi2NtEqhkG+uz3CKia4+H05WMV/z//dz3ESo5+cyBKrOnxVTJ5ZubMyltWjoYvy6v/jLhorXdDWcjn07yky7MQ==} 129 + 130 + '@atproto/lexicon@0.5.0': 131 + resolution: {integrity: sha512-3aAzEAy9EAPs3CxznzMhEcqDd7m3vz1eze/ya9/ThbB7yleqJIhz5GY2q76tCCwHPhn5qDDMhlA9kKV6fG23gA==} 132 + 133 + '@atproto/oauth-client-node@0.3.7': 134 + resolution: {integrity: sha512-6xtOSmYwB/nfT/YWI3Syrl1ywa0MFre8FmFeiGtvZ4jVSx5aJFR7plG3RaWtu2U9InAiK2Iz7RMPZTvDGkTiWg==} 135 + engines: {node: '>=18.7.0'} 136 + 137 + '@atproto/oauth-client@0.5.5': 138 + resolution: {integrity: sha512-J0WK3vKVduxUuV+0XmXjCc0QJ1pUzKYZbrtFUF7wVzXnufSRsoaZqQP25cdzgADyUOwW7dttJBi06aOkY1mTKA==} 139 + 140 + '@atproto/oauth-types@0.4.1': 141 + resolution: {integrity: sha512-c5ixf2ZOzcltOu1fDBnO/tok6Wj7JDDK66+Z0q/+bAr8LXgOnxP7zQfJ+DD4gTkB+saTqsqWtVv8qvx/IEtm1g==} 142 + 143 + '@atproto/syntax@0.4.1': 144 + resolution: {integrity: sha512-CJdImtLAiFO+0z3BWTtxwk6aY5w4t8orHTMVJgkf++QRJWTxPbIFko/0hrkADB7n2EruDxDSeAgfUGehpH6ngw==} 145 + 146 + '@atproto/xrpc@0.7.4': 147 + resolution: {integrity: sha512-sDi68+QE1XHegTaNAndlX41Gp827pouSzSs8CyAwhrqZdsJUxE3P7TMtrA0z+zAjvxVyvzscRc0TsN/fGUGrhw==} 148 + 149 + '@badrap/valita@0.4.6': 150 + resolution: {integrity: sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==} 151 + engines: {node: '>= 18'} 152 + 153 + '@cbor-extract/cbor-extract-darwin-arm64@2.2.0': 154 + resolution: {integrity: sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==} 155 + cpu: [arm64] 156 + os: [darwin] 157 + 158 + '@cbor-extract/cbor-extract-darwin-x64@2.2.0': 159 + resolution: {integrity: sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==} 160 + cpu: [x64] 161 + os: [darwin] 162 + 163 + '@cbor-extract/cbor-extract-linux-arm64@2.2.0': 164 + resolution: {integrity: sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==} 165 + cpu: [arm64] 166 + os: [linux] 167 + 168 + '@cbor-extract/cbor-extract-linux-arm@2.2.0': 169 + resolution: {integrity: sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==} 170 + cpu: [arm] 171 + os: [linux] 172 + 173 + '@cbor-extract/cbor-extract-linux-x64@2.2.0': 174 + resolution: {integrity: sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==} 175 + cpu: [x64] 176 + os: [linux] 177 + 178 + '@cbor-extract/cbor-extract-win32-x64@2.2.0': 179 + resolution: {integrity: sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==} 180 + cpu: [x64] 181 + os: [win32] 182 + 183 + '@drizzle-team/brocli@0.10.2': 184 + resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} 185 + 186 + '@esbuild-kit/core-utils@3.3.2': 187 + resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} 188 + deprecated: 'Merged into tsx: https://tsx.is' 189 + 190 + '@esbuild-kit/esm-loader@2.6.5': 191 + resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} 192 + deprecated: 'Merged into tsx: https://tsx.is' 193 + 194 + '@esbuild/aix-ppc64@0.25.9': 195 + resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} 196 + engines: {node: '>=18'} 197 + cpu: [ppc64] 198 + os: [aix] 199 + 200 + '@esbuild/android-arm64@0.18.20': 201 + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} 202 + engines: {node: '>=12'} 203 + cpu: [arm64] 204 + os: [android] 205 + 206 + '@esbuild/android-arm64@0.25.9': 207 + resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} 208 + engines: {node: '>=18'} 209 + cpu: [arm64] 210 + os: [android] 211 + 212 + '@esbuild/android-arm@0.18.20': 213 + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} 214 + engines: {node: '>=12'} 215 + cpu: [arm] 216 + os: [android] 217 + 218 + '@esbuild/android-arm@0.25.9': 219 + resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} 220 + engines: {node: '>=18'} 221 + cpu: [arm] 222 + os: [android] 223 + 224 + '@esbuild/android-x64@0.18.20': 225 + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} 226 + engines: {node: '>=12'} 227 + cpu: [x64] 228 + os: [android] 229 + 230 + '@esbuild/android-x64@0.25.9': 231 + resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} 232 + engines: {node: '>=18'} 233 + cpu: [x64] 234 + os: [android] 235 + 236 + '@esbuild/darwin-arm64@0.18.20': 237 + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} 238 + engines: {node: '>=12'} 239 + cpu: [arm64] 240 + os: [darwin] 241 + 242 + '@esbuild/darwin-arm64@0.25.9': 243 + resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} 244 + engines: {node: '>=18'} 245 + cpu: [arm64] 246 + os: [darwin] 247 + 248 + '@esbuild/darwin-x64@0.18.20': 249 + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} 250 + engines: {node: '>=12'} 251 + cpu: [x64] 252 + os: [darwin] 253 + 254 + '@esbuild/darwin-x64@0.25.9': 255 + resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} 256 + engines: {node: '>=18'} 257 + cpu: [x64] 258 + os: [darwin] 259 + 260 + '@esbuild/freebsd-arm64@0.18.20': 261 + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} 262 + engines: {node: '>=12'} 263 + cpu: [arm64] 264 + os: [freebsd] 265 + 266 + '@esbuild/freebsd-arm64@0.25.9': 267 + resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} 268 + engines: {node: '>=18'} 269 + cpu: [arm64] 270 + os: [freebsd] 271 + 272 + '@esbuild/freebsd-x64@0.18.20': 273 + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} 274 + engines: {node: '>=12'} 275 + cpu: [x64] 276 + os: [freebsd] 277 + 278 + '@esbuild/freebsd-x64@0.25.9': 279 + resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} 280 + engines: {node: '>=18'} 281 + cpu: [x64] 282 + os: [freebsd] 283 + 284 + '@esbuild/linux-arm64@0.18.20': 285 + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} 286 + engines: {node: '>=12'} 287 + cpu: [arm64] 288 + os: [linux] 289 + 290 + '@esbuild/linux-arm64@0.25.9': 291 + resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} 292 + engines: {node: '>=18'} 293 + cpu: [arm64] 294 + os: [linux] 295 + 296 + '@esbuild/linux-arm@0.18.20': 297 + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} 298 + engines: {node: '>=12'} 299 + cpu: [arm] 300 + os: [linux] 301 + 302 + '@esbuild/linux-arm@0.25.9': 303 + resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} 304 + engines: {node: '>=18'} 305 + cpu: [arm] 306 + os: [linux] 307 + 308 + '@esbuild/linux-ia32@0.18.20': 309 + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} 310 + engines: {node: '>=12'} 311 + cpu: [ia32] 312 + os: [linux] 313 + 314 + '@esbuild/linux-ia32@0.25.9': 315 + resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} 316 + engines: {node: '>=18'} 317 + cpu: [ia32] 318 + os: [linux] 319 + 320 + '@esbuild/linux-loong64@0.18.20': 321 + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} 322 + engines: {node: '>=12'} 323 + cpu: [loong64] 324 + os: [linux] 325 + 326 + '@esbuild/linux-loong64@0.25.9': 327 + resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} 328 + engines: {node: '>=18'} 329 + cpu: [loong64] 330 + os: [linux] 331 + 332 + '@esbuild/linux-mips64el@0.18.20': 333 + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} 334 + engines: {node: '>=12'} 335 + cpu: [mips64el] 336 + os: [linux] 337 + 338 + '@esbuild/linux-mips64el@0.25.9': 339 + resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} 340 + engines: {node: '>=18'} 341 + cpu: [mips64el] 342 + os: [linux] 343 + 344 + '@esbuild/linux-ppc64@0.18.20': 345 + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} 346 + engines: {node: '>=12'} 347 + cpu: [ppc64] 348 + os: [linux] 349 + 350 + '@esbuild/linux-ppc64@0.25.9': 351 + resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} 352 + engines: {node: '>=18'} 353 + cpu: [ppc64] 354 + os: [linux] 355 + 356 + '@esbuild/linux-riscv64@0.18.20': 357 + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} 358 + engines: {node: '>=12'} 359 + cpu: [riscv64] 360 + os: [linux] 361 + 362 + '@esbuild/linux-riscv64@0.25.9': 363 + resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} 364 + engines: {node: '>=18'} 365 + cpu: [riscv64] 366 + os: [linux] 367 + 368 + '@esbuild/linux-s390x@0.18.20': 369 + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} 370 + engines: {node: '>=12'} 371 + cpu: [s390x] 372 + os: [linux] 373 + 374 + '@esbuild/linux-s390x@0.25.9': 375 + resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} 376 + engines: {node: '>=18'} 377 + cpu: [s390x] 378 + os: [linux] 379 + 380 + '@esbuild/linux-x64@0.18.20': 381 + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} 382 + engines: {node: '>=12'} 383 + cpu: [x64] 384 + os: [linux] 385 + 386 + '@esbuild/linux-x64@0.25.9': 387 + resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} 388 + engines: {node: '>=18'} 389 + cpu: [x64] 390 + os: [linux] 391 + 392 + '@esbuild/netbsd-arm64@0.25.9': 393 + resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} 394 + engines: {node: '>=18'} 395 + cpu: [arm64] 396 + os: [netbsd] 397 + 398 + '@esbuild/netbsd-x64@0.18.20': 399 + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} 400 + engines: {node: '>=12'} 401 + cpu: [x64] 402 + os: [netbsd] 403 + 404 + '@esbuild/netbsd-x64@0.25.9': 405 + resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} 406 + engines: {node: '>=18'} 407 + cpu: [x64] 408 + os: [netbsd] 409 + 410 + '@esbuild/openbsd-arm64@0.25.9': 411 + resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} 412 + engines: {node: '>=18'} 413 + cpu: [arm64] 414 + os: [openbsd] 415 + 416 + '@esbuild/openbsd-x64@0.18.20': 417 + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} 418 + engines: {node: '>=12'} 419 + cpu: [x64] 420 + os: [openbsd] 421 + 422 + '@esbuild/openbsd-x64@0.25.9': 423 + resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} 424 + engines: {node: '>=18'} 425 + cpu: [x64] 426 + os: [openbsd] 427 + 428 + '@esbuild/openharmony-arm64@0.25.9': 429 + resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} 430 + engines: {node: '>=18'} 431 + cpu: [arm64] 432 + os: [openharmony] 433 + 434 + '@esbuild/sunos-x64@0.18.20': 435 + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} 436 + engines: {node: '>=12'} 437 + cpu: [x64] 438 + os: [sunos] 439 + 440 + '@esbuild/sunos-x64@0.25.9': 441 + resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} 442 + engines: {node: '>=18'} 443 + cpu: [x64] 444 + os: [sunos] 445 + 446 + '@esbuild/win32-arm64@0.18.20': 447 + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} 448 + engines: {node: '>=12'} 449 + cpu: [arm64] 450 + os: [win32] 451 + 452 + '@esbuild/win32-arm64@0.25.9': 453 + resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} 454 + engines: {node: '>=18'} 455 + cpu: [arm64] 456 + os: [win32] 457 + 458 + '@esbuild/win32-ia32@0.18.20': 459 + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} 460 + engines: {node: '>=12'} 461 + cpu: [ia32] 462 + os: [win32] 463 + 464 + '@esbuild/win32-ia32@0.25.9': 465 + resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} 466 + engines: {node: '>=18'} 467 + cpu: [ia32] 468 + os: [win32] 469 + 470 + '@esbuild/win32-x64@0.18.20': 471 + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} 472 + engines: {node: '>=12'} 473 + cpu: [x64] 474 + os: [win32] 475 + 476 + '@esbuild/win32-x64@0.25.9': 477 + resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} 478 + engines: {node: '>=18'} 479 + cpu: [x64] 480 + os: [win32] 481 + 482 + '@externdefs/collider@0.3.0': 483 + resolution: {integrity: sha512-x5CpeZ4c8n+1wMFthUMWSQKqCGcQo52/Qbda5ES+JFRRg/D8Ep6/JOvUUq5HExFuv/wW+6UYG2U/mXzw0IAd8Q==} 484 + peerDependencies: 485 + '@badrap/valita': ^0.4.4 486 + 487 + '@hono/node-server@1.19.1': 488 + resolution: {integrity: sha512-h44e5s+ByUriaRIbeS/C74O8v90m0A95luyYQGMF7KEn96KkYMXO7bZAwombzTpjQTU4e0TkU8U1WBIXlwuwtA==} 489 + engines: {node: '>=18.14.1'} 490 + peerDependencies: 491 + hono: ^4 492 + 493 + '@ipld/dag-cbor@7.0.3': 494 + resolution: {integrity: sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==} 495 + 496 + '@skyware/jetstream@0.2.5': 497 + resolution: {integrity: sha512-fM/zs03DLwqRyzZZJFWN20e76KrdqIp97Tlm8Cek+vxn96+tu5d/fx79V6H85L0QN6HvGiX2l9A8hWFqHvYlOA==} 498 + 499 + '@types/better-sqlite3@7.6.13': 500 + resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} 501 + 502 + '@types/node@24.3.1': 503 + resolution: {integrity: sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==} 504 + 505 + '@types/react@19.1.12': 506 + resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} 507 + 508 + abort-controller@3.0.0: 509 + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} 510 + engines: {node: '>=6.5'} 511 + 512 + atomic-sleep@1.0.0: 513 + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} 514 + engines: {node: '>=8.0.0'} 515 + 516 + await-lock@2.2.2: 517 + resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} 518 + 519 + base64-js@1.5.1: 520 + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 521 + 522 + better-sqlite3@12.2.0: 523 + resolution: {integrity: sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ==} 524 + engines: {node: 20.x || 22.x || 23.x || 24.x} 525 + 526 + bindings@1.5.0: 527 + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} 528 + 529 + bl@4.1.0: 530 + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} 531 + 532 + buffer-from@1.1.2: 533 + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 534 + 535 + buffer@5.7.1: 536 + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} 537 + 538 + buffer@6.0.3: 539 + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} 540 + 541 + bun-types@1.2.21: 542 + resolution: {integrity: sha512-sa2Tj77Ijc/NTLS0/Odjq/qngmEPZfbfnOERi0KRUYhT9R8M4VBioWVmMWE5GrYbKMc+5lVybXygLdibHaqVqw==} 543 + peerDependencies: 544 + '@types/react': ^19 545 + 546 + cbor-extract@2.2.0: 547 + resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} 548 + hasBin: true 549 + 550 + cbor-x@1.6.0: 551 + resolution: {integrity: sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==} 552 + 553 + cborg@1.10.2: 554 + resolution: {integrity: sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==} 555 + hasBin: true 556 + 557 + chownr@1.1.4: 558 + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} 559 + 560 + csstype@3.1.3: 561 + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 562 + 563 + debug@4.4.1: 564 + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} 565 + engines: {node: '>=6.0'} 566 + peerDependencies: 567 + supports-color: '*' 568 + peerDependenciesMeta: 569 + supports-color: 570 + optional: true 571 + 572 + decompress-response@6.0.0: 573 + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} 574 + engines: {node: '>=10'} 575 + 576 + deep-extend@0.6.0: 577 + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} 578 + engines: {node: '>=4.0.0'} 579 + 580 + detect-libc@2.0.4: 581 + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} 582 + engines: {node: '>=8'} 583 + 584 + dotenv@17.2.2: 585 + resolution: {integrity: sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==} 586 + engines: {node: '>=12'} 587 + 588 + drizzle-kit@0.31.4: 589 + resolution: {integrity: sha512-tCPWVZWZqWVx2XUsVpJRnH9Mx0ClVOf5YUHerZ5so1OKSlqww4zy1R5ksEdGRcO3tM3zj0PYN6V48TbQCL1RfA==} 590 + hasBin: true 591 + 592 + drizzle-orm@0.44.5: 593 + resolution: {integrity: sha512-jBe37K7d8ZSKptdKfakQFdeljtu3P2Cbo7tJoJSVZADzIKOBo9IAJPOmMsH2bZl90bZgh8FQlD8BjxXA/zuBkQ==} 594 + peerDependencies: 595 + '@aws-sdk/client-rds-data': '>=3' 596 + '@cloudflare/workers-types': '>=4' 597 + '@electric-sql/pglite': '>=0.2.0' 598 + '@libsql/client': '>=0.10.0' 599 + '@libsql/client-wasm': '>=0.10.0' 600 + '@neondatabase/serverless': '>=0.10.0' 601 + '@op-engineering/op-sqlite': '>=2' 602 + '@opentelemetry/api': ^1.4.1 603 + '@planetscale/database': '>=1.13' 604 + '@prisma/client': '*' 605 + '@tidbcloud/serverless': '*' 606 + '@types/better-sqlite3': '*' 607 + '@types/pg': '*' 608 + '@types/sql.js': '*' 609 + '@upstash/redis': '>=1.34.7' 610 + '@vercel/postgres': '>=0.8.0' 611 + '@xata.io/client': '*' 612 + better-sqlite3: '>=7' 613 + bun-types: '*' 614 + expo-sqlite: '>=14.0.0' 615 + gel: '>=2' 616 + knex: '*' 617 + kysely: '*' 618 + mysql2: '>=2' 619 + pg: '>=8' 620 + postgres: '>=3' 621 + prisma: '*' 622 + sql.js: '>=1' 623 + sqlite3: '>=5' 624 + peerDependenciesMeta: 625 + '@aws-sdk/client-rds-data': 626 + optional: true 627 + '@cloudflare/workers-types': 628 + optional: true 629 + '@electric-sql/pglite': 630 + optional: true 631 + '@libsql/client': 632 + optional: true 633 + '@libsql/client-wasm': 634 + optional: true 635 + '@neondatabase/serverless': 636 + optional: true 637 + '@op-engineering/op-sqlite': 638 + optional: true 639 + '@opentelemetry/api': 640 + optional: true 641 + '@planetscale/database': 642 + optional: true 643 + '@prisma/client': 644 + optional: true 645 + '@tidbcloud/serverless': 646 + optional: true 647 + '@types/better-sqlite3': 648 + optional: true 649 + '@types/pg': 650 + optional: true 651 + '@types/sql.js': 652 + optional: true 653 + '@upstash/redis': 654 + optional: true 655 + '@vercel/postgres': 656 + optional: true 657 + '@xata.io/client': 658 + optional: true 659 + better-sqlite3: 660 + optional: true 661 + bun-types: 662 + optional: true 663 + expo-sqlite: 664 + optional: true 665 + gel: 666 + optional: true 667 + knex: 668 + optional: true 669 + kysely: 670 + optional: true 671 + mysql2: 672 + optional: true 673 + pg: 674 + optional: true 675 + postgres: 676 + optional: true 677 + prisma: 678 + optional: true 679 + sql.js: 680 + optional: true 681 + sqlite3: 682 + optional: true 683 + 684 + end-of-stream@1.4.5: 685 + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} 686 + 687 + esbuild-register@3.6.0: 688 + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} 689 + peerDependencies: 690 + esbuild: '>=0.12 <1' 691 + 692 + esbuild@0.18.20: 693 + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} 694 + engines: {node: '>=12'} 695 + hasBin: true 696 + 697 + esbuild@0.25.9: 698 + resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} 699 + engines: {node: '>=18'} 700 + hasBin: true 701 + 702 + esm-env@1.2.2: 703 + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} 704 + 705 + event-target-polyfill@0.0.4: 706 + resolution: {integrity: sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==} 707 + 708 + event-target-shim@5.0.1: 709 + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} 710 + engines: {node: '>=6'} 711 + 712 + events@3.3.0: 713 + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 714 + engines: {node: '>=0.8.x'} 715 + 716 + expand-template@2.0.3: 717 + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} 718 + engines: {node: '>=6'} 719 + 720 + fast-redact@3.5.0: 721 + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} 722 + engines: {node: '>=6'} 723 + 724 + file-uri-to-path@1.0.0: 725 + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} 726 + 727 + fs-constants@1.0.0: 728 + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} 729 + 730 + fsevents@2.3.3: 731 + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 732 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 733 + os: [darwin] 734 + 735 + get-tsconfig@4.10.1: 736 + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} 737 + 738 + github-from-package@0.0.0: 739 + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} 740 + 741 + graphemer@1.4.0: 742 + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 743 + 744 + hono@4.9.6: 745 + resolution: {integrity: sha512-doVjXhSFvYZ7y0dNokjwwSahcrAfdz+/BCLvAMa/vHLzjj8+CFyV5xteThGUsKdkaasgN+gF2mUxao+SGLpUeA==} 746 + engines: {node: '>=16.9.0'} 747 + 748 + ieee754@1.2.1: 749 + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 750 + 751 + inherits@2.0.4: 752 + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 753 + 754 + ini@1.3.8: 755 + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} 756 + 757 + ipaddr.js@2.2.0: 758 + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} 759 + engines: {node: '>= 10'} 760 + 761 + iso-datestring-validator@2.2.2: 762 + resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} 763 + 764 + jose@5.10.0: 765 + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} 766 + 767 + lru-cache@10.4.3: 768 + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 769 + 770 + mimic-response@3.1.0: 771 + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} 772 + engines: {node: '>=10'} 773 + 774 + minimist@1.2.8: 775 + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 776 + 777 + mkdirp-classic@0.5.3: 778 + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} 779 + 780 + ms@2.1.3: 781 + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 782 + 783 + multiformats@9.9.0: 784 + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} 785 + 786 + napi-build-utils@2.0.0: 787 + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} 788 + 789 + node-abi@3.77.0: 790 + resolution: {integrity: sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==} 791 + engines: {node: '>=10'} 792 + 793 + node-gyp-build-optional-packages@5.1.1: 794 + resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} 795 + hasBin: true 796 + 797 + on-exit-leak-free@2.1.2: 798 + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} 799 + engines: {node: '>=14.0.0'} 800 + 801 + once@1.4.0: 802 + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 803 + 804 + partysocket@1.1.5: 805 + resolution: {integrity: sha512-8uw9foq9bij4sKLCtTSHvyqMrMTQ5FJjrHc7BjoM2s95Vu7xYCN63ABpI7OZHC7ZMP5xaom/A+SsoFPXmTV6ZQ==} 806 + 807 + picocolors@1.1.1: 808 + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 809 + 810 + pino-abstract-transport@1.2.0: 811 + resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} 812 + 813 + pino-std-serializers@6.2.2: 814 + resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} 815 + 816 + pino@8.21.0: 817 + resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} 818 + hasBin: true 819 + 820 + prebuild-install@7.1.3: 821 + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} 822 + engines: {node: '>=10'} 823 + hasBin: true 824 + 825 + prettier@3.6.2: 826 + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} 827 + engines: {node: '>=14'} 828 + hasBin: true 829 + 830 + process-warning@3.0.0: 831 + resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} 832 + 833 + process@0.11.10: 834 + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} 835 + engines: {node: '>= 0.6.0'} 836 + 837 + pump@3.0.3: 838 + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} 839 + 840 + quick-format-unescaped@4.0.4: 841 + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} 842 + 843 + rc@1.2.8: 844 + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} 845 + hasBin: true 846 + 847 + readable-stream@3.6.2: 848 + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} 849 + engines: {node: '>= 6'} 850 + 851 + readable-stream@4.7.0: 852 + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} 853 + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 854 + 855 + real-require@0.2.0: 856 + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} 857 + engines: {node: '>= 12.13.0'} 858 + 859 + resolve-pkg-maps@1.0.0: 860 + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 861 + 862 + safe-buffer@5.2.1: 863 + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 864 + 865 + safe-stable-stringify@2.5.0: 866 + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} 867 + engines: {node: '>=10'} 868 + 869 + semver@7.7.2: 870 + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} 871 + engines: {node: '>=10'} 872 + hasBin: true 873 + 874 + simple-concat@1.0.1: 875 + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} 876 + 877 + simple-get@4.0.1: 878 + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} 879 + 880 + sonic-boom@3.8.1: 881 + resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} 882 + 883 + source-map-support@0.5.21: 884 + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 885 + 886 + source-map@0.6.1: 887 + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 888 + engines: {node: '>=0.10.0'} 889 + 890 + split2@4.2.0: 891 + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} 892 + engines: {node: '>= 10.x'} 893 + 894 + string_decoder@1.3.0: 895 + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 896 + 897 + strip-json-comments@2.0.1: 898 + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} 899 + engines: {node: '>=0.10.0'} 900 + 901 + tar-fs@2.1.3: 902 + resolution: {integrity: sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==} 903 + 904 + tar-stream@2.2.0: 905 + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} 906 + engines: {node: '>=6'} 907 + 908 + thread-stream@2.7.0: 909 + resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} 910 + 911 + tiny-emitter@2.1.0: 912 + resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} 913 + 914 + tlds@1.260.0: 915 + resolution: {integrity: sha512-78+28EWBhCEE7qlyaHA9OR3IPvbCLiDh3Ckla593TksfFc9vfTsgvH7eS+dr3o9qr31gwGbogcI16yN91PoRjQ==} 916 + hasBin: true 917 + 918 + tsx@4.20.5: 919 + resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} 920 + engines: {node: '>=18.0.0'} 921 + hasBin: true 922 + 923 + tunnel-agent@0.6.0: 924 + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} 925 + 926 + typescript@5.9.2: 927 + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} 928 + engines: {node: '>=14.17'} 929 + hasBin: true 930 + 931 + uint8arrays@3.0.0: 932 + resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} 933 + 934 + undici-types@7.10.0: 935 + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} 936 + 937 + undici@6.21.3: 938 + resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} 939 + engines: {node: '>=18.17'} 940 + 941 + util-deprecate@1.0.2: 942 + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 943 + 944 + wrappy@1.0.2: 945 + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 946 + 947 + zod@3.25.76: 948 + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} 949 + 950 + snapshots: 951 + 952 + '@atcute/atproto@3.1.3': 953 + dependencies: 954 + '@atcute/lexicons': 1.1.1 955 + 956 + '@atcute/bluesky@3.2.2': 957 + dependencies: 958 + '@atcute/atproto': 3.1.3 959 + '@atcute/lexicons': 1.1.1 960 + 961 + '@atcute/lex-cli@2.2.0': 962 + dependencies: 963 + '@atcute/lexicon-doc': 1.1.1 964 + '@badrap/valita': 0.4.6 965 + '@externdefs/collider': 0.3.0(@badrap/valita@0.4.6) 966 + picocolors: 1.1.1 967 + prettier: 3.6.2 968 + 969 + '@atcute/lexicon-doc@1.1.1': 970 + dependencies: 971 + '@badrap/valita': 0.4.6 972 + 973 + '@atcute/lexicons@1.1.1': 974 + dependencies: 975 + esm-env: 1.2.2 976 + 977 + '@atproto-labs/did-resolver@0.2.1': 978 + dependencies: 979 + '@atproto-labs/fetch': 0.2.3 980 + '@atproto-labs/pipe': 0.1.1 981 + '@atproto-labs/simple-store': 0.3.0 982 + '@atproto-labs/simple-store-memory': 0.1.4 983 + '@atproto/did': 0.2.0 984 + zod: 3.25.76 985 + 986 + '@atproto-labs/fetch-node@0.1.10': 987 + dependencies: 988 + '@atproto-labs/fetch': 0.2.3 989 + '@atproto-labs/pipe': 0.1.1 990 + ipaddr.js: 2.2.0 991 + undici: 6.21.3 992 + 993 + '@atproto-labs/fetch@0.2.3': 994 + dependencies: 995 + '@atproto-labs/pipe': 0.1.1 996 + 997 + '@atproto-labs/handle-resolver-node@0.1.19': 998 + dependencies: 999 + '@atproto-labs/fetch-node': 0.1.10 1000 + '@atproto-labs/handle-resolver': 0.3.1 1001 + '@atproto/did': 0.2.0 1002 + 1003 + '@atproto-labs/handle-resolver@0.3.1': 1004 + dependencies: 1005 + '@atproto-labs/simple-store': 0.3.0 1006 + '@atproto-labs/simple-store-memory': 0.1.4 1007 + '@atproto/did': 0.2.0 1008 + zod: 3.25.76 1009 + 1010 + '@atproto-labs/identity-resolver@0.3.1': 1011 + dependencies: 1012 + '@atproto-labs/did-resolver': 0.2.1 1013 + '@atproto-labs/handle-resolver': 0.3.1 1014 + 1015 + '@atproto-labs/pipe@0.1.1': {} 1016 + 1017 + '@atproto-labs/simple-store-memory@0.1.4': 1018 + dependencies: 1019 + '@atproto-labs/simple-store': 0.3.0 1020 + lru-cache: 10.4.3 1021 + 1022 + '@atproto-labs/simple-store@0.3.0': {} 1023 + 1024 + '@atproto/api@0.16.7': 1025 + dependencies: 1026 + '@atproto/common-web': 0.4.2 1027 + '@atproto/lexicon': 0.5.0 1028 + '@atproto/syntax': 0.4.1 1029 + '@atproto/xrpc': 0.7.4 1030 + await-lock: 2.2.2 1031 + multiformats: 9.9.0 1032 + tlds: 1.260.0 1033 + zod: 3.25.76 1034 + 1035 + '@atproto/common-web@0.4.2': 1036 + dependencies: 1037 + graphemer: 1.4.0 1038 + multiformats: 9.9.0 1039 + uint8arrays: 3.0.0 1040 + zod: 3.25.76 1041 + 1042 + '@atproto/common@0.4.11': 1043 + dependencies: 1044 + '@atproto/common-web': 0.4.2 1045 + '@ipld/dag-cbor': 7.0.3 1046 + cbor-x: 1.6.0 1047 + iso-datestring-validator: 2.2.2 1048 + multiformats: 9.9.0 1049 + pino: 8.21.0 1050 + 1051 + '@atproto/did@0.2.0': 1052 + dependencies: 1053 + zod: 3.25.76 1054 + 1055 + '@atproto/jwk-jose@0.1.10': 1056 + dependencies: 1057 + '@atproto/jwk': 0.5.0 1058 + jose: 5.10.0 1059 + 1060 + '@atproto/jwk-webcrypto@0.1.10': 1061 + dependencies: 1062 + '@atproto/jwk': 0.5.0 1063 + '@atproto/jwk-jose': 0.1.10 1064 + zod: 3.25.76 1065 + 1066 + '@atproto/jwk@0.5.0': 1067 + dependencies: 1068 + multiformats: 9.9.0 1069 + zod: 3.25.76 1070 + 1071 + '@atproto/lexicon@0.5.0': 1072 + dependencies: 1073 + '@atproto/common-web': 0.4.2 1074 + '@atproto/syntax': 0.4.1 1075 + iso-datestring-validator: 2.2.2 1076 + multiformats: 9.9.0 1077 + zod: 3.25.76 1078 + 1079 + '@atproto/oauth-client-node@0.3.7': 1080 + dependencies: 1081 + '@atproto-labs/did-resolver': 0.2.1 1082 + '@atproto-labs/handle-resolver-node': 0.1.19 1083 + '@atproto-labs/simple-store': 0.3.0 1084 + '@atproto/did': 0.2.0 1085 + '@atproto/jwk': 0.5.0 1086 + '@atproto/jwk-jose': 0.1.10 1087 + '@atproto/jwk-webcrypto': 0.1.10 1088 + '@atproto/oauth-client': 0.5.5 1089 + '@atproto/oauth-types': 0.4.1 1090 + 1091 + '@atproto/oauth-client@0.5.5': 1092 + dependencies: 1093 + '@atproto-labs/did-resolver': 0.2.1 1094 + '@atproto-labs/fetch': 0.2.3 1095 + '@atproto-labs/handle-resolver': 0.3.1 1096 + '@atproto-labs/identity-resolver': 0.3.1 1097 + '@atproto-labs/simple-store': 0.3.0 1098 + '@atproto-labs/simple-store-memory': 0.1.4 1099 + '@atproto/did': 0.2.0 1100 + '@atproto/jwk': 0.5.0 1101 + '@atproto/oauth-types': 0.4.1 1102 + '@atproto/xrpc': 0.7.4 1103 + multiformats: 9.9.0 1104 + zod: 3.25.76 1105 + 1106 + '@atproto/oauth-types@0.4.1': 1107 + dependencies: 1108 + '@atproto/jwk': 0.5.0 1109 + zod: 3.25.76 1110 + 1111 + '@atproto/syntax@0.4.1': {} 1112 + 1113 + '@atproto/xrpc@0.7.4': 1114 + dependencies: 1115 + '@atproto/lexicon': 0.5.0 1116 + zod: 3.25.76 1117 + 1118 + '@badrap/valita@0.4.6': {} 1119 + 1120 + '@cbor-extract/cbor-extract-darwin-arm64@2.2.0': 1121 + optional: true 1122 + 1123 + '@cbor-extract/cbor-extract-darwin-x64@2.2.0': 1124 + optional: true 1125 + 1126 + '@cbor-extract/cbor-extract-linux-arm64@2.2.0': 1127 + optional: true 1128 + 1129 + '@cbor-extract/cbor-extract-linux-arm@2.2.0': 1130 + optional: true 1131 + 1132 + '@cbor-extract/cbor-extract-linux-x64@2.2.0': 1133 + optional: true 1134 + 1135 + '@cbor-extract/cbor-extract-win32-x64@2.2.0': 1136 + optional: true 1137 + 1138 + '@drizzle-team/brocli@0.10.2': {} 1139 + 1140 + '@esbuild-kit/core-utils@3.3.2': 1141 + dependencies: 1142 + esbuild: 0.18.20 1143 + source-map-support: 0.5.21 1144 + 1145 + '@esbuild-kit/esm-loader@2.6.5': 1146 + dependencies: 1147 + '@esbuild-kit/core-utils': 3.3.2 1148 + get-tsconfig: 4.10.1 1149 + 1150 + '@esbuild/aix-ppc64@0.25.9': 1151 + optional: true 1152 + 1153 + '@esbuild/android-arm64@0.18.20': 1154 + optional: true 1155 + 1156 + '@esbuild/android-arm64@0.25.9': 1157 + optional: true 1158 + 1159 + '@esbuild/android-arm@0.18.20': 1160 + optional: true 1161 + 1162 + '@esbuild/android-arm@0.25.9': 1163 + optional: true 1164 + 1165 + '@esbuild/android-x64@0.18.20': 1166 + optional: true 1167 + 1168 + '@esbuild/android-x64@0.25.9': 1169 + optional: true 1170 + 1171 + '@esbuild/darwin-arm64@0.18.20': 1172 + optional: true 1173 + 1174 + '@esbuild/darwin-arm64@0.25.9': 1175 + optional: true 1176 + 1177 + '@esbuild/darwin-x64@0.18.20': 1178 + optional: true 1179 + 1180 + '@esbuild/darwin-x64@0.25.9': 1181 + optional: true 1182 + 1183 + '@esbuild/freebsd-arm64@0.18.20': 1184 + optional: true 1185 + 1186 + '@esbuild/freebsd-arm64@0.25.9': 1187 + optional: true 1188 + 1189 + '@esbuild/freebsd-x64@0.18.20': 1190 + optional: true 1191 + 1192 + '@esbuild/freebsd-x64@0.25.9': 1193 + optional: true 1194 + 1195 + '@esbuild/linux-arm64@0.18.20': 1196 + optional: true 1197 + 1198 + '@esbuild/linux-arm64@0.25.9': 1199 + optional: true 1200 + 1201 + '@esbuild/linux-arm@0.18.20': 1202 + optional: true 1203 + 1204 + '@esbuild/linux-arm@0.25.9': 1205 + optional: true 1206 + 1207 + '@esbuild/linux-ia32@0.18.20': 1208 + optional: true 1209 + 1210 + '@esbuild/linux-ia32@0.25.9': 1211 + optional: true 1212 + 1213 + '@esbuild/linux-loong64@0.18.20': 1214 + optional: true 1215 + 1216 + '@esbuild/linux-loong64@0.25.9': 1217 + optional: true 1218 + 1219 + '@esbuild/linux-mips64el@0.18.20': 1220 + optional: true 1221 + 1222 + '@esbuild/linux-mips64el@0.25.9': 1223 + optional: true 1224 + 1225 + '@esbuild/linux-ppc64@0.18.20': 1226 + optional: true 1227 + 1228 + '@esbuild/linux-ppc64@0.25.9': 1229 + optional: true 1230 + 1231 + '@esbuild/linux-riscv64@0.18.20': 1232 + optional: true 1233 + 1234 + '@esbuild/linux-riscv64@0.25.9': 1235 + optional: true 1236 + 1237 + '@esbuild/linux-s390x@0.18.20': 1238 + optional: true 1239 + 1240 + '@esbuild/linux-s390x@0.25.9': 1241 + optional: true 1242 + 1243 + '@esbuild/linux-x64@0.18.20': 1244 + optional: true 1245 + 1246 + '@esbuild/linux-x64@0.25.9': 1247 + optional: true 1248 + 1249 + '@esbuild/netbsd-arm64@0.25.9': 1250 + optional: true 1251 + 1252 + '@esbuild/netbsd-x64@0.18.20': 1253 + optional: true 1254 + 1255 + '@esbuild/netbsd-x64@0.25.9': 1256 + optional: true 1257 + 1258 + '@esbuild/openbsd-arm64@0.25.9': 1259 + optional: true 1260 + 1261 + '@esbuild/openbsd-x64@0.18.20': 1262 + optional: true 1263 + 1264 + '@esbuild/openbsd-x64@0.25.9': 1265 + optional: true 1266 + 1267 + '@esbuild/openharmony-arm64@0.25.9': 1268 + optional: true 1269 + 1270 + '@esbuild/sunos-x64@0.18.20': 1271 + optional: true 1272 + 1273 + '@esbuild/sunos-x64@0.25.9': 1274 + optional: true 1275 + 1276 + '@esbuild/win32-arm64@0.18.20': 1277 + optional: true 1278 + 1279 + '@esbuild/win32-arm64@0.25.9': 1280 + optional: true 1281 + 1282 + '@esbuild/win32-ia32@0.18.20': 1283 + optional: true 1284 + 1285 + '@esbuild/win32-ia32@0.25.9': 1286 + optional: true 1287 + 1288 + '@esbuild/win32-x64@0.18.20': 1289 + optional: true 1290 + 1291 + '@esbuild/win32-x64@0.25.9': 1292 + optional: true 1293 + 1294 + '@externdefs/collider@0.3.0(@badrap/valita@0.4.6)': 1295 + dependencies: 1296 + '@badrap/valita': 0.4.6 1297 + 1298 + '@hono/node-server@1.19.1(hono@4.9.6)': 1299 + dependencies: 1300 + hono: 4.9.6 1301 + 1302 + '@ipld/dag-cbor@7.0.3': 1303 + dependencies: 1304 + cborg: 1.10.2 1305 + multiformats: 9.9.0 1306 + 1307 + '@skyware/jetstream@0.2.5': 1308 + dependencies: 1309 + '@atcute/atproto': 3.1.3 1310 + '@atcute/bluesky': 3.2.2 1311 + '@atcute/lexicons': 1.1.1 1312 + partysocket: 1.1.5 1313 + tiny-emitter: 2.1.0 1314 + 1315 + '@types/better-sqlite3@7.6.13': 1316 + dependencies: 1317 + '@types/node': 24.3.1 1318 + 1319 + '@types/node@24.3.1': 1320 + dependencies: 1321 + undici-types: 7.10.0 1322 + 1323 + '@types/react@19.1.12': 1324 + dependencies: 1325 + csstype: 3.1.3 1326 + optional: true 1327 + 1328 + abort-controller@3.0.0: 1329 + dependencies: 1330 + event-target-shim: 5.0.1 1331 + 1332 + atomic-sleep@1.0.0: {} 1333 + 1334 + await-lock@2.2.2: {} 1335 + 1336 + base64-js@1.5.1: {} 1337 + 1338 + better-sqlite3@12.2.0: 1339 + dependencies: 1340 + bindings: 1.5.0 1341 + prebuild-install: 7.1.3 1342 + 1343 + bindings@1.5.0: 1344 + dependencies: 1345 + file-uri-to-path: 1.0.0 1346 + 1347 + bl@4.1.0: 1348 + dependencies: 1349 + buffer: 5.7.1 1350 + inherits: 2.0.4 1351 + readable-stream: 3.6.2 1352 + 1353 + buffer-from@1.1.2: {} 1354 + 1355 + buffer@5.7.1: 1356 + dependencies: 1357 + base64-js: 1.5.1 1358 + ieee754: 1.2.1 1359 + 1360 + buffer@6.0.3: 1361 + dependencies: 1362 + base64-js: 1.5.1 1363 + ieee754: 1.2.1 1364 + 1365 + bun-types@1.2.21(@types/react@19.1.12): 1366 + dependencies: 1367 + '@types/node': 24.3.1 1368 + '@types/react': 19.1.12 1369 + optional: true 1370 + 1371 + cbor-extract@2.2.0: 1372 + dependencies: 1373 + node-gyp-build-optional-packages: 5.1.1 1374 + optionalDependencies: 1375 + '@cbor-extract/cbor-extract-darwin-arm64': 2.2.0 1376 + '@cbor-extract/cbor-extract-darwin-x64': 2.2.0 1377 + '@cbor-extract/cbor-extract-linux-arm': 2.2.0 1378 + '@cbor-extract/cbor-extract-linux-arm64': 2.2.0 1379 + '@cbor-extract/cbor-extract-linux-x64': 2.2.0 1380 + '@cbor-extract/cbor-extract-win32-x64': 2.2.0 1381 + optional: true 1382 + 1383 + cbor-x@1.6.0: 1384 + optionalDependencies: 1385 + cbor-extract: 2.2.0 1386 + 1387 + cborg@1.10.2: {} 1388 + 1389 + chownr@1.1.4: {} 1390 + 1391 + csstype@3.1.3: 1392 + optional: true 1393 + 1394 + debug@4.4.1: 1395 + dependencies: 1396 + ms: 2.1.3 1397 + 1398 + decompress-response@6.0.0: 1399 + dependencies: 1400 + mimic-response: 3.1.0 1401 + 1402 + deep-extend@0.6.0: {} 1403 + 1404 + detect-libc@2.0.4: {} 1405 + 1406 + dotenv@17.2.2: {} 1407 + 1408 + drizzle-kit@0.31.4: 1409 + dependencies: 1410 + '@drizzle-team/brocli': 0.10.2 1411 + '@esbuild-kit/esm-loader': 2.6.5 1412 + esbuild: 0.25.9 1413 + esbuild-register: 3.6.0(esbuild@0.25.9) 1414 + transitivePeerDependencies: 1415 + - supports-color 1416 + 1417 + drizzle-orm@0.44.5(@types/better-sqlite3@7.6.13)(better-sqlite3@12.2.0)(bun-types@1.2.21(@types/react@19.1.12)): 1418 + optionalDependencies: 1419 + '@types/better-sqlite3': 7.6.13 1420 + better-sqlite3: 12.2.0 1421 + bun-types: 1.2.21(@types/react@19.1.12) 1422 + 1423 + end-of-stream@1.4.5: 1424 + dependencies: 1425 + once: 1.4.0 1426 + 1427 + esbuild-register@3.6.0(esbuild@0.25.9): 1428 + dependencies: 1429 + debug: 4.4.1 1430 + esbuild: 0.25.9 1431 + transitivePeerDependencies: 1432 + - supports-color 1433 + 1434 + esbuild@0.18.20: 1435 + optionalDependencies: 1436 + '@esbuild/android-arm': 0.18.20 1437 + '@esbuild/android-arm64': 0.18.20 1438 + '@esbuild/android-x64': 0.18.20 1439 + '@esbuild/darwin-arm64': 0.18.20 1440 + '@esbuild/darwin-x64': 0.18.20 1441 + '@esbuild/freebsd-arm64': 0.18.20 1442 + '@esbuild/freebsd-x64': 0.18.20 1443 + '@esbuild/linux-arm': 0.18.20 1444 + '@esbuild/linux-arm64': 0.18.20 1445 + '@esbuild/linux-ia32': 0.18.20 1446 + '@esbuild/linux-loong64': 0.18.20 1447 + '@esbuild/linux-mips64el': 0.18.20 1448 + '@esbuild/linux-ppc64': 0.18.20 1449 + '@esbuild/linux-riscv64': 0.18.20 1450 + '@esbuild/linux-s390x': 0.18.20 1451 + '@esbuild/linux-x64': 0.18.20 1452 + '@esbuild/netbsd-x64': 0.18.20 1453 + '@esbuild/openbsd-x64': 0.18.20 1454 + '@esbuild/sunos-x64': 0.18.20 1455 + '@esbuild/win32-arm64': 0.18.20 1456 + '@esbuild/win32-ia32': 0.18.20 1457 + '@esbuild/win32-x64': 0.18.20 1458 + 1459 + esbuild@0.25.9: 1460 + optionalDependencies: 1461 + '@esbuild/aix-ppc64': 0.25.9 1462 + '@esbuild/android-arm': 0.25.9 1463 + '@esbuild/android-arm64': 0.25.9 1464 + '@esbuild/android-x64': 0.25.9 1465 + '@esbuild/darwin-arm64': 0.25.9 1466 + '@esbuild/darwin-x64': 0.25.9 1467 + '@esbuild/freebsd-arm64': 0.25.9 1468 + '@esbuild/freebsd-x64': 0.25.9 1469 + '@esbuild/linux-arm': 0.25.9 1470 + '@esbuild/linux-arm64': 0.25.9 1471 + '@esbuild/linux-ia32': 0.25.9 1472 + '@esbuild/linux-loong64': 0.25.9 1473 + '@esbuild/linux-mips64el': 0.25.9 1474 + '@esbuild/linux-ppc64': 0.25.9 1475 + '@esbuild/linux-riscv64': 0.25.9 1476 + '@esbuild/linux-s390x': 0.25.9 1477 + '@esbuild/linux-x64': 0.25.9 1478 + '@esbuild/netbsd-arm64': 0.25.9 1479 + '@esbuild/netbsd-x64': 0.25.9 1480 + '@esbuild/openbsd-arm64': 0.25.9 1481 + '@esbuild/openbsd-x64': 0.25.9 1482 + '@esbuild/openharmony-arm64': 0.25.9 1483 + '@esbuild/sunos-x64': 0.25.9 1484 + '@esbuild/win32-arm64': 0.25.9 1485 + '@esbuild/win32-ia32': 0.25.9 1486 + '@esbuild/win32-x64': 0.25.9 1487 + 1488 + esm-env@1.2.2: {} 1489 + 1490 + event-target-polyfill@0.0.4: {} 1491 + 1492 + event-target-shim@5.0.1: {} 1493 + 1494 + events@3.3.0: {} 1495 + 1496 + expand-template@2.0.3: {} 1497 + 1498 + fast-redact@3.5.0: {} 1499 + 1500 + file-uri-to-path@1.0.0: {} 1501 + 1502 + fs-constants@1.0.0: {} 1503 + 1504 + fsevents@2.3.3: 1505 + optional: true 1506 + 1507 + get-tsconfig@4.10.1: 1508 + dependencies: 1509 + resolve-pkg-maps: 1.0.0 1510 + 1511 + github-from-package@0.0.0: {} 1512 + 1513 + graphemer@1.4.0: {} 1514 + 1515 + hono@4.9.6: {} 1516 + 1517 + ieee754@1.2.1: {} 1518 + 1519 + inherits@2.0.4: {} 1520 + 1521 + ini@1.3.8: {} 1522 + 1523 + ipaddr.js@2.2.0: {} 1524 + 1525 + iso-datestring-validator@2.2.2: {} 1526 + 1527 + jose@5.10.0: {} 1528 + 1529 + lru-cache@10.4.3: {} 1530 + 1531 + mimic-response@3.1.0: {} 1532 + 1533 + minimist@1.2.8: {} 1534 + 1535 + mkdirp-classic@0.5.3: {} 1536 + 1537 + ms@2.1.3: {} 1538 + 1539 + multiformats@9.9.0: {} 1540 + 1541 + napi-build-utils@2.0.0: {} 1542 + 1543 + node-abi@3.77.0: 1544 + dependencies: 1545 + semver: 7.7.2 1546 + 1547 + node-gyp-build-optional-packages@5.1.1: 1548 + dependencies: 1549 + detect-libc: 2.0.4 1550 + optional: true 1551 + 1552 + on-exit-leak-free@2.1.2: {} 1553 + 1554 + once@1.4.0: 1555 + dependencies: 1556 + wrappy: 1.0.2 1557 + 1558 + partysocket@1.1.5: 1559 + dependencies: 1560 + event-target-polyfill: 0.0.4 1561 + 1562 + picocolors@1.1.1: {} 1563 + 1564 + pino-abstract-transport@1.2.0: 1565 + dependencies: 1566 + readable-stream: 4.7.0 1567 + split2: 4.2.0 1568 + 1569 + pino-std-serializers@6.2.2: {} 1570 + 1571 + pino@8.21.0: 1572 + dependencies: 1573 + atomic-sleep: 1.0.0 1574 + fast-redact: 3.5.0 1575 + on-exit-leak-free: 2.1.2 1576 + pino-abstract-transport: 1.2.0 1577 + pino-std-serializers: 6.2.2 1578 + process-warning: 3.0.0 1579 + quick-format-unescaped: 4.0.4 1580 + real-require: 0.2.0 1581 + safe-stable-stringify: 2.5.0 1582 + sonic-boom: 3.8.1 1583 + thread-stream: 2.7.0 1584 + 1585 + prebuild-install@7.1.3: 1586 + dependencies: 1587 + detect-libc: 2.0.4 1588 + expand-template: 2.0.3 1589 + github-from-package: 0.0.0 1590 + minimist: 1.2.8 1591 + mkdirp-classic: 0.5.3 1592 + napi-build-utils: 2.0.0 1593 + node-abi: 3.77.0 1594 + pump: 3.0.3 1595 + rc: 1.2.8 1596 + simple-get: 4.0.1 1597 + tar-fs: 2.1.3 1598 + tunnel-agent: 0.6.0 1599 + 1600 + prettier@3.6.2: {} 1601 + 1602 + process-warning@3.0.0: {} 1603 + 1604 + process@0.11.10: {} 1605 + 1606 + pump@3.0.3: 1607 + dependencies: 1608 + end-of-stream: 1.4.5 1609 + once: 1.4.0 1610 + 1611 + quick-format-unescaped@4.0.4: {} 1612 + 1613 + rc@1.2.8: 1614 + dependencies: 1615 + deep-extend: 0.6.0 1616 + ini: 1.3.8 1617 + minimist: 1.2.8 1618 + strip-json-comments: 2.0.1 1619 + 1620 + readable-stream@3.6.2: 1621 + dependencies: 1622 + inherits: 2.0.4 1623 + string_decoder: 1.3.0 1624 + util-deprecate: 1.0.2 1625 + 1626 + readable-stream@4.7.0: 1627 + dependencies: 1628 + abort-controller: 3.0.0 1629 + buffer: 6.0.3 1630 + events: 3.3.0 1631 + process: 0.11.10 1632 + string_decoder: 1.3.0 1633 + 1634 + real-require@0.2.0: {} 1635 + 1636 + resolve-pkg-maps@1.0.0: {} 1637 + 1638 + safe-buffer@5.2.1: {} 1639 + 1640 + safe-stable-stringify@2.5.0: {} 1641 + 1642 + semver@7.7.2: {} 1643 + 1644 + simple-concat@1.0.1: {} 1645 + 1646 + simple-get@4.0.1: 1647 + dependencies: 1648 + decompress-response: 6.0.0 1649 + once: 1.4.0 1650 + simple-concat: 1.0.1 1651 + 1652 + sonic-boom@3.8.1: 1653 + dependencies: 1654 + atomic-sleep: 1.0.0 1655 + 1656 + source-map-support@0.5.21: 1657 + dependencies: 1658 + buffer-from: 1.1.2 1659 + source-map: 0.6.1 1660 + 1661 + source-map@0.6.1: {} 1662 + 1663 + split2@4.2.0: {} 1664 + 1665 + string_decoder@1.3.0: 1666 + dependencies: 1667 + safe-buffer: 5.2.1 1668 + 1669 + strip-json-comments@2.0.1: {} 1670 + 1671 + tar-fs@2.1.3: 1672 + dependencies: 1673 + chownr: 1.1.4 1674 + mkdirp-classic: 0.5.3 1675 + pump: 3.0.3 1676 + tar-stream: 2.2.0 1677 + 1678 + tar-stream@2.2.0: 1679 + dependencies: 1680 + bl: 4.1.0 1681 + end-of-stream: 1.4.5 1682 + fs-constants: 1.0.0 1683 + inherits: 2.0.4 1684 + readable-stream: 3.6.2 1685 + 1686 + thread-stream@2.7.0: 1687 + dependencies: 1688 + real-require: 0.2.0 1689 + 1690 + tiny-emitter@2.1.0: {} 1691 + 1692 + tlds@1.260.0: {} 1693 + 1694 + tsx@4.20.5: 1695 + dependencies: 1696 + esbuild: 0.25.9 1697 + get-tsconfig: 4.10.1 1698 + optionalDependencies: 1699 + fsevents: 2.3.3 1700 + 1701 + tunnel-agent@0.6.0: 1702 + dependencies: 1703 + safe-buffer: 5.2.1 1704 + 1705 + typescript@5.9.2: {} 1706 + 1707 + uint8arrays@3.0.0: 1708 + dependencies: 1709 + multiformats: 9.9.0 1710 + 1711 + undici-types@7.10.0: {} 1712 + 1713 + undici@6.21.3: {} 1714 + 1715 + util-deprecate@1.0.2: {} 1716 + 1717 + wrappy@1.0.2: {} 1718 + 1719 + zod@3.25.76: {}
+3
pnpm-workspace.yaml
··· 1 + onlyBuiltDependencies: 2 + - better-sqlite3 3 + - esbuild
+29
src/atproto/client.ts
··· 1 + import { NodeOAuthClient } from "@atproto/oauth-client-node"; 2 + import { StateStore, SessionStore } from "./storage"; 3 + import { db } from "../drizzle/db"; 4 + 5 + const IS_DEV = process.env.NODE_ENV === "development"; 6 + const PUBLIC_URL = "https://fooodz.app"; 7 + const LOCAL_URL = "http://[::1]:3000"; 8 + const URL = IS_DEV ? LOCAL_URL : PUBLIC_URL; 9 + 10 + export const client = new NodeOAuthClient({ 11 + clientMetadata: { 12 + client_name: "fooodz", 13 + client_id: !IS_DEV 14 + ? `${PUBLIC_URL}/client-metadata.json` 15 + : `http://localhost?redirect_uri=${encodeURIComponent( 16 + `${URL}/oauth/callback`, 17 + )}&scope=${encodeURIComponent("atproto email profile account:email repo:app.fooodz.review")}`, 18 + client_uri: URL, 19 + redirect_uris: [`${URL}/oauth/callback`], 20 + scope: "atproto email profile account:email repo:app.fooodz.review", 21 + grant_types: ["authorization_code", "refresh_token"], 22 + response_types: ["code"], 23 + application_type: "web", 24 + token_endpoint_auth_method: "none", 25 + dpop_bound_access_tokens: true, 26 + }, 27 + stateStore: new StateStore(db), 28 + sessionStore: new SessionStore(db), 29 + });
+71
src/atproto/storage.ts
··· 1 + import type { 2 + NodeSavedSession, 3 + NodeSavedSessionStore, 4 + NodeSavedState, 5 + NodeSavedStateStore, 6 + } from "@atproto/oauth-client-node"; 7 + import type { DrizzleClient } from "../drizzle/db"; 8 + import { eq } from "drizzle-orm"; 9 + import { sessions, states } from "../drizzle/schema"; 10 + 11 + export class StateStore implements NodeSavedStateStore { 12 + constructor(private db: DrizzleClient) {} 13 + async get(key: string): Promise<NodeSavedState | undefined> { 14 + const result = await this.db.query.states.findFirst({ 15 + where: eq(states.key, key), 16 + }); 17 + 18 + if (!result?.state) return; 19 + return JSON.parse(result.state); 20 + } 21 + async set(key: string, value: NodeSavedState) { 22 + const state = JSON.stringify(value); 23 + 24 + await this.db 25 + .insert(states) 26 + .values({ 27 + key, 28 + state, 29 + }) 30 + .onConflictDoUpdate({ 31 + target: states.key, 32 + set: { 33 + state, 34 + }, 35 + }); 36 + } 37 + async del(key: string) { 38 + await this.db.delete(states).where(eq(states.key, key)); 39 + } 40 + } 41 + 42 + export class SessionStore implements NodeSavedSessionStore { 43 + constructor(private db: DrizzleClient) {} 44 + async get(key: string): Promise<NodeSavedSession | undefined> { 45 + const result = await this.db.query.sessions.findFirst({ 46 + where: eq(states.key, key), 47 + }); 48 + 49 + if (!result?.session) return; 50 + return JSON.parse(result.session) as NodeSavedSession; 51 + } 52 + async set(key: string, value: NodeSavedSession) { 53 + const session = JSON.stringify(value); 54 + 55 + await this.db 56 + .insert(sessions) 57 + .values({ 58 + key, 59 + session, 60 + }) 61 + .onConflictDoUpdate({ 62 + target: sessions.key, 63 + set: { 64 + session, 65 + }, 66 + }); 67 + } 68 + async del(key: string) { 69 + await this.db.delete(sessions).where(eq(states.key, key)); 70 + } 71 + }
+11
src/components/index.tsx
··· 1 + import type { FC } from "hono/jsx"; 2 + 3 + export const Layout: FC = (props) => { 4 + return ( 5 + <html lang="en"> 6 + <body> 7 + <main>{props.children}</main> 8 + </body> 9 + </html> 10 + ); 11 + };
+14
src/drizzle/db.ts
··· 1 + import { 2 + drizzle, 3 + type BetterSQLite3Database, 4 + } from "drizzle-orm/better-sqlite3"; 5 + import Database from "better-sqlite3"; 6 + import * as schema from "./schema"; 7 + 8 + const sqlite = new Database("foodz.db"); 9 + export const db: BetterSQLite3Database<typeof schema> = drizzle({ 10 + client: sqlite, 11 + schema, 12 + }); 13 + 14 + export type DrizzleClient = BetterSQLite3Database<typeof schema>;
+44
src/drizzle/schema.ts
··· 1 + import { sqliteTable, integer, text } from "drizzle-orm/sqlite-core"; 2 + import { relations, sql } from "drizzle-orm"; 3 + 4 + const timestamp = { 5 + createdAt: text("timestamp").notNull().default(sql`(current_timestamp)`), 6 + updatedAt: text("timestamp").notNull().default(sql`(current_timestamp)`), 7 + }; 8 + 9 + export const users = sqliteTable("users", { 10 + id: integer().primaryKey({ autoIncrement: true }), 11 + did: text().notNull(), 12 + ...timestamp, 13 + }); 14 + 15 + export const usersRelations = relations(users, ({ many }) => ({ 16 + reviews: many(reviews), 17 + })); 18 + 19 + export const reviews = sqliteTable("reviews", { 20 + rkey: text().notNull(), 21 + place: text().notNull(), 22 + // maybe the actual text review should be optional, some people just leave a rating 23 + review: text().notNull(), 24 + rating: integer().notNull(), 25 + authorDid: text().notNull(), 26 + ...timestamp, 27 + }); 28 + 29 + export const reviewsRelations = relations(reviews, ({ one }) => ({ 30 + author: one(users, { 31 + fields: [reviews.authorDid], 32 + references: [users.did], 33 + }), 34 + })); 35 + 36 + export const sessions = sqliteTable("sessions", { 37 + key: text().notNull().unique(), 38 + session: text(), 39 + }); 40 + 41 + export const states = sqliteTable("states", { 42 + key: text().notNull().unique(), 43 + state: text(), 44 + });
+196
src/index.tsx
··· 1 + import { OAuthResolverError } from "@atproto/oauth-client-node"; 2 + import { serve } from "@hono/node-server"; 3 + import { Hono } from "hono"; 4 + import { generateSignedCookie, getSignedCookie } from "hono/cookie"; 5 + import { client } from "./atproto/client"; 6 + import { resolveMiniDoc } from "./utils"; 7 + import "dotenv/config"; 8 + import { jetstream } from "./ingester"; 9 + import { Agent } from "@atproto/api"; 10 + import { TID } from "@atproto/common"; 11 + import { AppFooodzReview } from "./lexicons"; 12 + import { is } from "@atcute/lexicons"; 13 + import { Layout } from "./components"; 14 + import { db } from "./drizzle/db"; 15 + import { users } from "./drizzle/schema"; 16 + import { eq } from "drizzle-orm"; 17 + 18 + const app = new Hono(); 19 + 20 + app.get("/client-metadata.json", (c) => { 21 + return c.json(client.clientMetadata); 22 + }); 23 + 24 + app.get("/oauth/callback", async (c) => { 25 + const params = new URLSearchParams(c.req.url.split("?")[1]); 26 + 27 + try { 28 + const { session } = await client.callback(params); 29 + 30 + // check if user is already added to db 31 + const user = await db.query.users.findFirst({ 32 + where: eq(users.did, session.did), 33 + }); 34 + 35 + if (!user) { 36 + console.log("user not found in db, inserting"); 37 + await db.insert(users).values({ 38 + did: session.did, 39 + }); 40 + } 41 + 42 + const cookie = await generateSignedCookie( 43 + "__foooodz_session", 44 + session.did, 45 + process.env.COOKIE_SECRET as string, 46 + { 47 + path: "/", 48 + httpOnly: true, 49 + sameSite: "lax", 50 + maxAge: 60 * 60 * 24 * 7, 51 + secure: process.env.NODE_ENV === "production", 52 + }, 53 + ); 54 + return new Response(null, { 55 + status: 302, 56 + headers: { 57 + "Set-Cookie": cookie, 58 + Location: "/", 59 + }, 60 + }); 61 + } catch (error) { 62 + if (error instanceof Error) { 63 + throw error; 64 + } 65 + } 66 + }); 67 + 68 + app.post("/login", async (c) => { 69 + try { 70 + const formData = await c.req.formData(); 71 + const handle = formData.get("handle"); 72 + if (!handle || typeof handle !== "string") { 73 + return c.json( 74 + { 75 + ok: false, 76 + message: "Invalid handle", 77 + }, 78 + 400, 79 + ); 80 + } 81 + 82 + const { did } = await resolveMiniDoc(handle); 83 + 84 + const ac = new AbortController(); 85 + const redirectUrl = await client.authorize(did, { 86 + signal: ac.signal, 87 + }); 88 + return c.redirect(redirectUrl.toString()); 89 + } catch (error) { 90 + if (error instanceof OAuthResolverError) { 91 + return c.json({ ok: false, message: error.message }, 500); 92 + } 93 + console.log(error); 94 + return c.json({ ok: false, message: "something went wrong" }, 500); 95 + } 96 + }); 97 + 98 + app.get("/", async (c) => { 99 + return c.html( 100 + <Layout> 101 + <form method="post" action="/login"> 102 + <label htmlFor="handle">Handle</label> 103 + <input type="text" name="handle" id="handle" /> 104 + <button type="submit">Login</button> 105 + </form> 106 + </Layout>, 107 + ); 108 + }); 109 + 110 + app.get("/review", async (c) => { 111 + const reviews = await db.query.reviews.findMany({ 112 + limit: 10, 113 + }); 114 + return c.html( 115 + <Layout> 116 + <form method="post" action="/review"> 117 + <label htmlFor="place">place</label> 118 + <input type="text" name="place" id="place" maxlength={200} required /> 119 + <label htmlFor="review">review</label> 120 + <textarea name="review" id="review" maxlength={3000} required /> 121 + <label htmlFor="rating">rating</label> 122 + <select name="rating" id="rating" required> 123 + {Array.from({ length: 5 }, (_, index) => ( 124 + <option key={index} value={index + 1}> 125 + {index + 1} 126 + </option> 127 + ))} 128 + </select> 129 + <button type="submit">submit review</button> 130 + </form> 131 + <ul> 132 + {reviews.map((review) => ( 133 + <li key={review.rkey}> 134 + <article> 135 + <h2>{review.place}</h2> 136 + <p>{review.review}</p> 137 + <span>{review.rating}</span> 138 + <time datetime={review.createdAt}>{review.createdAt}</time> 139 + </article> 140 + </li> 141 + ))} 142 + </ul> 143 + </Layout>, 144 + ); 145 + }); 146 + 147 + app.post("/review", async (c) => { 148 + const cookie = await getSignedCookie(c, process.env.COOKIE_SECRET as string); 149 + if (cookie.__foooodz_session) { 150 + try { 151 + const oauthSession = await client.restore(cookie.__foooodz_session); 152 + const agent = new Agent(oauthSession); 153 + const formData = await c.req.formData(); 154 + const place = formData.get("place") as string; 155 + const review = formData.get("review") as string; 156 + const rating = formData.get("rating") as string; 157 + 158 + const rkey = TID.nextStr(); 159 + 160 + const record: AppFooodzReview.Main = { 161 + $type: "app.fooodz.review", 162 + place, 163 + rating: +rating, 164 + review, 165 + createdAt: new Date().toISOString(), 166 + }; 167 + 168 + if (!is(AppFooodzReview.mainSchema, record)) { 169 + return c.json({ ok: false, message: "invalid review record" }, 400); 170 + } 171 + 172 + await agent.com.atproto.repo.putRecord({ 173 + repo: agent.assertDid, 174 + rkey, 175 + record, 176 + collection: "app.fooodz.review", 177 + validate: false, 178 + }); 179 + 180 + return c.redirect("/review"); 181 + } catch (error) { 182 + return c.json({ ok: false, message: "failed to write record" }, 500); 183 + } 184 + } 185 + }); 186 + 187 + serve( 188 + { 189 + fetch: app.fetch, 190 + port: 3000, 191 + }, 192 + (info) => { 193 + console.log(`Server is running @ http://localhost:${info.port}`); 194 + jetstream.start(); 195 + }, 196 + );
+63
src/ingester.ts
··· 1 + import { is } from "@atcute/lexicons"; 2 + import { Jetstream } from "@skyware/jetstream"; 3 + import { AppFooodzReview } from "./lexicons"; 4 + import { db } from "./drizzle/db"; 5 + import { reviews } from "./drizzle/schema"; 6 + import { eq } from "drizzle-orm"; 7 + 8 + const jetstream = new Jetstream({ 9 + wantedCollections: ["app.fooodz.review"], 10 + }); 11 + 12 + jetstream.onCreate("app.fooodz.review", async (event) => { 13 + console.info(`new review ${event.commit.rkey}`); 14 + if (is(AppFooodzReview.mainSchema, event.commit.record)) { 15 + const { place, rating, review, createdAt } = event.commit.record; 16 + 17 + // should store the did and rkey as well 18 + await db.insert(reviews).values({ 19 + rkey: event.commit.rkey, 20 + authorDid: event.did, 21 + place, 22 + rating, 23 + review, 24 + createdAt, 25 + }); 26 + } 27 + }); 28 + 29 + jetstream.onUpdate("app.fooodz.review", async (event) => { 30 + if (is(AppFooodzReview.mainSchema, event.commit.record)) { 31 + const { place, rating, review, createdAt } = event.commit.record; 32 + 33 + await db 34 + .insert(reviews) 35 + .values({ 36 + rkey: event.commit.rkey, 37 + authorDid: event.did, 38 + place, 39 + rating, 40 + review, 41 + createdAt, 42 + }) 43 + .onConflictDoUpdate({ 44 + target: reviews.rkey, 45 + set: { 46 + place, 47 + rating, 48 + review, 49 + }, 50 + }); 51 + } 52 + }); 53 + 54 + jetstream.onDelete("app.fooodz.review", async (event) => { 55 + await db.delete(reviews).where(eq(reviews.rkey, event.commit.rkey)); 56 + console.log("deleted record", event.commit.rkey); 57 + }); 58 + 59 + jetstream.on("open", () => { 60 + console.log("jetstream ingester started"); 61 + }); 62 + 63 + export { jetstream };
+1
src/lexicons/index.ts
··· 1 + export * as AppFooodzReview from "./types/app/fooodz/review.js";
+36
src/lexicons/types/app/fooodz/review.ts
··· 1 + import type {} from "@atcute/lexicons"; 2 + import * as v from "@atcute/lexicons/validations"; 3 + import type {} from "@atcute/lexicons/ambient"; 4 + 5 + const _mainSchema = /*#__PURE__*/ v.record( 6 + /*#__PURE__*/ v.string(), 7 + /*#__PURE__*/ v.object({ 8 + $type: /*#__PURE__*/ v.literal("app.fooodz.review"), 9 + createdAt: /*#__PURE__*/ v.datetimeString(), 10 + place: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 11 + /*#__PURE__*/ v.stringLength(0, 200), 12 + /*#__PURE__*/ v.stringGraphemes(0, 20), 13 + ]), 14 + rating: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ 15 + /*#__PURE__*/ v.integerRange(1, 5), 16 + ]), 17 + review: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 18 + /*#__PURE__*/ v.stringLength(0, 3000), 19 + /*#__PURE__*/ v.stringGraphemes(0, 300), 20 + ]), 21 + }), 22 + ); 23 + 24 + type main$schematype = typeof _mainSchema; 25 + 26 + export interface mainSchema extends main$schematype {} 27 + 28 + export const mainSchema = _mainSchema as mainSchema; 29 + 30 + export interface Main extends v.InferInput<typeof mainSchema> {} 31 + 32 + declare module "@atcute/lexicons/ambient" { 33 + interface Records { 34 + "app.fooodz.review": mainSchema; 35 + } 36 + }
+11
src/utils.ts
··· 1 + export async function resolveMiniDoc(handle: string) { 2 + const response = await fetch( 3 + `https://slingshot.microcosm.blue/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=${handle}`, 4 + ); 5 + const data = (await response.json()) as { pds: string; did: string }; 6 + 7 + return { 8 + pds: data.pds, 9 + did: data.did, 10 + }; 11 + }
+10
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "moduleResolution": "bundler", 4 + "module": "esnext", 5 + "esModuleInterop": true, 6 + "strict": true, 7 + "jsx": "react-jsx", 8 + "jsxImportSource": "hono/jsx" 9 + } 10 + }