cerulea/lexicon

define atproto schemas in TypeScript

git clone https://git.t4t.associates/cerulea/lexicon

Charlotte Sominitial commit1945441

main
3.1 KiB109 linesraw
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) {
101  const format = schema.type === "string" ? schema.format : schema.type;
102  Deno.test(`${format} syntax accepts valid values and rejects malformed ones`, () => {
103    const check = l.compile(schema);
104    for (const value of valid) assert(check(value).success, `Rejected valid ${format}: ${value}`);
105    for (const value of invalid) {
106      assert(!check(value).success, `Accepted invalid ${format}: ${value}`);
107    }
108  });
109}