An experimental TypeSpec syntax for Lexicon
at externals 276 lines 7.1 kB view raw
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