An experimental TypeSpec syntax for Lexicon
at cli 216 lines 4.3 kB view raw
1/** 2 * Simplified TypeSpec emitter types for Atproto Lexicon 3 * 4 * These types mirror the atproto lexicon structure but use plain TypeScript 5 * instead of Zod schemas. This avoids type conflicts from discriminated unions 6 * while remaining structurally compatible at runtime. 7 */ 8 9// Primitives 10export type LexNull = { 11 type: "null"; 12 description?: string; 13}; 14 15export type LexBoolean = { 16 type: "boolean"; 17 description?: string; 18 default?: boolean; 19 const?: boolean; 20}; 21 22export type LexInteger = { 23 type: "integer"; 24 description?: string; 25 default?: number; 26 minimum?: number; 27 maximum?: number; 28 enum?: number[]; 29 const?: number; 30}; 31 32export type LexString = { 33 type: "string"; 34 format?: string; 35 description?: string; 36 default?: string; 37 minLength?: number; 38 maxLength?: number; 39 minGraphemes?: number; 40 maxGraphemes?: number; 41 enum?: string[]; 42 const?: string; 43 knownValues?: string[]; 44}; 45 46export type LexUnknown = { 47 type: "unknown"; 48 description?: string; 49}; 50 51export type LexPrimitive = LexNull | LexBoolean | LexInteger | LexString | LexUnknown; 52 53// IPLD types 54export type LexBytes = { 55 type: "bytes"; 56 description?: string; 57 maxLength?: number; 58 minLength?: number; 59}; 60 61export type LexCidLink = { 62 type: "cid-link"; 63 description?: string; 64}; 65 66export type LexIpldType = LexBytes | LexCidLink; 67 68// References 69export type LexRef = { 70 type: "ref"; 71 description?: string; 72 ref: string; 73}; 74 75export type LexRefUnion = { 76 type: "union"; 77 description?: string; 78 refs: string[]; 79 closed?: boolean; 80}; 81 82export type LexRefVariant = LexRef | LexRefUnion; 83 84// Blobs 85export type LexBlob = { 86 type: "blob"; 87 description?: string; 88 accept?: string[]; 89 maxSize?: number; 90}; 91 92// Arrays 93export type LexArrayItem = LexPrimitive | LexIpldType | LexRefVariant | LexBlob; 94 95export type LexArray = { 96 type: "array"; 97 description?: string; 98 items: LexArrayItem; 99 minLength?: number; 100 maxLength?: number; 101}; 102 103// Objects - use a looser type for properties to avoid discriminated union issues 104export type LexObjectProperty = 105 | LexArray 106 | LexPrimitive 107 | LexIpldType 108 | LexRefVariant 109 | LexBlob 110 | LexObject; // Allow nested objects 111 112export type LexObject = { 113 type: "object"; 114 description?: string; 115 required?: string[]; 116 nullable?: string[]; 117 properties: Record<string, LexObjectProperty>; 118}; 119 120// Token 121export type LexToken = { 122 type: "token"; 123 description?: string; 124}; 125 126// XRPC types 127export type LexPrimitiveArray = { 128 type: "array"; 129 description?: string; 130 items: LexPrimitive; 131 minLength?: number; 132 maxLength?: number; 133}; 134 135export type LexXrpcParameterProperty = LexPrimitive | LexPrimitiveArray; 136 137export type LexXrpcParameters = { 138 type: "params"; 139 description?: string; 140 required?: string[]; 141 properties: Record<string, LexXrpcParameterProperty>; 142}; 143 144export type LexXrpcBody = { 145 description?: string; 146 encoding: string; 147 schema?: LexRefVariant | LexObject; 148}; 149 150export type LexXrpcSubscriptionMessage = { 151 description?: string; 152 schema?: LexRefVariant | LexObject; 153}; 154 155export type LexXrpcError = { 156 name: string; 157 description?: string; 158}; 159 160export type LexXrpcQuery = { 161 type: "query"; 162 description?: string; 163 parameters?: LexXrpcParameters; 164 output?: LexXrpcBody; 165 errors?: LexXrpcError[]; 166}; 167 168export type LexXrpcProcedure = { 169 type: "procedure"; 170 description?: string; 171 parameters?: LexXrpcParameters; 172 input?: LexXrpcBody; 173 output?: LexXrpcBody; 174 errors?: LexXrpcError[]; 175}; 176 177export type LexXrpcSubscription = { 178 type: "subscription"; 179 description?: string; 180 parameters?: LexXrpcParameters; 181 message?: LexXrpcSubscriptionMessage; 182 errors?: LexXrpcError[]; 183}; 184 185// Records 186export type LexRecord = { 187 type: "record"; 188 description?: string; 189 key?: string; 190 record: LexObject; 191}; 192 193// Union of all user-definable types 194export type LexUserType = 195 | LexRecord 196 | LexXrpcQuery 197 | LexXrpcProcedure 198 | LexXrpcSubscription 199 | LexBlob 200 | LexArray 201 | LexToken 202 | LexObject 203 | LexPrimitive 204 | LexIpldType; 205 206// Lexicon document 207export type LexiconDoc = { 208 lexicon: 1; 209 id: string; 210 revision?: number; 211 description?: string; 212 defs: Record<string, LexUserType>; 213}; 214 215// Helper type for objects that can have descriptions 216export type WithDescription<T> = T & { description?: string };