cerulea/lexicon
define atproto schemas in TypeScript
git clone https://git.t4t.associates/cerulea/lexicon
1945441
main
1import * as l from "../mod.ts" ; 2import { assert } from "./assert.ts" ; 3 4const cases :readonly [ l . Schema , readonly string [], readonly string []][] = [ 5[ l . did , [ 6"did:plc:alice" , 7"did:web:example.com" , 8"did:web:example.com%3A3000:users:alice" , 9"did:example:abc%20" , 10], [ 11"" , 12"did:plc:" , 13"did:PLC:alice" , 14"did:plc:alice/extra" , 15"did:plc:alice#fragment" , 16"did:plc:abc%zz" , 17"did:plc:abc:" , 18]], 19[ l . atUri , [ 20"at://did:plc:alice" , 21"at://alice.example" , 22"at://did:plc:alice/blue.cerulea.app.post/abc" , 23"at://alice.example/blue.cerulea.app.profile/self" , 24], [ 25"https://example.com" , 26"at://alice" , 27"at://did:plc:alice/bad/key" , 28"at://did:plc:alice/blue.cerulea.app.post/.." , 29"at://did:plc:alice/blue.cerulea.app.post/key?x=1" , 30"at://did:plc:alice/blue.cerulea.app.post/key/extra" , 31]], 32[ l . datetime , [ 33"2024-02-29T23:59:59Z" , 34"2026-09-16T00:00:00.000123Z" , 35"1985-04-12T23:20:50.123+07:30" , 36"0000-01-01T00:00:00Z" , 37], [ 38"2023-02-29T00:00:00Z" , 39"2024-02-30T00:00:00Z" , 40"2026-13-01T00:00:00Z" , 41"2026-09-16T24:00:00Z" , 42"2026-09-16T00:00:00" , 43"2026-09-16t00:00:00z" , 44"2026-09-16T00:00:00-00:00" , 45"2026-09-16T00:00:00+24:00" , 46"0000-01-01T00:00:00+01:00" , 47]], 48[ l . language , [ 49"en" , 50"pt-BR" , 51"zh-Hant-TW" , 52"de-CH-1901" , 53"sl-rozaj-biske" , 54"en-US-u-ca-gregory" , 55"en-a-foo-b-bar" , 56"x-private" , 57"i-klingon" , 58"en-GB-oed" , 59], [ "" , "e" , "en_US" , "en-" , "abcdefghi" , "en-a" , "x" , "en-1901-1901" , "en-a-foo-a-bar" ]], 60[ l . uri , [ 61"https://example.com/path?q=a%20b#anchor" , 62"mailto:alice@example.com" , 63"did:plc:alice" , 64"urn:isbn:0451450523" , 65"https://[::1]:8080/path" , 66"file:///tmp/a" , 67"custom://[v1.test]/" , 68], [ 69"relative/path" , 70"https://example.com/a b" , 71"https://example.com/%GG" , 72"https://example.com/🙂" , 73"1http://example.com" , 74"https://example.com/#a#b" , 75"https://example.com:abc" , 76"https://[not-ip]/" , 77]], 78[ l . nsid , [ "blue.cerulea.app.post" , "com.example.getProfile" , "com.example-v2.post" ], [ 79"com.example" , 80"com..post" , 81"com.example.1post" , 82"com.example.post-name" , 83"com.-example.post" , 84"1com.example.post" , 85]], 86[ l . cid , [ 87"bafyreiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" , 88"bafkreiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" , 89], [ 90"" , 91"not-a-cid" , 92"bafyreia" , 93"bafyreiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" , 94"BAFYREIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" , 95"QmYwAPJzv5CZsnAzt8auVTLwPjVEhUV9BM1hNnA5mJ7uSY" , 96"f01711220" + "00" . repeat ( 32 ), 97]], 98]; 99 100for ( const [ schema , valid , invalid ] of cases ) { 101const format = schema . type === "string" ?schema . format :schema . type ; 102Deno . test ( ` ${ format } syntax accepts valid values and rejects malformed ones` , () => { 103const check = l . compile ( schema ); 104for ( const value of valid ) assert ( check ( value ). success , `Rejected valid ${ format } : ${ value } ` ); 105for ( const value of invalid ) { 106assert ( ! check ( value ). success , `Accepted invalid ${ format } : ${ value } ` ); 107} 108}); 109}