Suite of AT Protocol TypeScript libraries built on web standards
21
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: explicit types in lex

+368 -99
+3 -1
lex/core/result.ts
··· 23 23 return failure(new Error("Unknown error", { cause: err })); 24 24 } 25 25 26 - export function createCatcher<T>(Ctor: new (...args: any[]) => T) { 26 + export function createCatcher<T>( 27 + Ctor: new (...args: any[]) => T, 28 + ): (err: unknown) => ResultFailure<T> { 27 29 return (err: unknown): ResultFailure<T> => { 28 30 if (err instanceof Ctor) return failure(err); 29 31 throw err;
+13 -1
lex/core/string-format.ts
··· 24 24 export type UriString = `${string}:${string}`; 25 25 export type LanguageString = string; 26 26 27 - export const STRING_FORMATS = Object.freeze( 27 + export const STRING_FORMATS: readonly [ 28 + "datetime", 29 + "uri", 30 + "at-uri", 31 + "did", 32 + "handle", 33 + "at-identifier", 34 + "nsid", 35 + "cid", 36 + "language", 37 + "tid", 38 + "record-key", 39 + ] = Object.freeze( 28 40 [ 29 41 "datetime", 30 42 "uri",
+228 -37
lex/document/lexicon.ts
··· 1 1 import { l } from "../mod.ts"; 2 2 3 - const bool = l.boolean(); 4 - const int = l.integer(); 5 - const str = l.string(); 3 + const bool: l.BooleanSchema = l.boolean(); 4 + const int: l.IntegerSchema = l.integer(); 5 + const str: l.StringSchema<NonNullable<unknown>> = l.string(); 6 6 7 - const boolOpt = l.optional(bool); 8 - const intOpt = l.optional(int); 9 - const strOpt = l.optional(str); 7 + const boolOpt: l.OptionalSchema<boolean> = l.optional(bool); 8 + const intOpt: l.OptionalSchema<number> = l.optional(int); 9 + const strOpt: l.OptionalSchema<string> = l.optional(str); 10 10 11 - const strArrOpt = l.optional(l.array(str)); 11 + const strArrOpt: l.OptionalSchema<string[]> = l.optional(l.array(str)); 12 12 13 - export const lexiconBooleanSchema = l.object({ 13 + export const lexiconBooleanSchema: l.ObjectSchema<{ 14 + type: l.LiteralSchema<"boolean">; 15 + default: typeof boolOpt; 16 + const: typeof boolOpt; 17 + description: typeof strOpt; 18 + }> = l.object({ 14 19 type: l.literal("boolean"), 15 20 default: boolOpt, 16 21 const: boolOpt, ··· 18 23 }); 19 24 export type LexiconBoolean = l.Infer<typeof lexiconBooleanSchema>; 20 25 21 - export const lexiconIntegerSchema = l.object({ 26 + export const lexiconIntegerSchema: l.ObjectSchema<{ 27 + type: l.LiteralSchema<"integer">; 28 + default: typeof intOpt; 29 + minimum: typeof intOpt; 30 + maximum: typeof intOpt; 31 + enum: l.OptionalSchema<l.Infer<typeof int>[]>; 32 + const: typeof intOpt; 33 + description: typeof strOpt; 34 + }> = l.object({ 22 35 type: l.literal("integer"), 23 36 default: intOpt, 24 37 minimum: intOpt, ··· 29 42 }); 30 43 export type LexiconInteger = l.Infer<typeof lexiconIntegerSchema>; 31 44 32 - export const lexiconStringSchema = l.object({ 45 + export const lexiconStringSchema: l.ObjectSchema<{ 46 + type: l.LiteralSchema<"string">; 47 + format: l.OptionalSchema<l.StringFormat>; 48 + default: typeof strOpt; 49 + minLength: typeof intOpt; 50 + maxLength: typeof intOpt; 51 + minGraphemes: typeof intOpt; 52 + maxGraphemes: typeof intOpt; 53 + enum: typeof strArrOpt; 54 + const: typeof strOpt; 55 + knownValues: typeof strArrOpt; 56 + description: typeof strOpt; 57 + }> = l.object({ 33 58 type: l.literal("string"), 34 59 format: l.optional(l.enum<l.StringFormat>(l.STRING_FORMATS)), 35 60 default: strOpt, ··· 44 69 }); 45 70 export type LexiconString = l.Infer<typeof lexiconStringSchema>; 46 71 47 - export const lexiconBytesSchema = l.object({ 72 + export const lexiconBytesSchema: l.ObjectSchema<{ 73 + type: l.LiteralSchema<"bytes">; 74 + maxLength: typeof intOpt; 75 + minLength: typeof intOpt; 76 + description: typeof strOpt; 77 + }> = l.object({ 48 78 type: l.literal("bytes"), 49 79 maxLength: intOpt, 50 80 minLength: intOpt, ··· 52 82 }); 53 83 export type LexiconBytes = l.Infer<typeof lexiconBytesSchema>; 54 84 55 - export const lexiconCidLinkSchema = l.object({ 85 + export const lexiconCidLinkSchema: l.ObjectSchema<{ 86 + type: l.LiteralSchema<"cid-link">; 87 + description: typeof strOpt; 88 + }> = l.object({ 56 89 type: l.literal("cid-link"), 57 90 description: strOpt, 58 91 }); 59 92 export type LexiconCid = l.Infer<typeof lexiconCidLinkSchema>; 60 93 61 - export const lexiconBlobSchema = l.object({ 94 + export const lexiconBlobSchema: l.ObjectSchema<{ 95 + type: l.LiteralSchema<"blob">; 96 + accept: typeof strArrOpt; 97 + maxSize: typeof intOpt; 98 + description: typeof strOpt; 99 + }> = l.object({ 62 100 type: l.literal("blob"), 63 101 accept: strArrOpt, 64 102 maxSize: intOpt, ··· 75 113 lexiconBlobSchema, 76 114 ] as const; 77 115 78 - export const lexiconUnknownSchema = l.object({ 116 + export const lexiconUnknownSchema: l.ObjectSchema<{ 117 + type: l.LiteralSchema<"unknown">; 118 + description: typeof strOpt; 119 + }> = l.object({ 79 120 type: l.literal("unknown"), 80 121 description: strOpt, 81 122 }); 82 123 export type LexiconUnknown = l.Infer<typeof lexiconUnknownSchema>; 83 124 84 - export const lexiconTokenSchema = l.object({ 125 + export const lexiconTokenSchema: l.ObjectSchema<{ 126 + type: l.LiteralSchema<"token">; 127 + description: typeof strOpt; 128 + }> = l.object({ 85 129 type: l.literal("token"), 86 130 description: strOpt, 87 131 }); 88 132 export type LexiconToken = l.Infer<typeof lexiconTokenSchema>; 89 133 90 - export const lexiconRefSchema = l.object({ 134 + export const lexiconRefSchema: l.ObjectSchema<{ 135 + type: l.LiteralSchema<"ref">; 136 + ref: typeof str; 137 + description: typeof strOpt; 138 + }> = l.object({ 91 139 type: l.literal("ref"), 92 140 ref: str, 93 141 description: strOpt, 94 142 }); 95 143 export type LexiconRef = l.Infer<typeof lexiconRefSchema>; 96 144 97 - export const lexiconRefUnionSchema = l.object({ 145 + export const lexiconRefUnionSchema: l.ObjectSchema<{ 146 + type: l.LiteralSchema<"union">; 147 + refs: l.ArraySchema<typeof str>; 148 + closed: typeof boolOpt; 149 + description: typeof strOpt; 150 + }> = l.object({ 98 151 type: l.literal("union"), 99 152 refs: l.array(str), 100 153 closed: boolOpt, ··· 111 164 112 165 export type LexiconArrayItems = l.Infer<(typeof ARRAY_ITEMS_SCHEMAS)[number]>; 113 166 114 - export const lexiconArraySchema = l.object({ 167 + export const lexiconArraySchema: l.ObjectSchema<{ 168 + type: l.LiteralSchema<"array">; 169 + items: l.DiscriminatedUnionSchema<"type", typeof ARRAY_ITEMS_SCHEMAS>; 170 + minLength: typeof intOpt; 171 + maxLength: typeof intOpt; 172 + description: typeof strOpt; 173 + }> = l.object({ 115 174 type: l.literal("array"), 116 175 items: l.discriminatedUnion("type", ARRAY_ITEMS_SCHEMAS), 117 176 minLength: intOpt, ··· 129 188 path: "required", 130 189 }; 131 190 132 - export const lexiconObjectSchema = l.refine( 191 + export const lexiconObjectSchema: l.ObjectSchema<{ 192 + type: l.LiteralSchema<"object">; 193 + properties: l.DictSchema< 194 + typeof str, 195 + l.DiscriminatedUnionSchema< 196 + "type", 197 + readonly [...typeof ARRAY_ITEMS_SCHEMAS, typeof lexiconArraySchema] 198 + > 199 + >; 200 + required: typeof strArrOpt; 201 + nullable: typeof strArrOpt; 202 + description: typeof strOpt; 203 + }> = l.refine( 133 204 l.object({ 134 205 type: l.literal("object"), 135 206 properties: l.dict( ··· 147 218 ); 148 219 export type LexiconObject = l.Infer<typeof lexiconObjectSchema>; 149 220 150 - export const lexiconRecordKeySchema = l.custom( 151 - l.isLexiconRecordKey, 152 - 'Invalid record key definition (must be "any", "nsid", "tid", or "literal:<string>")', 153 - ); 221 + export const lexiconRecordKeySchema: l.CustomSchema<l.LexiconRecordKey> = l 222 + .custom( 223 + l.isLexiconRecordKey, 224 + 'Invalid record key definition (must be "any", "nsid", "tid", or "literal:<string>")', 225 + ); 154 226 export type LexiconRecordKey = l.LexiconRecordKey; 155 227 156 - export const lexiconRecordSchema = l.object({ 228 + export const lexiconRecordSchema: l.ObjectSchema<{ 229 + type: l.LiteralSchema<"record">; 230 + record: typeof lexiconObjectSchema; 231 + description: typeof strOpt; 232 + key: typeof lexiconRecordKeySchema; 233 + }> = l.object({ 157 234 type: l.literal("record"), 158 235 record: lexiconObjectSchema, 159 236 description: strOpt, ··· 161 238 }); 162 239 export type LexiconRecord = l.Infer<typeof lexiconRecordSchema>; 163 240 164 - export const lexiconParameters = l.refine( 241 + export const lexiconParameters: l.ObjectSchema<{ 242 + type: l.LiteralSchema<"params">; 243 + properties: l.DictSchema< 244 + typeof str, 245 + l.DiscriminatedUnionSchema< 246 + "type", 247 + readonly [ 248 + typeof lexiconBooleanSchema, 249 + typeof lexiconIntegerSchema, 250 + typeof lexiconStringSchema, 251 + l.ObjectSchema<{ 252 + type: l.LiteralSchema<"array">; 253 + items: l.DiscriminatedUnionSchema< 254 + "type", 255 + readonly [ 256 + typeof lexiconBooleanSchema, 257 + typeof lexiconIntegerSchema, 258 + typeof lexiconStringSchema, 259 + ] 260 + >; 261 + minLength: typeof intOpt; 262 + maxLength: typeof intOpt; 263 + description: typeof strOpt; 264 + }>, 265 + ] 266 + > 267 + >; 268 + required: typeof strArrOpt; 269 + description: typeof strOpt; 270 + }> = l.refine( 165 271 l.object({ 166 272 type: l.literal("params"), 167 273 properties: l.dict( ··· 190 296 ); 191 297 export type LexiconParameters = l.Infer<typeof lexiconParameters>; 192 298 193 - export const lexiconPayload = l.object({ 299 + export const lexiconPayload: l.ObjectSchema<{ 300 + encoding: typeof str; 301 + schema: l.OptionalSchema< 302 + l.Infer< 303 + l.DiscriminatedUnionSchema< 304 + "type", 305 + readonly [ 306 + typeof lexiconRefSchema, 307 + typeof lexiconRefUnionSchema, 308 + typeof lexiconObjectSchema, 309 + ] 310 + > 311 + > 312 + >; 313 + description: typeof strOpt; 314 + }> = l.object({ 194 315 encoding: str, 195 316 schema: l.optional( 196 317 l.discriminatedUnion("type", [ ··· 203 324 }); 204 325 export type LexiconPayload = l.Infer<typeof lexiconPayload>; 205 326 206 - export const lexiconSubscriptionMessage = l.object({ 327 + export const lexiconSubscriptionMessage: l.ObjectSchema<{ 328 + description: typeof strOpt; 329 + schema: l.OptionalSchema< 330 + l.Infer< 331 + l.DiscriminatedUnionSchema< 332 + "type", 333 + readonly [ 334 + typeof lexiconRefSchema, 335 + typeof lexiconRefUnionSchema, 336 + typeof lexiconObjectSchema, 337 + ] 338 + > 339 + > 340 + >; 341 + }> = l.object({ 207 342 description: strOpt, 208 343 schema: l.optional( 209 344 l.discriminatedUnion("type", [ ··· 217 352 typeof lexiconSubscriptionMessage 218 353 >; 219 354 220 - export const lexiconError = l.object({ 355 + export const lexiconError: l.ObjectSchema<{ 356 + name: l.StringSchema<{ minLength: 1 }>; 357 + description: typeof strOpt; 358 + }> = l.object({ 221 359 name: l.string({ minLength: 1 }), 222 360 description: strOpt, 223 361 }); 224 362 export type LexiconError = l.Infer<typeof lexiconError>; 225 363 226 - export const lexiconQuerySchema = l.object({ 364 + export const lexiconQuerySchema: l.ObjectSchema<{ 365 + type: l.LiteralSchema<"query">; 366 + parameters: l.OptionalSchema<l.Infer<typeof lexiconParameters>>; 367 + output: l.OptionalSchema<l.Infer<typeof lexiconPayload>>; 368 + errors: l.OptionalSchema<l.Infer<typeof lexiconError>[]>; 369 + description: typeof strOpt; 370 + }> = l.object({ 227 371 type: l.literal("query"), 228 372 parameters: l.optional(lexiconParameters), 229 373 output: l.optional(lexiconPayload), ··· 232 376 }); 233 377 export type LexiconQuery = l.Infer<typeof lexiconQuerySchema>; 234 378 235 - export const lexiconProcedureSchema = l.object({ 379 + export const lexiconProcedureSchema: l.ObjectSchema<{ 380 + type: l.LiteralSchema<"procedure">; 381 + parameters: l.OptionalSchema<l.Infer<typeof lexiconParameters>>; 382 + input: l.OptionalSchema<l.Infer<typeof lexiconPayload>>; 383 + output: l.OptionalSchema<l.Infer<typeof lexiconPayload>>; 384 + errors: l.OptionalSchema<l.Infer<typeof lexiconError>[]>; 385 + description: typeof strOpt; 386 + }> = l.object({ 236 387 type: l.literal("procedure"), 237 388 parameters: l.optional(lexiconParameters), 238 389 input: l.optional(lexiconPayload), ··· 242 393 }); 243 394 export type LexiconProcedure = l.Infer<typeof lexiconProcedureSchema>; 244 395 245 - export const lexiconSubscriptionSchema = l.object({ 396 + export const lexiconSubscriptionSchema: l.ObjectSchema<{ 397 + type: l.LiteralSchema<"subscription">; 398 + description: typeof strOpt; 399 + parameters: l.OptionalSchema<l.Infer<typeof lexiconParameters>>; 400 + message: l.OptionalSchema<l.Infer<typeof lexiconSubscriptionMessage>>; 401 + errors: l.OptionalSchema<l.Infer<typeof lexiconError>[]>; 402 + }> = l.object({ 246 403 type: l.literal("subscription"), 247 404 description: strOpt, 248 405 parameters: l.optional(lexiconParameters), ··· 251 408 }); 252 409 export type LexiconSubscription = l.Infer<typeof lexiconSubscriptionSchema>; 253 410 254 - const lexiconLanguageSchema = l.string({ format: "language" }); 411 + const lexiconLanguageSchema: l.StringSchema<{ format: "language" }> = l.string({ 412 + format: "language", 413 + }); 255 414 export type LexiconLanguage = l.Infer<typeof lexiconLanguageSchema>; 256 415 257 - const lexiconLanguageDict = l.dict(lexiconLanguageSchema, str); 416 + const lexiconLanguageDict: l.DictSchema< 417 + typeof lexiconLanguageSchema, 418 + typeof str 419 + > = l.dict(lexiconLanguageSchema, str); 258 420 export type LexiconLanguageDict = l.Infer<typeof lexiconLanguageDict>; 259 421 260 - const lexiconPermissionSchema = l.intersection( 422 + const lexiconPermissionSchema: l.IntersectionSchema< 423 + l.ObjectSchema<{ 424 + type: l.LiteralSchema<"permission">; 425 + resource: l.StringSchema<{ minLength: 1 }>; 426 + }>, 427 + l.DictSchema<l.StringSchema<NonNullable<unknown>>, l.UnknownSchema> 428 + > = l.intersection( 261 429 l.object({ 262 430 type: l.literal("permission"), 263 431 resource: l.string({ minLength: 1 }), ··· 266 434 ); 267 435 export type LexiconPermission = l.Infer<typeof lexiconPermissionSchema>; 268 436 269 - const lexiconPermissionSetSchema = l.object({ 437 + const lexiconPermissionSetSchema: l.ObjectSchema<{ 438 + type: l.LiteralSchema<"permission-set">; 439 + permissions: l.ArraySchema<typeof lexiconPermissionSchema>; 440 + title: typeof strOpt; 441 + "title:lang": l.OptionalSchema<l.Infer<typeof lexiconLanguageDict>>; 442 + detail: typeof strOpt; 443 + "detail:lang": l.OptionalSchema<l.Infer<typeof lexiconLanguageDict>>; 444 + description: typeof strOpt; 445 + }> = l.object({ 270 446 type: l.literal("permission-set"), 271 447 permissions: l.array(lexiconPermissionSchema), 272 448 title: strOpt, ··· 301 477 (typeof MAIN_LEXICON_SCHEMAS)[number] 302 478 >; 303 479 304 - export const lexiconIdentifierSchema = l.string({ format: "nsid" }); 480 + export const lexiconIdentifierSchema: l.StringSchema<{ format: "nsid" }> = l 481 + .string({ format: "nsid" }); 305 482 export type LexiconIdentifier = l.Infer<typeof lexiconIdentifierSchema>; 306 483 307 - export const lexiconDocumentSchema = l.object({ 484 + export const lexiconDocumentSchema: l.ObjectSchema<{ 485 + lexicon: l.LiteralSchema<1>; 486 + id: typeof lexiconIdentifierSchema; 487 + revision: typeof intOpt; 488 + description: typeof strOpt; 489 + defs: l.IntersectionSchema< 490 + l.ObjectSchema<{ 491 + main: l.OptionalSchema<MainLexiconDefinition>; 492 + }>, 493 + l.DictSchema< 494 + l.StringSchema<{ minLength: 1 }>, 495 + l.DiscriminatedUnionSchema<"type", typeof NAMED_LEXICON_SCHEMAS> 496 + > 497 + >; 498 + }> = l.object({ 308 499 lexicon: l.literal(1), 309 500 id: lexiconIdentifierSchema, 310 501 revision: intOpt,
+70 -35
lex/external.ts
··· 142 142 M extends Procedure | Query | Subscription = Procedure | Query | Subscription, 143 143 > = M extends { errors: readonly (infer E extends string)[] } ? E : never; 144 144 145 - export function never() { 145 + export function never(): NeverSchema { 146 146 return new NeverSchema(); 147 147 } 148 148 149 - export function unknown() { 149 + export function unknown(): UnknownSchema { 150 150 return new UnknownSchema(); 151 151 } 152 152 153 - function _null() { 153 + function _null(): NullSchema { 154 154 return new NullSchema(); 155 155 } 156 156 export { _null as null }; ··· 158 158 export function literal<const V extends null | string | number | boolean>( 159 159 value: V, 160 160 options?: LiteralSchemaOptions<V>, 161 - ) { 161 + ): LiteralSchema<V> { 162 162 return new LiteralSchema<V>(value, options); 163 163 } 164 164 165 165 function _enum<const V extends null | string | number | boolean>( 166 166 values: readonly V[], 167 167 options?: EnumSchemaOptions<V>, 168 - ) { 168 + ): EnumSchema<V> { 169 169 return new EnumSchema<V>(values, options); 170 170 } 171 171 export { _enum as enum }; 172 172 173 - export function boolean(options?: BooleanSchemaOptions) { 173 + export function boolean(options?: BooleanSchemaOptions): BooleanSchema { 174 174 return new BooleanSchema(options ?? {}); 175 175 } 176 176 177 - export function integer(options?: IntegerSchemaOptions) { 177 + export function integer(options?: IntegerSchemaOptions): IntegerSchema { 178 178 return new IntegerSchema(options ?? {}); 179 179 } 180 180 181 - export function cidLink(options?: CidSchemaOptions) { 181 + export function cidLink(options?: CidSchemaOptions): CidSchema { 182 182 return new CidSchema(options ?? {}); 183 183 } 184 184 185 - export function bytes(options?: BytesSchemaOptions) { 185 + export function bytes(options?: BytesSchemaOptions): BytesSchema { 186 186 return new BytesSchema(options ?? {}); 187 187 } 188 188 189 189 export function blob<O extends BlobSchemaOptions = NonNullable<unknown>>( 190 190 options: O = {} as O, 191 - ) { 191 + ): BlobSchema<O> { 192 192 return new BlobSchema(options); 193 193 } 194 194 195 195 export function string< 196 196 const O extends StringSchemaOptions = NonNullable<unknown>, 197 - >(options: StringSchemaOptions & O = {} as O) { 197 + >(options: StringSchemaOptions & O = {} as O): StringSchema<O> { 198 198 return new StringSchema<O>(options); 199 199 } 200 200 201 - export function regexp<T extends string = string>(pattern: RegExp) { 201 + export function regexp<T extends string = string>( 202 + pattern: RegExp, 203 + ): RegexpSchema<T> { 202 204 return new RegexpSchema<T>(pattern); 203 205 } 204 206 ··· 213 215 export function array<const S extends Validator>( 214 216 items: S, 215 217 options?: ArraySchemaOptions, 216 - ) { 218 + ): ArraySchema<S> { 217 219 return new ArraySchema<S>(items, options ?? {}); 218 220 } 219 221 220 - export function object<const P extends ObjectSchemaShape>(properties: P) { 222 + export function object<const P extends ObjectSchemaShape>( 223 + properties: P, 224 + ): ObjectSchema<P> { 221 225 return new ObjectSchema<P>(properties); 222 226 } 223 227 224 228 export function dict< 225 229 const K extends Validator<string>, 226 230 const V extends Validator, 227 - >(key: K, value: V) { 231 + >(key: K, value: V): DictSchema<K, V> { 228 232 return new DictSchema<K, V>(key, value); 229 233 } 230 234 231 235 export type { UnknownObjectOutput as UnknownObject }; 232 236 233 - export function unknownObject() { 237 + export function unknownObject(): UnknownObjectSchema { 234 238 return new UnknownObjectSchema(); 235 239 } 236 240 237 - export function ref<T>(get: RefSchemaGetter<T>) { 241 + export function ref<T>(get: RefSchemaGetter<T>): RefSchema<T> { 238 242 return new RefSchema<T>(get); 239 243 } 240 244 ··· 242 246 assertion: CustomAssertion<T>, 243 247 message: string, 244 248 path?: PropertyKey | readonly PropertyKey[], 245 - ) { 249 + ): CustomSchema<T> { 246 250 return new CustomSchema<T>(assertion, message, path); 247 251 } 248 252 249 - export function nullable<const S extends Validator>(schema: S) { 253 + export function nullable<const S extends Validator>( 254 + schema: S, 255 + ): NullableSchema<Infer<S>> { 250 256 return new NullableSchema<Infer<S>>(schema); 251 257 } 252 258 253 - export function optional<const S extends Validator>(schema: S) { 259 + export function optional<const S extends Validator>( 260 + schema: S, 261 + ): OptionalSchema<Infer<S>> { 254 262 return new OptionalSchema<Infer<S>>(schema); 255 263 } 256 264 257 - export function union<const V extends UnionSchemaValidators>(validators: V) { 265 + export function union<const V extends UnionSchemaValidators>( 266 + validators: V, 267 + ): UnionSchema<V> { 258 268 return new UnionSchema<V>(validators); 259 269 } 260 270 261 271 export function intersection< 262 272 const Left extends ObjectSchema, 263 273 const Right extends DictSchema, 264 - >(left: Left, right: Right) { 274 + >(left: Left, right: Right): IntersectionSchema<Left, Right> { 265 275 return new IntersectionSchema<Left, Right>(left, right); 266 276 } 267 277 268 278 export function discriminatedUnion< 269 279 const Discriminator extends string, 270 280 const Options extends DiscriminatedUnionVariants<Discriminator>, 271 - >(discriminator: Discriminator, variants: Options) { 281 + >( 282 + discriminator: Discriminator, 283 + variants: Options, 284 + ): DiscriminatedUnionSchema<Discriminator, Options> { 272 285 return new DiscriminatedUnionSchema<Discriminator, Options>( 273 286 discriminator, 274 287 variants, ··· 278 291 export function token<const N extends NsidString, const H extends string>( 279 292 nsid: N, 280 293 hash: H, 281 - ) { 294 + ): TokenSchema<$Type<N, H>> { 282 295 return new TokenSchema($type(nsid, hash)); 283 296 } 284 297 285 298 export function typedRef<const V extends { $type?: string }>( 286 299 get: TypedRefGetter<V>, 287 - ) { 300 + ): TypedRefSchema<V> { 288 301 return new TypedRefSchema<V>(get); 289 302 } 290 303 291 304 export function typedUnion< 292 305 const R extends readonly TypedRefSchema[], 293 306 const C extends boolean, 294 - >(refs: R, closed: C) { 307 + >(refs: R, closed: C): TypedUnionSchema<R, C> { 295 308 return new TypedUnionSchema<R, C>(refs, closed); 296 309 } 297 310 ··· 342 355 343 356 export function params< 344 357 const P extends ParamsSchemaShape = NonNullable<unknown>, 345 - >(properties: P = {} as P) { 358 + >(properties: P = {} as P): ParamsSchema<P> { 346 359 return new ParamsSchema<P>(properties); 347 360 } 348 361 349 - export const paramsSchema = new ParamsSchema({}); 362 + export const paramsSchema: ParamsSchema<{}> = new ParamsSchema({}); 350 363 351 364 export function payload< 352 365 const E extends string | undefined = undefined, 353 366 const S extends PayloadBody<E> = undefined, 354 - >(encoding: E = undefined as E, schema: S = undefined as S) { 367 + >( 368 + encoding: E = undefined as E, 369 + schema: S = undefined as S, 370 + ): Payload<E, S> { 355 371 return new Payload<E, S>(encoding, schema); 356 372 } 357 373 358 - export function jsonPayload<const P extends ObjectSchemaShape>(properties: P) { 374 + export function jsonPayload<const P extends ObjectSchemaShape>( 375 + properties: P, 376 + ): Payload<"application/json", ObjectSchema<P>> { 359 377 return payload("application/json", object(properties)); 360 378 } 361 379 ··· 364 382 const P extends ParamsSchema, 365 383 const O extends Payload, 366 384 const E extends undefined | readonly string[] = undefined, 367 - >(nsid: N, parameters: P, output: O, errors: E = undefined as E) { 385 + >( 386 + nsid: N, 387 + parameters: P, 388 + output: O, 389 + errors: E = undefined as E, 390 + ): Query<N, P, O, E> { 368 391 return new Query<N, P, O, E>(nsid, parameters, output, errors); 369 392 } 370 393 ··· 380 403 input: I, 381 404 output: O, 382 405 errors: E = undefined as E, 383 - ) { 406 + ): Procedure<N, P, I, O, E> { 384 407 return new Procedure<N, P, I, O, E>(nsid, parameters, input, output, errors); 385 408 } 386 409 ··· 393 416 | TypedUnionSchema 394 417 | ObjectSchema, 395 418 const E extends undefined | readonly string[] = undefined, 396 - >(nsid: N, parameters: P, message: M, errors: E = undefined as E) { 419 + >( 420 + nsid: N, 421 + parameters: P, 422 + message: M, 423 + errors: E = undefined as E, 424 + ): Subscription<N, P, M, E> { 397 425 return new Subscription<N, P, M, E>(nsid, parameters, message, errors); 398 426 } 399 427 400 428 export function permission< 401 429 const R extends string, 402 430 const O extends PermissionOptions, 403 - >(resource: R, options: PermissionOptions & O = {} as O) { 431 + >( 432 + resource: R, 433 + options: PermissionOptions & O = {} as O, 434 + ): Permission<R, O> { 404 435 return new Permission<R, O>(resource, options); 405 436 } 406 437 407 438 export function permissionSet< 408 439 const N extends NsidString, 409 440 const P extends readonly Permission[], 410 - >(nsid: N, permissions: P, options?: PermissionSetOptions) { 441 + >( 442 + nsid: N, 443 + permissions: P, 444 + options?: PermissionSetOptions, 445 + ): PermissionSet<N, P> { 411 446 return new PermissionSet<N, P>(nsid, permissions, options); 412 447 }
+17 -3
lex/schema/_parameters.ts
··· 7 7 import type { Infer, Validator } from "../validation.ts"; 8 8 9 9 export type ParamScalar = Infer<typeof paramScalarSchema>; 10 - const paramScalarSchema = new UnionSchema([ 10 + const paramScalarSchema: UnionSchema< 11 + readonly [ 12 + BooleanSchema, 13 + IntegerSchema, 14 + StringSchema<NonNullable<unknown>>, 15 + ] 16 + > = new UnionSchema([ 11 17 new BooleanSchema({}), 12 18 new IntegerSchema({}), 13 19 new StringSchema({}), 14 20 ]); 15 21 16 22 export type Param = Infer<typeof paramSchema>; 17 - export const paramSchema = new UnionSchema([ 23 + export const paramSchema: UnionSchema< 24 + readonly [ 25 + typeof paramScalarSchema, 26 + ArraySchema<typeof paramScalarSchema>, 27 + ] 28 + > = new UnionSchema([ 18 29 paramScalarSchema, 19 30 new ArraySchema(paramScalarSchema, {}), 20 31 ]); 21 32 22 33 export type Params = { [_: string]: undefined | Param }; 23 - export const paramsSchema = new DictSchema( 34 + export const paramsSchema: DictSchema< 35 + StringSchema<NonNullable<unknown>>, 36 + typeof paramSchema 37 + > = new DictSchema( 24 38 new StringSchema({}), 25 39 paramSchema, 26 40 ) satisfies Validator<Params>;
+6 -2
lex/schema/record.ts
··· 51 51 return { ...input, $type: this.$type }; 52 52 } 53 53 54 - $isTypeOf<X extends { $type?: unknown }>(value: X) { 54 + $isTypeOf<X extends { $type?: unknown }>( 55 + value: X, 56 + ): value is X extends { $type: T } ? X : X & { $type: T } { 55 57 return this.isTypeOf(value); 56 58 } 57 59 58 - $build<X extends Omit<Infer<S>, "$type">>(input: X) { 60 + $build<X extends Omit<Infer<S>, "$type">>( 61 + input: X, 62 + ): Simplify<Omit<X, "$type"> & { $type: T }> { 59 63 return this.build(input); 60 64 } 61 65
+6 -2
lex/schema/typed-object.ts
··· 36 36 return { ...input, $type: this.$type }; 37 37 } 38 38 39 - $isTypeOf<X extends Record<string, unknown>>(value: X) { 39 + $isTypeOf<X extends Record<string, unknown>>( 40 + value: X, 41 + ): value is X extends { $type?: T } ? X : X & { $type?: T } { 40 42 return this.isTypeOf(value); 41 43 } 42 44 43 - $build<X extends Omit<Infer<S>, "$type">>(input: X) { 45 + $build<X extends Omit<Infer<S>, "$type">>( 46 + input: X, 47 + ): Simplify<Omit<X, "$type"> & { $type: T }> { 44 48 return this.build<X>(input); 45 49 } 46 50
+1 -1
lex/schema/typed-union.ts
··· 44 44 return lazyProperty(this, "refsMap", map); 45 45 } 46 46 47 - get $types() { 47 + get $types(): TypedRefs[number]["$type"][] { 48 48 return Array.from(this.refsMap.keys()); 49 49 } 50 50
+7 -7
lex/validation/validation-issue.ts
··· 21 21 super("custom", path, input); 22 22 } 23 23 24 - toString() { 24 + toString(): string { 25 25 return `${this.message}${stringifyPath(this.path)}`; 26 26 } 27 27 } ··· 36 36 super("invalid_format", path, input); 37 37 } 38 38 39 - toString() { 39 + toString(): string { 40 40 return `Invalid ${this.formatDescription} format${ 41 41 this.message ? ` (${this.message})` : "" 42 42 }${stringifyPath(this.path)} (got ${stringifyValue(this.input)})`; ··· 71 71 super("invalid_type", path, input); 72 72 } 73 73 74 - toString() { 74 + toString(): string { 75 75 return `Expected ${ 76 76 oneOf(this.expected.map(stringifyExpectedType)) 77 77 } value type${stringifyPath(this.path)} (got ${stringifyType(this.input)})`; ··· 87 87 super("invalid_value", path, input); 88 88 } 89 89 90 - toString() { 90 + toString(): string { 91 91 return `Expected ${oneOf(this.values.map(stringifyValue))}${ 92 92 stringifyPath(this.path) 93 93 } (got ${stringifyValue(this.input)})`; ··· 103 103 super("required_key", path, input); 104 104 } 105 105 106 - toString() { 106 + toString(): string { 107 107 return `Missing required key "${String(this.key)}"${ 108 108 stringifyPath(this.path) 109 109 }`; ··· 129 129 super("too_big", path, input); 130 130 } 131 131 132 - toString() { 132 + toString(): string { 133 133 return `${this.type} too big (maximum ${this.maximum})${ 134 134 stringifyPath(this.path) 135 135 } (got ${this.actual})`; ··· 147 147 super("too_small", path, input); 148 148 } 149 149 150 - toString() { 150 + toString(): string { 151 151 return `${this.type} too small (minimum ${this.minimum})${ 152 152 stringifyPath(this.path) 153 153 } (got ${this.actual})`;
+17 -10
lex/validation/validator.ts
··· 61 61 this.currentPath = options?.path != null ? Array.from(options.path) : []; 62 62 } 63 63 64 - get path() { 64 + get path(): PropertyKey[] { 65 65 return Array.from(this.currentPath); 66 66 } 67 67 68 - concatPath(path?: PropertyKey | readonly PropertyKey[]) { 68 + concatPath(path?: PropertyKey | readonly PropertyKey[]): PropertyKey[] { 69 69 if (path == null) return this.path; 70 70 return this.currentPath.concat(path); 71 71 } ··· 114 114 return failure(new ValidationError([...this.issues, issue])); 115 115 } 116 116 117 - issueInvalidValue(input: unknown, values: readonly unknown[]) { 117 + issueInvalidValue( 118 + input: unknown, 119 + values: readonly unknown[], 120 + ): ValidationFailure { 118 121 return this.failure(new IssueInvalidValue(this.path, input, values)); 119 122 } 120 123 121 - issueInvalidType(input: unknown, expected: string) { 124 + issueInvalidType(input: unknown, expected: string): ValidationFailure { 122 125 return this.failure(new IssueInvalidType(this.path, input, [expected])); 123 126 } 124 127 125 - issueRequiredKey(input: object, key: PropertyKey) { 128 + issueRequiredKey(input: object, key: PropertyKey): ValidationFailure { 126 129 return this.failure(new IssueRequiredKey(this.path, input, key)); 127 130 } 128 131 129 - issueInvalidFormat(input: unknown, format: string, msg?: string) { 132 + issueInvalidFormat( 133 + input: unknown, 134 + format: string, 135 + msg?: string, 136 + ): ValidationFailure { 130 137 return this.failure( 131 138 new IssueInvalidFormat(this.path, input, format, msg), 132 139 ); ··· 137 144 type: MeasurableType, 138 145 max: number, 139 146 actual: number, 140 - ) { 147 + ): ValidationFailure { 141 148 return this.failure(new IssueTooBig(this.path, input, max, type, actual)); 142 149 } 143 150 ··· 146 153 type: MeasurableType, 147 154 min: number, 148 155 actual: number, 149 - ) { 156 + ): ValidationFailure { 150 157 return this.failure( 151 158 new IssueTooSmall(this.path, input, min, type, actual), 152 159 ); ··· 156 163 input: I, 157 164 property: keyof I & PropertyKey, 158 165 values: readonly unknown[], 159 - ) { 166 + ): ValidationFailure { 160 167 const value = input[property]; 161 168 const path = this.concatPath(property); 162 169 return this.failure(new IssueInvalidValue(path, value, values)); ··· 166 173 input: I, 167 174 property: keyof I & PropertyKey, 168 175 expected: string, 169 - ) { 176 + ): ValidationFailure { 170 177 const value = input[property]; 171 178 const path = this.concatPath(property); 172 179 return this.failure(new IssueInvalidType(path, value, [expected]));