A simple BlueSky profile labeler that can be ran on Cloudflare Workers github.com/SocksTheWolf/SimpleBSkyLabeler
cf bsky profile label bluesky cloudflare workers
1
fork

Configure Feed

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

add rate limit ability

+880 -118
+108 -108
package-lock.json
··· 18 18 "@types/node": "^25.5.0", 19 19 "run-p": "^0.0.0", 20 20 "typescript": "^5.9.3", 21 - "wrangler": "^4.73.0" 21 + "wrangler": "^4.77.0" 22 22 } 23 23 }, 24 24 "node_modules/@atcute/cbor": { ··· 48 48 "license": "MIT" 49 49 }, 50 50 "node_modules/@atcute/multibase": { 51 - "version": "1.1.8", 52 - "resolved": "https://registry.npmjs.org/@atcute/multibase/-/multibase-1.1.8.tgz", 53 - "integrity": "sha512-pJgtImMZKCjqwRbu+2GzB+4xQjKBXDwdZOzeqe0u97zYKRGftpGYGvYv3+pMe2xXe+msDyu7Nv8iJp+U14otTA==", 51 + "version": "1.2.0", 52 + "resolved": "https://registry.npmjs.org/@atcute/multibase/-/multibase-1.2.0.tgz", 53 + "integrity": "sha512-ZK2GRra+qIYq9nNuQB52m2ul0hOmCQEtPobGfTSUxm7pF0OGEkWGkWHugFhNEDVzHzTwPxHp6VGotdZFue4lYQ==", 54 54 "license": "0BSD", 55 55 "dependencies": { 56 56 "@atcute/uint8array": "^1.1.1" ··· 79 79 } 80 80 }, 81 81 "node_modules/@cloudflare/unenv-preset": { 82 - "version": "2.15.0", 83 - "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.15.0.tgz", 84 - "integrity": "sha512-EGYmJaGZKWl+X8tXxcnx4v2bOZSjQeNI5dWFeXivgX9+YCT69AkzHHwlNbVpqtEUTbew8eQurpyOpeN8fg00nw==", 82 + "version": "2.16.0", 83 + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.0.tgz", 84 + "integrity": "sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg==", 85 85 "dev": true, 86 86 "license": "MIT OR Apache-2.0", 87 87 "peerDependencies": { ··· 95 95 } 96 96 }, 97 97 "node_modules/@cloudflare/workerd-darwin-64": { 98 - "version": "1.20260312.1", 99 - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260312.1.tgz", 100 - "integrity": "sha512-HUAtDWaqUduS6yasV6+NgsK7qBpP1qGU49ow/Wb117IHjYp+PZPUGReDYocpB4GOMRoQlvdd4L487iFxzdARpw==", 98 + "version": "1.20260317.1", 99 + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260317.1.tgz", 100 + "integrity": "sha512-8hjh3sPMwY8M/zedq3/sXoA2Q4BedlGufn3KOOleIG+5a4ReQKLlUah140D7J6zlKmYZAFMJ4tWC7hCuI/s79g==", 101 101 "cpu": [ 102 102 "x64" 103 103 ], ··· 112 112 } 113 113 }, 114 114 "node_modules/@cloudflare/workerd-darwin-arm64": { 115 - "version": "1.20260312.1", 116 - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260312.1.tgz", 117 - "integrity": "sha512-DOn7TPTHSxJYfi4m4NYga/j32wOTqvJf/pY4Txz5SDKWIZHSTXFyGz2K4B+thoPWLop/KZxGoyTv7db0mk/qyw==", 115 + "version": "1.20260317.1", 116 + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260317.1.tgz", 117 + "integrity": "sha512-M/MnNyvO5HMgoIdr3QHjdCj2T1ki9gt0vIUnxYxBu9ISXS/jgtMl6chUVPJ7zHYBn9MyYr8ByeN6frjYxj0MGg==", 118 118 "cpu": [ 119 119 "arm64" 120 120 ], ··· 129 129 } 130 130 }, 131 131 "node_modules/@cloudflare/workerd-linux-64": { 132 - "version": "1.20260312.1", 133 - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260312.1.tgz", 134 - "integrity": "sha512-TdkIh3WzPXYHuvz7phAtFEEvAxvFd30tHrm4gsgpw0R0F5b8PtoM3hfL2uY7EcBBWVYUBtkY2ahDYFfufnXw/g==", 132 + "version": "1.20260317.1", 133 + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260317.1.tgz", 134 + "integrity": "sha512-1ltuEjkRcS3fsVF7CxsKlWiRmzq2ZqMfqDN0qUOgbUwkpXsLVJsXmoblaLf5OP00ELlcgF0QsN0p2xPEua4Uug==", 135 135 "cpu": [ 136 136 "x64" 137 137 ], ··· 146 146 } 147 147 }, 148 148 "node_modules/@cloudflare/workerd-linux-arm64": { 149 - "version": "1.20260312.1", 150 - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260312.1.tgz", 151 - "integrity": "sha512-kNauZhL569Iy94t844OMwa1zP6zKFiL3xiJ4tGLS+TFTEfZ3pZsRH6lWWOtkXkjTyCmBEOog0HSEKjIV4oAffw==", 149 + "version": "1.20260317.1", 150 + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260317.1.tgz", 151 + "integrity": "sha512-3QrNnPF1xlaNwkHpasvRvAMidOvQs2NhXQmALJrEfpIJ/IDL2la8g499yXp3eqhG3hVMCB07XVY149GTs42Xtw==", 152 152 "cpu": [ 153 153 "arm64" 154 154 ], ··· 163 163 } 164 164 }, 165 165 "node_modules/@cloudflare/workerd-windows-64": { 166 - "version": "1.20260312.1", 167 - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260312.1.tgz", 168 - "integrity": "sha512-5dBrlSK+nMsZy5bYQpj8t9iiQNvCRlkm9GGvswJa9vVU/1BNO4BhJMlqOLWT24EmFyApZ+kaBiPJMV8847NDTg==", 166 + "version": "1.20260317.1", 167 + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260317.1.tgz", 168 + "integrity": "sha512-MfZTz+7LfuIpMGTa3RLXHX8Z/pnycZLItn94WRdHr8LPVet+C5/1Nzei399w/jr3+kzT4pDKk26JF/tlI5elpQ==", 169 169 "cpu": [ 170 170 "x64" 171 171 ], ··· 193 193 } 194 194 }, 195 195 "node_modules/@emnapi/runtime": { 196 - "version": "1.9.0", 197 - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", 198 - "integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==", 196 + "version": "1.9.1", 197 + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", 198 + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", 199 199 "dev": true, 200 200 "license": "MIT", 201 201 "optional": true, ··· 1173 1173 "kleur": "^4.1.5" 1174 1174 } 1175 1175 }, 1176 - "node_modules/@poppinss/colors/node_modules/kleur": { 1177 - "version": "4.1.5", 1178 - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", 1179 - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", 1180 - "dev": true, 1181 - "license": "MIT", 1182 - "engines": { 1183 - "node": ">=6" 1184 - } 1185 - }, 1186 1176 "node_modules/@poppinss/dumper": { 1187 1177 "version": "0.6.5", 1188 1178 "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", ··· 1216 1206 } 1217 1207 }, 1218 1208 "node_modules/@speed-highlight/core": { 1219 - "version": "1.2.14", 1220 - "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.14.tgz", 1221 - "integrity": "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==", 1209 + "version": "1.2.15", 1210 + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz", 1211 + "integrity": "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==", 1222 1212 "dev": true, 1223 1213 "license": "CC0-1.0" 1224 1214 }, ··· 1239 1229 "dev": true, 1240 1230 "license": "MIT" 1241 1231 }, 1232 + "node_modules/cookie": { 1233 + "version": "1.1.1", 1234 + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", 1235 + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", 1236 + "dev": true, 1237 + "license": "MIT", 1238 + "engines": { 1239 + "node": ">=18" 1240 + }, 1241 + "funding": { 1242 + "type": "opencollective", 1243 + "url": "https://opencollective.com/express" 1244 + } 1245 + }, 1246 + "node_modules/detect-libc": { 1247 + "version": "2.1.2", 1248 + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", 1249 + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", 1250 + "dev": true, 1251 + "license": "Apache-2.0", 1252 + "engines": { 1253 + "node": ">=8" 1254 + } 1255 + }, 1242 1256 "node_modules/error-stack-parser-es": { 1243 1257 "version": "1.0.5", 1244 1258 "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", ··· 1318 1332 "integrity": "sha512-tYzMAz72bJXRBFKhWnEZrVdBbBqV4/vwNGv6O96LqZv+BjtmUGUBtBkFr+vqGlgHOVIcRalUNdJlumvXSAbuaQ==", 1319 1333 "license": "MIT" 1320 1334 }, 1335 + "node_modules/kleur": { 1336 + "version": "4.1.5", 1337 + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", 1338 + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", 1339 + "dev": true, 1340 + "license": "MIT", 1341 + "engines": { 1342 + "node": ">=6" 1343 + } 1344 + }, 1321 1345 "node_modules/miniflare": { 1322 - "version": "4.20260312.0", 1323 - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260312.0.tgz", 1324 - "integrity": "sha512-pieP2rfXynPT6VRINYaiHe/tfMJ4c5OIhqRlIdLF6iZ9g5xgpEmvimvIgMpgAdDJuFlrLcwDUi8MfAo2R6dt/w==", 1346 + "version": "4.20260317.2", 1347 + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260317.2.tgz", 1348 + "integrity": "sha512-qNL+yWAFMX6fr0pWU6Lx1vNpPobpnDSF1V8eunIckWvoIQl8y1oBjL2RJFEGY3un+l3f9gwW9dirDPP26usYJQ==", 1325 1349 "dev": true, 1326 1350 "license": "MIT", 1327 1351 "dependencies": { 1328 1352 "@cspotcode/source-map-support": "0.8.1", 1329 1353 "sharp": "^0.34.5", 1330 - "undici": "7.18.2", 1331 - "workerd": "1.20260312.1", 1354 + "undici": "7.24.4", 1355 + "workerd": "1.20260317.1", 1332 1356 "ws": "8.18.0", 1333 1357 "youch": "4.1.0-beta.10" 1334 1358 }, ··· 1337 1361 }, 1338 1362 "engines": { 1339 1363 "node": ">=18.0.0" 1340 - } 1341 - }, 1342 - "node_modules/miniflare/node_modules/ws": { 1343 - "version": "8.18.0", 1344 - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", 1345 - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", 1346 - "dev": true, 1347 - "license": "MIT", 1348 - "engines": { 1349 - "node": ">=10.0.0" 1350 - }, 1351 - "peerDependencies": { 1352 - "bufferutil": "^4.0.1", 1353 - "utf-8-validate": ">=5.0.2" 1354 - }, 1355 - "peerDependenciesMeta": { 1356 - "bufferutil": { 1357 - "optional": true 1358 - }, 1359 - "utf-8-validate": { 1360 - "optional": true 1361 - } 1362 1364 } 1363 1365 }, 1364 1366 "node_modules/multiformats": { ··· 1446 1448 "@img/sharp-win32-x64": "0.34.5" 1447 1449 } 1448 1450 }, 1449 - "node_modules/sharp/node_modules/detect-libc": { 1450 - "version": "2.1.2", 1451 - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", 1452 - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", 1453 - "dev": true, 1454 - "license": "Apache-2.0", 1455 - "engines": { 1456 - "node": ">=8" 1457 - } 1458 - }, 1459 1451 "node_modules/supports-color": { 1460 1452 "version": "10.2.2", 1461 1453 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", ··· 1501 1493 } 1502 1494 }, 1503 1495 "node_modules/undici": { 1504 - "version": "7.24.0", 1505 - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.0.tgz", 1506 - "integrity": "sha512-jxytwMHhsbdpBXxLAcuu0fzlQeXCNnWdDyRHpvWsUl8vd98UwYdl9YTyn8/HcpcJPC3pwUveefsa3zTxyD/ERg==", 1496 + "version": "7.24.4", 1497 + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz", 1498 + "integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==", 1507 1499 "dev": true, 1508 1500 "license": "MIT", 1509 1501 "engines": { ··· 1528 1520 } 1529 1521 }, 1530 1522 "node_modules/workerd": { 1531 - "version": "1.20260312.1", 1532 - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260312.1.tgz", 1533 - "integrity": "sha512-nNpPkw9jaqo79B+iBCOiksx+N62xC+ETIfyzofUEdY3cSOHJg6oNnVSHm7vHevzVblfV76c8Gr0cXHEapYMBEg==", 1523 + "version": "1.20260317.1", 1524 + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260317.1.tgz", 1525 + "integrity": "sha512-ZuEq1OdrJBS+NV+L5HMYPCzVn49a2O60slQiiLpG44jqtlOo+S167fWC76kEXteXLLLydeuRrluRel7WdOUa4g==", 1534 1526 "dev": true, 1535 1527 "hasInstallScript": true, 1536 1528 "license": "Apache-2.0", ··· 1541 1533 "node": ">=16" 1542 1534 }, 1543 1535 "optionalDependencies": { 1544 - "@cloudflare/workerd-darwin-64": "1.20260312.1", 1545 - "@cloudflare/workerd-darwin-arm64": "1.20260312.1", 1546 - "@cloudflare/workerd-linux-64": "1.20260312.1", 1547 - "@cloudflare/workerd-linux-arm64": "1.20260312.1", 1548 - "@cloudflare/workerd-windows-64": "1.20260312.1" 1536 + "@cloudflare/workerd-darwin-64": "1.20260317.1", 1537 + "@cloudflare/workerd-darwin-arm64": "1.20260317.1", 1538 + "@cloudflare/workerd-linux-64": "1.20260317.1", 1539 + "@cloudflare/workerd-linux-arm64": "1.20260317.1", 1540 + "@cloudflare/workerd-windows-64": "1.20260317.1" 1549 1541 } 1550 1542 }, 1551 1543 "node_modules/wrangler": { 1552 - "version": "4.73.0", 1553 - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.73.0.tgz", 1554 - "integrity": "sha512-VJXsqKDFCp6OtFEHXITSOR5kh95JOknwPY8m7RyQuWJQguSybJy43m4vhoCSt42prutTef7eeuw7L4V4xiynGw==", 1544 + "version": "4.77.0", 1545 + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.77.0.tgz", 1546 + "integrity": "sha512-E2Gm69+K++BFd3QvoWjC290RPQj1vDOUotA++sNHmtKPb7EP6C8Qv+1D5Ii73tfZtyNgakpqHlh8lBBbVWTKAQ==", 1555 1547 "dev": true, 1556 1548 "license": "MIT OR Apache-2.0", 1557 1549 "dependencies": { 1558 1550 "@cloudflare/kv-asset-handler": "0.4.2", 1559 - "@cloudflare/unenv-preset": "2.15.0", 1551 + "@cloudflare/unenv-preset": "2.16.0", 1560 1552 "blake3-wasm": "2.1.5", 1561 1553 "esbuild": "0.27.3", 1562 - "miniflare": "4.20260312.0", 1554 + "miniflare": "4.20260317.2", 1563 1555 "path-to-regexp": "6.3.0", 1564 1556 "unenv": "2.0.0-rc.24", 1565 - "workerd": "1.20260312.1" 1557 + "workerd": "1.20260317.1" 1566 1558 }, 1567 1559 "bin": { 1568 1560 "wrangler": "bin/wrangler.js", 1569 1561 "wrangler2": "bin/wrangler.js" 1570 1562 }, 1571 1563 "engines": { 1572 - "node": ">=20.0.0" 1564 + "node": ">=20.3.0" 1573 1565 }, 1574 1566 "optionalDependencies": { 1575 1567 "fsevents": "~2.3.2" 1576 1568 }, 1577 1569 "peerDependencies": { 1578 - "@cloudflare/workers-types": "^4.20260312.1" 1570 + "@cloudflare/workers-types": "^4.20260317.1" 1579 1571 }, 1580 1572 "peerDependenciesMeta": { 1581 1573 "@cloudflare/workers-types": { ··· 1583 1575 } 1584 1576 } 1585 1577 }, 1578 + "node_modules/ws": { 1579 + "version": "8.18.0", 1580 + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", 1581 + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", 1582 + "dev": true, 1583 + "license": "MIT", 1584 + "engines": { 1585 + "node": ">=10.0.0" 1586 + }, 1587 + "peerDependencies": { 1588 + "bufferutil": "^4.0.1", 1589 + "utf-8-validate": ">=5.0.2" 1590 + }, 1591 + "peerDependenciesMeta": { 1592 + "bufferutil": { 1593 + "optional": true 1594 + }, 1595 + "utf-8-validate": { 1596 + "optional": true 1597 + } 1598 + } 1599 + }, 1586 1600 "node_modules/youch": { 1587 1601 "version": "4.1.0-beta.10", 1588 1602 "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", ··· 1606 1620 "dependencies": { 1607 1621 "@poppinss/exception": "^1.2.2", 1608 1622 "error-stack-parser-es": "^1.0.5" 1609 - } 1610 - }, 1611 - "node_modules/youch/node_modules/cookie": { 1612 - "version": "1.1.1", 1613 - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", 1614 - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", 1615 - "dev": true, 1616 - "license": "MIT", 1617 - "engines": { 1618 - "node": ">=18" 1619 - }, 1620 - "funding": { 1621 - "type": "opencollective", 1622 - "url": "https://opencollective.com/express" 1623 1623 } 1624 1624 } 1625 1625 }
+2 -7
package.json
··· 1 1 { 2 2 "name": "simplebskylabeler", 3 - "version": "1.0.0", 3 + "version": "1.2.0", 4 4 "private": true, 5 5 "scripts": { 6 6 "createdb": "wrangler d1 create bskylabels --binding DB --update-config", ··· 16 16 "@types/node": "^25.5.0", 17 17 "run-p": "^0.0.0", 18 18 "typescript": "^5.9.3", 19 - "wrangler": "^4.73.0" 19 + "wrangler": "^4.77.0" 20 20 }, 21 21 "dependencies": { 22 22 "@atcute/cbor": "^1.0.7", ··· 24 24 "just-has": "^2.3.0", 25 25 "just-template": "^2.2.0", 26 26 "uint8arrays": "^5.1.0" 27 - }, 28 - "overrides": { 29 - "miniflare": { 30 - "undici": "^7.24.0" 31 - } 32 27 } 33 28 }
+8 -1
src/index.ts
··· 128 128 } 129 129 } 130 130 return response; 131 - } else if (url.pathname === "/add-account" || url.pathname === "/add-self") { 131 + } else if (url.pathname === "/add-account") { 132 + if (env.RATELIMIT === "true") { 133 + const ipAddress = request.headers.get("cf-connecting-ip") || ""; 134 + const { success } = await env.BSKY_LABEL_LIMITER.limit({ key: ipAddress }); 135 + if (!success) { 136 + return new Response("<b>ERROR</b>: You are adding too quickly, please slow down", {status: 429}); 137 + } 138 + } 132 139 // drop non post requests 133 140 if (request.method !== "POST") { 134 141 return new Response("<b>ERROR</b>: You cannot submit data this way", {status: 405});
+751 -2
worker-configuration.d.ts
··· 1 1 /* eslint-disable */ 2 - // Generated by Wrangler by running `wrangler types` (hash: a3a025b6baf0beefc4d917e42f0f0b05) 3 - // Runtime types generated with workerd@1.20260312.1 2024-12-18 nodejs_compat 2 + // Generated by Wrangler by running `wrangler types` (hash: 4fbff60ff6193980e25186a76790a338) 3 + // Runtime types generated with workerd@1.20260317.1 2024-12-18 nodejs_compat 4 4 declare namespace Cloudflare { 5 5 interface GlobalProps { 6 6 mainModule: typeof import("./src/index"); 7 7 } 8 8 interface Env { 9 9 DB: D1Database; 10 + BSKY_LABEL_LIMITER: RateLimit; 10 11 ASSETS: Fetcher; 11 12 COUNT_CACHE_HOUR: "4"; 13 + RATELIMIT: "true"; 12 14 SITE_TITLE: "Simple BSky Labeler"; 13 15 SITE_DESCRIPTION: "Allow people to obtain a bsky label you provide"; 14 16 SITE_SHORTNAME: "SBL"; ··· 3293 3295 } 3294 3296 interface WorkerLoader { 3295 3297 get(name: string | null, getCode: () => WorkerLoaderWorkerCode | Promise<WorkerLoaderWorkerCode>): WorkerStub; 3298 + load(code: WorkerLoaderWorkerCode): WorkerStub; 3296 3299 } 3297 3300 interface WorkerLoaderModule { 3298 3301 js?: string; ··· 10686 10689 declare module "cloudflare:sockets" { 10687 10690 function _connect(address: string | SocketAddress, options?: SocketOptions): Socket; 10688 10691 export { _connect as connect }; 10692 + } 10693 + /** 10694 + * Binding entrypoint for Cloudflare Stream. 10695 + * 10696 + * Usage: 10697 + * - Binding-level operations: 10698 + * `await env.STREAM.videos.upload` 10699 + * `await env.STREAM.videos.createDirectUpload` 10700 + * `await env.STREAM.videos.*` 10701 + * `await env.STREAM.watermarks.*` 10702 + * - Per-video operations: 10703 + * `await env.STREAM.video(id).downloads.*` 10704 + * `await env.STREAM.video(id).captions.*` 10705 + * 10706 + * Example usage: 10707 + * ```ts 10708 + * await env.STREAM.video(id).downloads.generate(); 10709 + * 10710 + * const video = env.STREAM.video(id) 10711 + * const captions = video.captions.list(); 10712 + * const videoDetails = video.details() 10713 + * ``` 10714 + */ 10715 + interface StreamBinding { 10716 + /** 10717 + * Returns a handle scoped to a single video for per-video operations. 10718 + * @param id The unique identifier for the video. 10719 + * @returns A handle for per-video operations. 10720 + */ 10721 + video(id: string): StreamVideoHandle; 10722 + /** 10723 + * Uploads a new video from a File. 10724 + * @param file The video file to upload. 10725 + * @returns The uploaded video details. 10726 + * @throws {BadRequestError} if the upload parameter is invalid 10727 + * @throws {QuotaReachedError} if the account storage capacity is exceeded 10728 + * @throws {MaxFileSizeError} if the file size is too large 10729 + * @throws {RateLimitedError} if the server received too many requests 10730 + * @throws {InternalError} if an unexpected error occurs 10731 + */ 10732 + upload(file: File): Promise<StreamVideo>; 10733 + /** 10734 + * Uploads a new video from a provided URL. 10735 + * @param url The URL to upload from. 10736 + * @param params Optional upload parameters. 10737 + * @returns The uploaded video details. 10738 + * @throws {BadRequestError} if the upload parameter is invalid or the URL is invalid 10739 + * @throws {QuotaReachedError} if the account storage capacity is exceeded 10740 + * @throws {MaxFileSizeError} if the file size is too large 10741 + * @throws {RateLimitedError} if the server received too many requests 10742 + * @throws {AlreadyUploadedError} if a video was already uploaded to this URL 10743 + * @throws {InternalError} if an unexpected error occurs 10744 + */ 10745 + upload(url: string, params?: StreamUrlUploadParams): Promise<StreamVideo>; 10746 + /** 10747 + * Creates a direct upload that allows video uploads without an API key. 10748 + * @param params Parameters for the direct upload 10749 + * @returns The direct upload details. 10750 + * @throws {BadRequestError} if the parameters are invalid 10751 + * @throws {RateLimitedError} if the server received too many requests 10752 + * @throws {InternalError} if an unexpected error occurs 10753 + */ 10754 + createDirectUpload(params: StreamDirectUploadCreateParams): Promise<StreamDirectUpload>; 10755 + videos: StreamVideos; 10756 + watermarks: StreamWatermarks; 10757 + } 10758 + /** 10759 + * Handle for operations scoped to a single Stream video. 10760 + */ 10761 + interface StreamVideoHandle { 10762 + /** 10763 + * The unique identifier for the video. 10764 + */ 10765 + id: string; 10766 + /** 10767 + * Get a full videos details 10768 + * @returns The full video details. 10769 + * @throws {NotFoundError} if the video is not found 10770 + * @throws {InternalError} if an unexpected error occurs 10771 + */ 10772 + details(): Promise<StreamVideo>; 10773 + /** 10774 + * Update details for a single video. 10775 + * @param params The fields to update for the video. 10776 + * @returns The updated video details. 10777 + * @throws {NotFoundError} if the video is not found 10778 + * @throws {BadRequestError} if the parameters are invalid 10779 + * @throws {InternalError} if an unexpected error occurs 10780 + */ 10781 + update(params: StreamUpdateVideoParams): Promise<StreamVideo>; 10782 + /** 10783 + * Deletes a video and its copies from Cloudflare Stream. 10784 + * @returns A promise that resolves when deletion completes. 10785 + * @throws {NotFoundError} if the video is not found 10786 + * @throws {InternalError} if an unexpected error occurs 10787 + */ 10788 + delete(): Promise<void>; 10789 + /** 10790 + * Creates a signed URL token for a video. 10791 + * @returns The signed token that was created. 10792 + * @throws {InternalError} if the signing key cannot be retrieved or the token cannot be signed 10793 + */ 10794 + generateToken(): Promise<string>; 10795 + downloads: StreamScopedDownloads; 10796 + captions: StreamScopedCaptions; 10797 + } 10798 + interface StreamVideo { 10799 + /** 10800 + * The unique identifier for the video. 10801 + */ 10802 + id: string; 10803 + /** 10804 + * A user-defined identifier for the media creator. 10805 + */ 10806 + creator: string | null; 10807 + /** 10808 + * The thumbnail URL for the video. 10809 + */ 10810 + thumbnail: string; 10811 + /** 10812 + * The thumbnail timestamp percentage. 10813 + */ 10814 + thumbnailTimestampPct: number; 10815 + /** 10816 + * Indicates whether the video is ready to stream. 10817 + */ 10818 + readyToStream: boolean; 10819 + /** 10820 + * The date and time the video became ready to stream. 10821 + */ 10822 + readyToStreamAt: string | null; 10823 + /** 10824 + * Processing status information. 10825 + */ 10826 + status: StreamVideoStatus; 10827 + /** 10828 + * A user modifiable key-value store. 10829 + */ 10830 + meta: Record<string, string>; 10831 + /** 10832 + * The date and time the video was created. 10833 + */ 10834 + created: string; 10835 + /** 10836 + * The date and time the video was last modified. 10837 + */ 10838 + modified: string; 10839 + /** 10840 + * The date and time at which the video will be deleted. 10841 + */ 10842 + scheduledDeletion: string | null; 10843 + /** 10844 + * The size of the video in bytes. 10845 + */ 10846 + size: number; 10847 + /** 10848 + * The preview URL for the video. 10849 + */ 10850 + preview?: string; 10851 + /** 10852 + * Origins allowed to display the video. 10853 + */ 10854 + allowedOrigins: Array<string>; 10855 + /** 10856 + * Indicates whether signed URLs are required. 10857 + */ 10858 + requireSignedURLs: boolean | null; 10859 + /** 10860 + * The date and time the video was uploaded. 10861 + */ 10862 + uploaded: string | null; 10863 + /** 10864 + * The date and time when the upload URL expires. 10865 + */ 10866 + uploadExpiry: string | null; 10867 + /** 10868 + * The maximum size in bytes for direct uploads. 10869 + */ 10870 + maxSizeBytes: number | null; 10871 + /** 10872 + * The maximum duration in seconds for direct uploads. 10873 + */ 10874 + maxDurationSeconds: number | null; 10875 + /** 10876 + * The video duration in seconds. -1 indicates unknown. 10877 + */ 10878 + duration: number; 10879 + /** 10880 + * Input metadata for the original upload. 10881 + */ 10882 + input: StreamVideoInput; 10883 + /** 10884 + * Playback URLs for the video. 10885 + */ 10886 + hlsPlaybackUrl: string; 10887 + dashPlaybackUrl: string; 10888 + /** 10889 + * The watermark applied to the video, if any. 10890 + */ 10891 + watermark: StreamWatermark | null; 10892 + /** 10893 + * The live input id associated with the video, if any. 10894 + */ 10895 + liveInputId?: string | null; 10896 + /** 10897 + * The source video id if this is a clip. 10898 + */ 10899 + clippedFromId: string | null; 10900 + /** 10901 + * Public details associated with the video. 10902 + */ 10903 + publicDetails: StreamPublicDetails | null; 10904 + } 10905 + type StreamVideoStatus = { 10906 + /** 10907 + * The current processing state. 10908 + */ 10909 + state: string; 10910 + /** 10911 + * The current processing step. 10912 + */ 10913 + step?: string; 10914 + /** 10915 + * The percent complete as a string. 10916 + */ 10917 + pctComplete?: string; 10918 + /** 10919 + * An error reason code, if applicable. 10920 + */ 10921 + errorReasonCode: string; 10922 + /** 10923 + * An error reason text, if applicable. 10924 + */ 10925 + errorReasonText: string; 10926 + }; 10927 + type StreamVideoInput = { 10928 + /** 10929 + * The input width in pixels. 10930 + */ 10931 + width: number; 10932 + /** 10933 + * The input height in pixels. 10934 + */ 10935 + height: number; 10936 + }; 10937 + type StreamPublicDetails = { 10938 + /** 10939 + * The public title for the video. 10940 + */ 10941 + title: string | null; 10942 + /** 10943 + * The public share link. 10944 + */ 10945 + share_link: string | null; 10946 + /** 10947 + * The public channel link. 10948 + */ 10949 + channel_link: string | null; 10950 + /** 10951 + * The public logo URL. 10952 + */ 10953 + logo: string | null; 10954 + }; 10955 + type StreamDirectUpload = { 10956 + /** 10957 + * The URL an unauthenticated upload can use for a single multipart request. 10958 + */ 10959 + uploadURL: string; 10960 + /** 10961 + * A Cloudflare-generated unique identifier for a media item. 10962 + */ 10963 + id: string; 10964 + /** 10965 + * The watermark profile applied to the upload. 10966 + */ 10967 + watermark: StreamWatermark | null; 10968 + /** 10969 + * The scheduled deletion time, if any. 10970 + */ 10971 + scheduledDeletion: string | null; 10972 + }; 10973 + type StreamDirectUploadCreateParams = { 10974 + /** 10975 + * The maximum duration in seconds for a video upload. 10976 + */ 10977 + maxDurationSeconds: number; 10978 + /** 10979 + * The date and time after upload when videos will not be accepted. 10980 + */ 10981 + expiry?: string; 10982 + /** 10983 + * A user-defined identifier for the media creator. 10984 + */ 10985 + creator?: string; 10986 + /** 10987 + * A user modifiable key-value store used to reference other systems of record for 10988 + * managing videos. 10989 + */ 10990 + meta?: Record<string, string>; 10991 + /** 10992 + * Lists the origins allowed to display the video. 10993 + */ 10994 + allowedOrigins?: Array<string>; 10995 + /** 10996 + * Indicates whether the video can be accessed using the id. When set to `true`, 10997 + * a signed token must be generated with a signing key to view the video. 10998 + */ 10999 + requireSignedURLs?: boolean; 11000 + /** 11001 + * The thumbnail timestamp percentage. 11002 + */ 11003 + thumbnailTimestampPct?: number; 11004 + /** 11005 + * The date and time at which the video will be deleted. Include `null` to remove 11006 + * a scheduled deletion. 11007 + */ 11008 + scheduledDeletion?: string | null; 11009 + /** 11010 + * The watermark profile to apply. 11011 + */ 11012 + watermark?: StreamDirectUploadWatermark; 11013 + }; 11014 + type StreamDirectUploadWatermark = { 11015 + /** 11016 + * The unique identifier for the watermark profile. 11017 + */ 11018 + id: string; 11019 + }; 11020 + type StreamUrlUploadParams = { 11021 + /** 11022 + * Lists the origins allowed to display the video. Enter allowed origin 11023 + * domains in an array and use `*` for wildcard subdomains. Empty arrays allow the 11024 + * video to be viewed on any origin. 11025 + */ 11026 + allowedOrigins?: Array<string>; 11027 + /** 11028 + * A user-defined identifier for the media creator. 11029 + */ 11030 + creator?: string; 11031 + /** 11032 + * A user modifiable key-value store used to reference other systems of 11033 + * record for managing videos. 11034 + */ 11035 + meta?: Record<string, string>; 11036 + /** 11037 + * Indicates whether the video can be a accessed using the id. When 11038 + * set to `true`, a signed token must be generated with a signing key to view the 11039 + * video. 11040 + */ 11041 + requireSignedURLs?: boolean; 11042 + /** 11043 + * Indicates the date and time at which the video will be deleted. Omit 11044 + * the field to indicate no change, or include with a `null` value to remove an 11045 + * existing scheduled deletion. If specified, must be at least 30 days from upload 11046 + * time. 11047 + */ 11048 + scheduledDeletion?: string | null; 11049 + /** 11050 + * The timestamp for a thumbnail image calculated as a percentage value 11051 + * of the video's duration. To convert from a second-wise timestamp to a 11052 + * percentage, divide the desired timestamp by the total duration of the video. If 11053 + * this value is not set, the default thumbnail image is taken from 0s of the 11054 + * video. 11055 + */ 11056 + thumbnailTimestampPct?: number; 11057 + /** 11058 + * The identifier for the watermark profile 11059 + */ 11060 + watermarkId?: string; 11061 + }; 11062 + interface StreamScopedCaptions { 11063 + /** 11064 + * Uploads the caption or subtitle file to the endpoint for a specific BCP47 language. 11065 + * One caption or subtitle file per language is allowed. 11066 + * @param language The BCP 47 language tag for the caption or subtitle. 11067 + * @param file The caption or subtitle file to upload. 11068 + * @returns The created caption entry. 11069 + * @throws {NotFoundError} if the video is not found 11070 + * @throws {BadRequestError} if the language or file is invalid 11071 + * @throws {MaxFileSizeError} if the file size is too large 11072 + * @throws {InternalError} if an unexpected error occurs 11073 + */ 11074 + upload(language: string, file: File): Promise<StreamCaption>; 11075 + /** 11076 + * Generate captions or subtitles for the provided language via AI. 11077 + * @param language The BCP 47 language tag to generate. 11078 + * @returns The generated caption entry. 11079 + * @throws {NotFoundError} if the video is not found 11080 + * @throws {BadRequestError} if the language is invalid 11081 + * @throws {StreamError} if a generated caption already exists 11082 + * @throws {StreamError} if the video duration is too long 11083 + * @throws {StreamError} if the video is missing audio 11084 + * @throws {StreamError} if the requested language is not supported 11085 + * @throws {InternalError} if an unexpected error occurs 11086 + */ 11087 + generate(language: string): Promise<StreamCaption>; 11088 + /** 11089 + * Lists the captions or subtitles. 11090 + * Use the language parameter to filter by a specific language. 11091 + * @param language The optional BCP 47 language tag to filter by. 11092 + * @returns The list of captions or subtitles. 11093 + * @throws {NotFoundError} if the video or caption is not found 11094 + * @throws {InternalError} if an unexpected error occurs 11095 + */ 11096 + list(language?: string): Promise<StreamCaption[]>; 11097 + /** 11098 + * Removes the captions or subtitles from a video. 11099 + * @param language The BCP 47 language tag to remove. 11100 + * @returns A promise that resolves when deletion completes. 11101 + * @throws {NotFoundError} if the video or caption is not found 11102 + * @throws {InternalError} if an unexpected error occurs 11103 + */ 11104 + delete(language: string): Promise<void>; 11105 + } 11106 + interface StreamScopedDownloads { 11107 + /** 11108 + * Generates a download for a video when a video is ready to view. Available 11109 + * types are `default` and `audio`. Defaults to `default` when omitted. 11110 + * @param downloadType The download type to create. 11111 + * @returns The current downloads for the video. 11112 + * @throws {NotFoundError} if the video is not found 11113 + * @throws {BadRequestError} if the download type is invalid 11114 + * @throws {StreamError} if the video duration is too long to generate a download 11115 + * @throws {StreamError} if the video is not ready to stream 11116 + * @throws {InternalError} if an unexpected error occurs 11117 + */ 11118 + generate(downloadType?: StreamDownloadType): Promise<StreamDownloadGetResponse>; 11119 + /** 11120 + * Lists the downloads created for a video. 11121 + * @returns The current downloads for the video. 11122 + * @throws {NotFoundError} if the video or downloads are not found 11123 + * @throws {InternalError} if an unexpected error occurs 11124 + */ 11125 + get(): Promise<StreamDownloadGetResponse>; 11126 + /** 11127 + * Delete the downloads for a video. Available types are `default` and `audio`. 11128 + * Defaults to `default` when omitted. 11129 + * @param downloadType The download type to delete. 11130 + * @returns A promise that resolves when deletion completes. 11131 + * @throws {NotFoundError} if the video or downloads are not found 11132 + * @throws {InternalError} if an unexpected error occurs 11133 + */ 11134 + delete(downloadType?: StreamDownloadType): Promise<void>; 11135 + } 11136 + interface StreamVideos { 11137 + /** 11138 + * Lists all videos in a users account. 11139 + * @returns The list of videos. 11140 + * @throws {BadRequestError} if the parameters are invalid 11141 + * @throws {InternalError} if an unexpected error occurs 11142 + */ 11143 + list(params?: StreamVideosListParams): Promise<StreamVideo[]>; 11144 + } 11145 + interface StreamWatermarks { 11146 + /** 11147 + * Generate a new watermark profile 11148 + * @param file The image file to upload 11149 + * @param params The watermark creation parameters. 11150 + * @returns The created watermark profile. 11151 + * @throws {BadRequestError} if the parameters are invalid 11152 + * @throws {InvalidURLError} if the URL is invalid 11153 + * @throws {MaxFileSizeError} if the file size is too large 11154 + * @throws {TooManyWatermarksError} if the number of allowed watermarks is reached 11155 + * @throws {InternalError} if an unexpected error occurs 11156 + */ 11157 + generate(file: File, params: StreamWatermarkCreateParams): Promise<StreamWatermark>; 11158 + /** 11159 + * Generate a new watermark profile 11160 + * @param url The image url to upload 11161 + * @param params The watermark creation parameters. 11162 + * @returns The created watermark profile. 11163 + * @throws {BadRequestError} if the parameters are invalid 11164 + * @throws {InvalidURLError} if the URL is invalid 11165 + * @throws {MaxFileSizeError} if the file size is too large 11166 + * @throws {TooManyWatermarksError} if the number of allowed watermarks is reached 11167 + * @throws {InternalError} if an unexpected error occurs 11168 + */ 11169 + generate(url: string, params: StreamWatermarkCreateParams): Promise<StreamWatermark>; 11170 + /** 11171 + * Lists all watermark profiles for an account. 11172 + * @returns The list of watermark profiles. 11173 + * @throws {InternalError} if an unexpected error occurs 11174 + */ 11175 + list(): Promise<StreamWatermark[]>; 11176 + /** 11177 + * Retrieves details for a single watermark profile. 11178 + * @param watermarkId The watermark profile identifier. 11179 + * @returns The watermark profile details. 11180 + * @throws {NotFoundError} if the watermark is not found 11181 + * @throws {InternalError} if an unexpected error occurs 11182 + */ 11183 + get(watermarkId: string): Promise<StreamWatermark>; 11184 + /** 11185 + * Deletes a watermark profile. 11186 + * @param watermarkId The watermark profile identifier. 11187 + * @returns A promise that resolves when deletion completes. 11188 + * @throws {NotFoundError} if the watermark is not found 11189 + * @throws {InternalError} if an unexpected error occurs 11190 + */ 11191 + delete(watermarkId: string): Promise<void>; 11192 + } 11193 + type StreamUpdateVideoParams = { 11194 + /** 11195 + * Lists the origins allowed to display the video. Enter allowed origin 11196 + * domains in an array and use `*` for wildcard subdomains. Empty arrays allow the 11197 + * video to be viewed on any origin. 11198 + */ 11199 + allowedOrigins?: Array<string>; 11200 + /** 11201 + * A user-defined identifier for the media creator. 11202 + */ 11203 + creator?: string; 11204 + /** 11205 + * The maximum duration in seconds for a video upload. Can be set for a 11206 + * video that is not yet uploaded to limit its duration. Uploads that exceed the 11207 + * specified duration will fail during processing. A value of `-1` means the value 11208 + * is unknown. 11209 + */ 11210 + maxDurationSeconds?: number; 11211 + /** 11212 + * A user modifiable key-value store used to reference other systems of 11213 + * record for managing videos. 11214 + */ 11215 + meta?: Record<string, string>; 11216 + /** 11217 + * Indicates whether the video can be a accessed using the id. When 11218 + * set to `true`, a signed token must be generated with a signing key to view the 11219 + * video. 11220 + */ 11221 + requireSignedURLs?: boolean; 11222 + /** 11223 + * Indicates the date and time at which the video will be deleted. Omit 11224 + * the field to indicate no change, or include with a `null` value to remove an 11225 + * existing scheduled deletion. If specified, must be at least 30 days from upload 11226 + * time. 11227 + */ 11228 + scheduledDeletion?: string | null; 11229 + /** 11230 + * The timestamp for a thumbnail image calculated as a percentage value 11231 + * of the video's duration. To convert from a second-wise timestamp to a 11232 + * percentage, divide the desired timestamp by the total duration of the video. If 11233 + * this value is not set, the default thumbnail image is taken from 0s of the 11234 + * video. 11235 + */ 11236 + thumbnailTimestampPct?: number; 11237 + }; 11238 + type StreamCaption = { 11239 + /** 11240 + * Whether the caption was generated via AI. 11241 + */ 11242 + generated?: boolean; 11243 + /** 11244 + * The language label displayed in the native language to users. 11245 + */ 11246 + label: string; 11247 + /** 11248 + * The language tag in BCP 47 format. 11249 + */ 11250 + language: string; 11251 + /** 11252 + * The status of a generated caption. 11253 + */ 11254 + status?: 'ready' | 'inprogress' | 'error'; 11255 + }; 11256 + type StreamDownloadStatus = 'ready' | 'inprogress' | 'error'; 11257 + type StreamDownloadType = 'default' | 'audio'; 11258 + type StreamDownload = { 11259 + /** 11260 + * Indicates the progress as a percentage between 0 and 100. 11261 + */ 11262 + percentComplete: number; 11263 + /** 11264 + * The status of a generated download. 11265 + */ 11266 + status: StreamDownloadStatus; 11267 + /** 11268 + * The URL to access the generated download. 11269 + */ 11270 + url?: string; 11271 + }; 11272 + /** 11273 + * An object with download type keys. Each key is optional and only present if that 11274 + * download type has been created. 11275 + */ 11276 + type StreamDownloadGetResponse = { 11277 + /** 11278 + * The audio-only download. Only present if this download type has been created. 11279 + */ 11280 + audio?: StreamDownload; 11281 + /** 11282 + * The default video download. Only present if this download type has been created. 11283 + */ 11284 + default?: StreamDownload; 11285 + }; 11286 + type StreamWatermarkPosition = 'upperRight' | 'upperLeft' | 'lowerLeft' | 'lowerRight' | 'center'; 11287 + type StreamWatermark = { 11288 + /** 11289 + * The unique identifier for a watermark profile. 11290 + */ 11291 + id: string; 11292 + /** 11293 + * The size of the image in bytes. 11294 + */ 11295 + size: number; 11296 + /** 11297 + * The height of the image in pixels. 11298 + */ 11299 + height: number; 11300 + /** 11301 + * The width of the image in pixels. 11302 + */ 11303 + width: number; 11304 + /** 11305 + * The date and a time a watermark profile was created. 11306 + */ 11307 + created: string; 11308 + /** 11309 + * The source URL for a downloaded image. If the watermark profile was created via 11310 + * direct upload, this field is null. 11311 + */ 11312 + downloadedFrom: string | null; 11313 + /** 11314 + * A short description of the watermark profile. 11315 + */ 11316 + name: string; 11317 + /** 11318 + * The translucency of the image. A value of `0.0` makes the image completely 11319 + * transparent, and `1.0` makes the image completely opaque. Note that if the image 11320 + * is already semi-transparent, setting this to `1.0` will not make the image 11321 + * completely opaque. 11322 + */ 11323 + opacity: number; 11324 + /** 11325 + * The whitespace between the adjacent edges (determined by position) of the video 11326 + * and the image. `0.0` indicates no padding, and `1.0` indicates a fully padded 11327 + * video width or length, as determined by the algorithm. 11328 + */ 11329 + padding: number; 11330 + /** 11331 + * The size of the image relative to the overall size of the video. This parameter 11332 + * will adapt to horizontal and vertical videos automatically. `0.0` indicates no 11333 + * scaling (use the size of the image as-is), and `1.0 `fills the entire video. 11334 + */ 11335 + scale: number; 11336 + /** 11337 + * The location of the image. Valid positions are: `upperRight`, `upperLeft`, 11338 + * `lowerLeft`, `lowerRight`, and `center`. Note that `center` ignores the 11339 + * `padding` parameter. 11340 + */ 11341 + position: StreamWatermarkPosition; 11342 + }; 11343 + type StreamWatermarkCreateParams = { 11344 + /** 11345 + * A short description of the watermark profile. 11346 + */ 11347 + name?: string; 11348 + /** 11349 + * The translucency of the image. A value of `0.0` makes the image completely 11350 + * transparent, and `1.0` makes the image completely opaque. Note that if the 11351 + * image is already semi-transparent, setting this to `1.0` will not make the 11352 + * image completely opaque. 11353 + */ 11354 + opacity?: number; 11355 + /** 11356 + * The whitespace between the adjacent edges (determined by position) of the 11357 + * video and the image. `0.0` indicates no padding, and `1.0` indicates a fully 11358 + * padded video width or length, as determined by the algorithm. 11359 + */ 11360 + padding?: number; 11361 + /** 11362 + * The size of the image relative to the overall size of the video. This 11363 + * parameter will adapt to horizontal and vertical videos automatically. `0.0` 11364 + * indicates no scaling (use the size of the image as-is), and `1.0 `fills the 11365 + * entire video. 11366 + */ 11367 + scale?: number; 11368 + /** 11369 + * The location of the image. 11370 + */ 11371 + position?: StreamWatermarkPosition; 11372 + }; 11373 + type StreamVideosListParams = { 11374 + /** 11375 + * The maximum number of videos to return. 11376 + */ 11377 + limit?: number; 11378 + /** 11379 + * Return videos created before this timestamp. 11380 + * (RFC3339/RFC3339Nano) 11381 + */ 11382 + before?: string; 11383 + /** 11384 + * Comparison operator for the `before` field. 11385 + * @default 'lt' 11386 + */ 11387 + beforeComp?: StreamPaginationComparison; 11388 + /** 11389 + * Return videos created after this timestamp. 11390 + * (RFC3339/RFC3339Nano) 11391 + */ 11392 + after?: string; 11393 + /** 11394 + * Comparison operator for the `after` field. 11395 + * @default 'gte' 11396 + */ 11397 + afterComp?: StreamPaginationComparison; 11398 + }; 11399 + type StreamPaginationComparison = 'eq' | 'gt' | 'gte' | 'lt' | 'lte'; 11400 + /** 11401 + * Error object for Stream binding operations. 11402 + */ 11403 + interface StreamError extends Error { 11404 + readonly code: number; 11405 + readonly statusCode: number; 11406 + readonly message: string; 11407 + readonly stack?: string; 11408 + } 11409 + interface InternalError extends StreamError { 11410 + name: 'InternalError'; 11411 + } 11412 + interface BadRequestError extends StreamError { 11413 + name: 'BadRequestError'; 11414 + } 11415 + interface NotFoundError extends StreamError { 11416 + name: 'NotFoundError'; 11417 + } 11418 + interface ForbiddenError extends StreamError { 11419 + name: 'ForbiddenError'; 11420 + } 11421 + interface RateLimitedError extends StreamError { 11422 + name: 'RateLimitedError'; 11423 + } 11424 + interface QuotaReachedError extends StreamError { 11425 + name: 'QuotaReachedError'; 11426 + } 11427 + interface MaxFileSizeError extends StreamError { 11428 + name: 'MaxFileSizeError'; 11429 + } 11430 + interface InvalidURLError extends StreamError { 11431 + name: 'InvalidURLError'; 11432 + } 11433 + interface AlreadyUploadedError extends StreamError { 11434 + name: 'AlreadyUploadedError'; 11435 + } 11436 + interface TooManyWatermarksError extends StreamError { 11437 + name: 'TooManyWatermarksError'; 10689 11438 } 10690 11439 type MarkdownDocument = { 10691 11440 name: string;
+11
wrangler.toml
··· 21 21 database_name = "bskylabels" 22 22 database_id = "" 23 23 24 + [[ratelimits]] 25 + name = "BSKY_LABEL_LIMITER" 26 + namespace_id = "461001" 27 + [ratelimits.simple] 28 + limit = 10 29 + period = 60 30 + 24 31 [vars] 25 32 COUNT_CACHE_HOUR="4" 33 + 34 + # use rate limits (recommended) 35 + RATELIMIT="true" 36 + 26 37 # Site metadata 27 38 SITE_TITLE="Simple BSky Labeler" 28 39 SITE_DESCRIPTION="Allow people to obtain a bsky label you provide"