handy online tools for AT Protocol boat.kelinci.net
atproto bluesky atcute typescript solidjs
20
fork

Configure Feed

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

fix: it doesn't work

Mary 6e09467b c9e85fdf

+97 -36
+1 -1
package.json
··· 24 24 }, 25 25 "devDependencies": { 26 26 "@tailwindcss/forms": "^0.5.9", 27 - "@types/node": "^22.8.2", 27 + "@types/bun": "^1.1.14", 28 28 "autoprefixer": "^10.4.20", 29 29 "prettier": "^3.3.3", 30 30 "prettier-plugin-tailwindcss": "^0.6.8",
+37 -3
pnpm-lock.yaml
··· 54 54 '@tailwindcss/forms': 55 55 specifier: ^0.5.9 56 56 version: 0.5.9(tailwindcss@3.4.14) 57 - '@types/node': 58 - specifier: ^22.8.2 59 - version: 22.8.2 57 + '@types/bun': 58 + specifier: ^1.1.14 59 + version: 1.1.14 60 60 autoprefixer: 61 61 specifier: ^10.4.20 62 62 version: 10.4.20(postcss@8.4.47) ··· 698 698 '@types/babel__traverse@7.20.6': 699 699 resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} 700 700 701 + '@types/bun@1.1.14': 702 + resolution: {integrity: sha512-opVYiFGtO2af0dnWBdZWlioLBoxSdDO5qokaazLhq8XQtGZbY4pY3/JxY8Zdf/hEwGubbp7ErZXoN1+h2yesxA==} 703 + 701 704 '@types/estree@1.0.6': 702 705 resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 703 706 704 707 '@types/node-forge@1.3.11': 705 708 resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} 706 709 710 + '@types/node@20.12.14': 711 + resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} 712 + 707 713 '@types/node@22.8.2': 708 714 resolution: {integrity: sha512-NzaRNFV+FZkvK/KLCsNdTvID0SThyrs5SHB6tsD/lajr22FGC73N2QeDPM2wHtVde8mgcXuSsHQkH5cX1pbPLw==} 715 + 716 + '@types/ws@8.5.13': 717 + resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} 709 718 710 719 acorn-walk@8.3.4: 711 720 resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} ··· 786 795 787 796 buffer-from@1.1.2: 788 797 resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 798 + 799 + bun-types@1.1.37: 800 + resolution: {integrity: sha512-C65lv6eBr3LPJWFZ2gswyrGZ82ljnH8flVE03xeXxKhi2ZGtFiO4isRKTKnitbSqtRAcaqYSR6djt1whI66AbA==} 789 801 790 802 camelcase-css@2.0.1: 791 803 resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} ··· 1438 1450 uint8arrays@5.1.0: 1439 1451 resolution: {integrity: sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==} 1440 1452 1453 + undici-types@5.26.5: 1454 + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} 1455 + 1441 1456 undici-types@6.19.8: 1442 1457 resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} 1443 1458 ··· 2050 2065 dependencies: 2051 2066 '@babel/types': 7.26.0 2052 2067 2068 + '@types/bun@1.1.14': 2069 + dependencies: 2070 + bun-types: 1.1.37 2071 + 2053 2072 '@types/estree@1.0.6': {} 2054 2073 2055 2074 '@types/node-forge@1.3.11': 2056 2075 dependencies: 2057 2076 '@types/node': 22.8.2 2058 2077 2078 + '@types/node@20.12.14': 2079 + dependencies: 2080 + undici-types: 5.26.5 2081 + 2059 2082 '@types/node@22.8.2': 2060 2083 dependencies: 2061 2084 undici-types: 6.19.8 2062 2085 2086 + '@types/ws@8.5.13': 2087 + dependencies: 2088 + '@types/node': 22.8.2 2089 + 2063 2090 acorn-walk@8.3.4: 2064 2091 dependencies: 2065 2092 acorn: 8.14.0 ··· 2136 2163 update-browserslist-db: 1.1.1(browserslist@4.24.2) 2137 2164 2138 2165 buffer-from@1.1.2: {} 2166 + 2167 + bun-types@1.1.37: 2168 + dependencies: 2169 + '@types/node': 20.12.14 2170 + '@types/ws': 8.5.13 2139 2171 2140 2172 camelcase-css@2.0.1: {} 2141 2173 ··· 2749 2781 uint8arrays@5.1.0: 2750 2782 dependencies: 2751 2783 multiformats: 13.3.1 2784 + 2785 + undici-types@5.26.5: {} 2752 2786 2753 2787 undici-types@6.19.8: {} 2754 2788
+16 -14
src/api/types/did-doc.ts
··· 9 9 publicKeyMultibase: v.optional(v.string()), 10 10 }); 11 11 12 - const service = v.variant('type', [ 13 - v.object({ 14 - id: v.string(), 15 - type: v.union([ 16 - v.union([ 17 - v.literal('AtprotoPersonalDataServer'), 18 - v.literal('AtprotoLabeler'), 19 - v.literal('BskyFeedGenerator'), 20 - v.literal('BskyNotificationService'), 21 - ]), 22 - ]), 23 - serviceEndpoint: serviceUrlString, 24 - }), 12 + const service = v.pipe( 25 13 v.object({ 26 14 id: v.string(), 27 15 type: v.string(), 28 16 serviceEndpoint: v.union([urlString, v.record(v.string(), urlString), v.array(urlString)]), 29 17 }), 30 - ]); 18 + v.forward( 19 + v.check((input) => { 20 + switch (input.type) { 21 + case 'AtprotoPersonalDataServer': 22 + case 'AtprotoLabeler': 23 + case 'BskyFeedGenerator': 24 + case 'BskyNotificationService': 25 + return v.is(serviceUrlString, input.serviceEndpoint); 26 + } 27 + 28 + return true; 29 + }, 'must be a valid atproto service endpoint'), 30 + ['serviceEndpoint'], 31 + ), 32 + ); 31 33 32 34 export const didDocument = v.object({ 33 35 id: didString,
+16 -14
src/api/types/plc.ts
··· 65 65 ...v.omit(updateOp, ['type', 'prev', 'sig', 'services']).entries, 66 66 services: v.record( 67 67 v.string(), 68 - v.variant('type', [ 69 - v.object({ 70 - type: v.union([ 71 - v.literal('AtprotoPersonalDataServer'), 72 - v.literal('AtprotoLabeler'), 73 - v.literal('BskyFeedGenerator'), 74 - v.literal('BskyNotificationService'), 75 - ]), 76 - endpoint: v.pipe( 77 - serviceUrlString, 78 - v.transform((urlString) => urlString.replace(/\/$/, '')), 79 - ), 80 - }), 68 + v.pipe( 81 69 v.object({ 82 70 type: v.string(), 83 71 endpoint: urlString, 84 72 }), 85 - ]), 73 + v.forward( 74 + v.check((input) => { 75 + switch (input.type) { 76 + case 'AtprotoPersonalDataServer': 77 + case 'AtprotoLabeler': 78 + case 'BskyFeedGenerator': 79 + case 'BskyNotificationService': 80 + return v.is(serviceUrlString, input.endpoint); 81 + } 82 + 83 + return true; 84 + }, 'must be a valid atproto service endpoint'), 85 + ['endpoint'], 86 + ), 87 + ), 86 88 ), 87 89 }); 88 90 export type PlcUpdatePayload = v.InferOutput<typeof updatePayload>;
+1 -1
src/api/types/strings.ts
··· 19 19 url.search === '' && 20 20 url.hash === '' 21 21 ); 22 - }, 'must be a valid service url'), 22 + }, 'must be a valid atproto service url'), 23 23 ); 24 24 25 25 export const didKeyString = v.pipe(
+1 -1
src/api/utils/strings.ts
··· 1 1 import type { At, Records } from '@atcute/client/lexicons'; 2 2 3 - import { assert } from '~/lib/utils/invariant'; 3 + import { assert } from '../../lib/utils/invariant'; 4 4 5 5 export const ATURI_RE = 6 6 /^at:\/\/(did:[a-zA-Z0-9._:%\-]+|[a-zA-Z0-9-.]+)\/([a-zA-Z0-9-.]+)\/([a-zA-Z0-9._~:@!$&%')(*+,;=\-]+)(?:#(\/[a-zA-Z0-9._~:@!$&%')(*+,;=\-[\]/\\]*))?$/;
+23
tests/plc.test.ts
··· 1 + import { describe, it, expect } from 'bun:test'; 2 + 3 + import * as v from 'valibot'; 4 + 5 + import { updatePayload, PlcUpdatePayload } from '../src/api/types/plc.ts'; 6 + 7 + describe('update payload', () => { 8 + it('does not allow atproto service endpoints containing paths', () => { 9 + const payload: PlcUpdatePayload = { 10 + alsoKnownAs: [], 11 + rotationKeys: ['did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg'], 12 + verificationMethods: {}, 13 + services: { 14 + atproto_pds: { 15 + type: 'AtprotoPersonalDataServer', 16 + endpoint: 'https://pds.test/hello', 17 + }, 18 + }, 19 + }; 20 + 21 + expect(() => v.assert(updatePayload, payload)).toThrow(/must be a valid atproto service endpoint/); 22 + }); 23 + });
+2 -2
tsconfig.node.json
··· 4 4 "useDefineForClassFields": false, 5 5 "module": "NodeNext", 6 6 "lib": ["ESNext"], 7 - "types": ["node"], 7 + "types": ["bun"], 8 8 "skipLibCheck": true, 9 9 10 10 "moduleResolution": "NodeNext", ··· 19 19 "noFallthroughCasesInSwitch": true, 20 20 "noUncheckedSideEffectImports": true, 21 21 }, 22 - "include": ["vite.config.ts"], 22 + "include": ["vite.config.ts", "tests/"], 23 23 }