JavaScript-optional public web frontend for Bluesky anartia.kelinci.net
sveltekit atcute bluesky typescript svelte

refactor: replace valita with valibot

mary.my.id 4a542657 efbc48a2

verified
+49 -28
+2 -2
package.json
··· 35 35 "@atcute/lexicons": "^1.1.1", 36 36 "@atcute/multibase": "^1.1.5", 37 37 "@atcute/uint8array": "^1.0.4", 38 - "@badrap/valita": "^0.4.6", 39 38 "@mary/array-fns": "jsr:^0.1.5", 40 39 "@mary/date-fns": "jsr:^0.1.3", 41 - "hls.js": "^1.6.13" 40 + "hls.js": "^1.6.13", 41 + "valibot": "^1.1.0" 42 42 }, 43 43 "pnpm": { 44 44 "onlyBuiltDependencies": [
+15 -3
pnpm-lock.yaml
··· 32 32 '@atcute/uint8array': 33 33 specifier: ^1.0.4 34 34 version: 1.0.4 35 - '@badrap/valita': 36 - specifier: ^0.4.6 37 - version: 0.4.6 38 35 '@mary/array-fns': 39 36 specifier: jsr:^0.1.5 40 37 version: '@jsr/mary__array-fns@0.1.5' ··· 44 41 hls.js: 45 42 specifier: ^1.6.13 46 43 version: 1.6.13 44 + valibot: 45 + specifier: ^1.1.0 46 + version: 1.1.0(typescript@5.8.3) 47 47 devDependencies: 48 48 '@sveltejs/adapter-cloudflare': 49 49 specifier: ^7.2.3 ··· 1088 1088 unenv@2.0.0-rc.21: 1089 1089 resolution: {integrity: sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==} 1090 1090 1091 + valibot@1.1.0: 1092 + resolution: {integrity: sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==} 1093 + peerDependencies: 1094 + typescript: '>=5' 1095 + peerDependenciesMeta: 1096 + typescript: 1097 + optional: true 1098 + 1091 1099 vite@7.1.7: 1092 1100 resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} 1093 1101 engines: {node: ^20.19.0 || >=22.12.0} ··· 2002 2010 ohash: 2.0.11 2003 2011 pathe: 2.0.3 2004 2012 ufo: 1.6.1 2013 + 2014 + valibot@1.1.0(typescript@5.8.3): 2015 + optionalDependencies: 2016 + typescript: 5.8.3 2005 2017 2006 2018 vite@7.1.7: 2007 2019 dependencies:
+7 -7
src/lib/queries/constellation.ts
··· 5 5 import { fromBase64Url, toBase64Url } from '@atcute/multibase'; 6 6 import { decodeUtf8From, encodeUtf8 } from '@atcute/uint8array'; 7 7 8 - import * as v from '@badrap/valita'; 8 + import * as v from 'valibot'; 9 9 10 10 import { PUBLIC_APP_USER_AGENT, PUBLIC_CONSTELLATION_URL } from '$env/static/public'; 11 11 12 - import { didString, integer, nsidString, recordKeyString } from '$lib/types/valita'; 12 + import { didString, integer, nsidString, recordKeyString } from '$lib/types/valibot'; 13 13 14 14 const linkResponse = v.object({ 15 15 total: integer, 16 - cursor: v.string().nullable(), 16 + cursor: v.nullable(v.string()), 17 17 linking_records: v.array( 18 18 v.object({ 19 19 did: didString, ··· 65 65 } 66 66 67 67 const rawJson = await response.json(); 68 - const json = linkResponse.parse(rawJson, { mode: 'passthrough' }); 68 + const json = v.parse(linkResponse, rawJson); 69 69 70 70 return json as LinkResponse<K>; 71 71 }; 72 72 73 - const multiPathCursor = v.tuple([v.string(), v.string().nullable()]); 73 + const multiPathCursor = v.tuple([v.string(), v.nullable(v.string())]); 74 74 75 75 /** 76 76 * generate multi path cursor ··· 79 79 * @returns compressed cursor 80 80 */ 81 81 const generateMultiPathCursor = (path: string, subcursor: string | null): string => { 82 - const mp: v.Infer<typeof multiPathCursor> = [path, subcursor]; 82 + const mp: v.InferOutput<typeof multiPathCursor> = [path, subcursor]; 83 83 const json = JSON.stringify(mp); 84 84 85 85 return toBase64Url(encodeUtf8(json)); ··· 119 119 const raw = decodeUtf8From(fromBase64Url(cursor)); 120 120 const json = JSON.parse(raw); 121 121 122 - const [currentPath, subCursor] = multiPathCursor.parse(json); 122 + const [currentPath, subCursor] = v.parse(multiPathCursor, json); 123 123 const foundIndex = paths.indexOf(currentPath); 124 124 125 125 if (foundIndex === -1) {
+20
src/lib/types/valibot.ts
··· 1 + import { isDid, isNsid, isRecordKey, type Did, type Nsid, type RecordKey } from '@atcute/lexicons/syntax'; 2 + 3 + import * as v from 'valibot'; 4 + 5 + export const didString = v.pipe( 6 + v.string(), 7 + v.check((input) => isDid(input), `must be a did string`), 8 + ) as v.GenericSchema<string, Did>; 9 + 10 + export const nsidString = v.pipe( 11 + v.string(), 12 + v.check((input) => isNsid(input), `must be an nsid string`), 13 + ) as v.GenericSchema<string, Nsid>; 14 + 15 + export const recordKeyString = v.pipe( 16 + v.string(), 17 + v.check((input) => isRecordKey(input), `must be an rkey string`), 18 + ) as v.GenericSchema<string, RecordKey>; 19 + 20 + export const integer = v.pipe(v.number(), v.safeInteger(), v.minValue(0));
-11
src/lib/types/valita.ts
··· 1 - import { isDid, isNsid, isRecordKey } from '@atcute/lexicons/syntax'; 2 - 3 - import * as v from '@badrap/valita'; 4 - 5 - export const didString = v.string().assert(isDid); 6 - 7 - export const nsidString = v.string().assert(isNsid); 8 - 9 - export const recordKeyString = v.string().assert(isRecordKey); 10 - 11 - export const integer = v.number().assert((input) => Number.isSafeInteger(input) && input >= 0);
+5 -5
src/routes/go/[shortid]/+page.ts
··· 1 1 import { error, redirect } from '@sveltejs/kit'; 2 2 3 - import * as v from '@badrap/valita'; 3 + import * as v from 'valibot'; 4 4 5 5 import { PUBLIC_GO_BSKY_URL } from '$env/static/public'; 6 6 import type { PageLoad } from './$types'; ··· 28 28 29 29 const raw = await response.json(); 30 30 31 - const result = jsonSchema.try(raw); 32 - if (!result.ok) { 31 + const result = v.safeParse(jsonSchema, raw); 32 + if (!result.success) { 33 33 error(500, `Invalid response from upstream server`); 34 34 } 35 35 36 - const url = safeUrlParse(result.value.url); 36 + const url = safeUrlParse(result.output.url); 37 37 if (!url) { 38 - error(500, `Invalid URL from upstream server; got ${result.value.url}`); 38 + error(500, `Invalid URL from upstream server; got ${result.output.url}`); 39 39 } 40 40 41 41 const redir = redirectBskyUrl(url);