An experimental TypeSpec syntax for Lexicon
1/**
2 * GENERATED CODE - DO NOT MODIFY
3 */
4import {
5 type LexiconDoc,
6 Lexicons,
7 ValidationError,
8 type ValidationResult,
9} from '@atproto/lexicon'
10import { type $Typed, is$typed, maybe$typed } from './util.js'
11
12export const schemaDict = {
13 AppExampleDefs: {
14 lexicon: 1,
15 id: 'app.example.defs',
16 defs: {
17 postRef: {
18 type: 'object',
19 properties: {
20 uri: {
21 type: 'string',
22 description: 'AT URI of the post',
23 },
24 cid: {
25 type: 'string',
26 description: 'CID of the post',
27 },
28 },
29 description: 'Reference to a post',
30 required: ['uri', 'cid'],
31 },
32 replyRef: {
33 type: 'object',
34 properties: {
35 root: {
36 type: 'ref',
37 ref: 'lex:app.example.defs#postRef',
38 description: 'Root post in the thread',
39 },
40 parent: {
41 type: 'ref',
42 ref: 'lex:app.example.defs#postRef',
43 description: 'Direct parent post being replied to',
44 },
45 },
46 description: 'Reference to a parent post in a reply chain',
47 required: ['root', 'parent'],
48 },
49 entity: {
50 type: 'object',
51 properties: {
52 start: {
53 type: 'integer',
54 description: 'Start index in text',
55 },
56 end: {
57 type: 'integer',
58 description: 'End index in text',
59 },
60 type: {
61 type: 'string',
62 description: 'Entity type',
63 },
64 value: {
65 type: 'string',
66 description: 'Entity value (handle, URL, or tag)',
67 },
68 },
69 description: 'Text entity (mention, link, or tag)',
70 required: ['start', 'end', 'type', 'value'],
71 },
72 notificationType: {
73 type: 'string',
74 knownValues: ['like', 'repost', 'follow', 'mention', 'reply'],
75 description: 'Type of notification',
76 },
77 },
78 },
79 AppExampleFollow: {
80 lexicon: 1,
81 id: 'app.example.follow',
82 defs: {
83 main: {
84 type: 'record',
85 key: 'tid',
86 record: {
87 type: 'object',
88 properties: {
89 subject: {
90 type: 'string',
91 description: 'DID of the account being followed',
92 },
93 createdAt: {
94 type: 'string',
95 format: 'datetime',
96 description: 'When the follow was created',
97 },
98 },
99 required: ['subject', 'createdAt'],
100 },
101 description: 'A follow relationship',
102 },
103 },
104 },
105 AppExampleLike: {
106 lexicon: 1,
107 id: 'app.example.like',
108 defs: {
109 main: {
110 type: 'record',
111 key: 'tid',
112 record: {
113 type: 'object',
114 properties: {
115 subject: {
116 type: 'ref',
117 ref: 'lex:app.example.defs#postRef',
118 description: 'Post being liked',
119 },
120 createdAt: {
121 type: 'string',
122 format: 'datetime',
123 description: 'When the like was created',
124 },
125 },
126 required: ['subject', 'createdAt'],
127 },
128 description: 'A like on a post',
129 },
130 },
131 },
132 AppExamplePost: {
133 lexicon: 1,
134 id: 'app.example.post',
135 defs: {
136 main: {
137 type: 'record',
138 key: 'tid',
139 record: {
140 type: 'object',
141 properties: {
142 text: {
143 type: 'string',
144 description: 'Post text content',
145 },
146 createdAt: {
147 type: 'string',
148 format: 'datetime',
149 description: 'Creation timestamp',
150 },
151 langs: {
152 type: 'array',
153 items: {
154 type: 'string',
155 },
156 description: 'Languages the post is written in',
157 },
158 entities: {
159 type: 'array',
160 items: {
161 type: 'ref',
162 ref: 'lex:app.example.defs#entity',
163 },
164 description: 'Referenced entities in the post',
165 },
166 reply: {
167 type: 'ref',
168 ref: 'lex:app.example.defs#replyRef',
169 description: 'Post the user is replying to',
170 },
171 },
172 required: ['text', 'createdAt'],
173 },
174 description: 'A post in the feed',
175 },
176 },
177 },
178 AppExampleProfile: {
179 lexicon: 1,
180 id: 'app.example.profile',
181 defs: {
182 main: {
183 type: 'record',
184 key: 'self',
185 record: {
186 type: 'object',
187 properties: {
188 displayName: {
189 type: 'string',
190 description: 'Display name',
191 },
192 description: {
193 type: 'string',
194 description: 'Profile description',
195 },
196 avatar: {
197 type: 'string',
198 description: 'Profile avatar image',
199 },
200 banner: {
201 type: 'string',
202 description: 'Profile banner image',
203 },
204 },
205 },
206 description: 'User profile information',
207 },
208 },
209 },
210 AppExampleRepost: {
211 lexicon: 1,
212 id: 'app.example.repost',
213 defs: {
214 main: {
215 type: 'record',
216 key: 'tid',
217 record: {
218 type: 'object',
219 properties: {
220 subject: {
221 type: 'ref',
222 ref: 'lex:app.example.defs#postRef',
223 description: 'Post being reposted',
224 },
225 createdAt: {
226 type: 'string',
227 format: 'datetime',
228 description: 'When the repost was created',
229 },
230 },
231 required: ['subject', 'createdAt'],
232 },
233 description: 'A repost of another post',
234 },
235 },
236 },
237} as const satisfies Record<string, LexiconDoc>
238export const schemas = Object.values(schemaDict) satisfies LexiconDoc[]
239export const lexicons: Lexicons = new Lexicons(schemas)
240
241export function validate<T extends { $type: string }>(
242 v: unknown,
243 id: string,
244 hash: string,
245 requiredType: true,
246): ValidationResult<T>
247export function validate<T extends { $type?: string }>(
248 v: unknown,
249 id: string,
250 hash: string,
251 requiredType?: false,
252): ValidationResult<T>
253export function validate(
254 v: unknown,
255 id: string,
256 hash: string,
257 requiredType?: boolean,
258): ValidationResult {
259 return (requiredType ? is$typed : maybe$typed)(v, id, hash)
260 ? lexicons.validate(`${id}#${hash}`, v)
261 : {
262 success: false,
263 error: new ValidationError(
264 `Must be an object with "${hash === 'main' ? id : `${id}#${hash}`}" $type property`,
265 ),
266 }
267}
268
269export const ids = {
270 AppExampleDefs: 'app.example.defs',
271 AppExampleFollow: 'app.example.follow',
272 AppExampleLike: 'app.example.like',
273 AppExamplePost: 'app.example.post',
274 AppExampleProfile: 'app.example.profile',
275 AppExampleRepost: 'app.example.repost',
276} as const