Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

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

at 557ff54b2b435e5f1e789c6a8a4e1bebf2d7deb6 178 lines 5.9 kB view raw
1/** 2 * @fileoverview These types help with typing JSON schemas. They're all copied 3 * from AJV v7 (https://github.com/ajv-validator/ajv/blob/master/lib/types/json-schema.ts), 4 * but then **modified for JSON Schema draft 4's format** where needed. 5 */ 6 7// These types mostly come from the Ajv package and are just meant to be flexible 8// to generate TS types from JSON Schema values, so it's fine for them to have `any`s. 9/* eslint-disable @typescript-eslint/no-explicit-any */ 10 11type UnionToIntersection<U> = (U extends any ? (_: U) => void : never) extends ( 12 _: infer I, 13) => void 14 ? I 15 : never; 16 17export type SomeJSONSchema = UncheckedJSONSchemaType<JSON, true>; 18 19export type PartialSchema<T> = Partial<UncheckedJSONSchemaType<T, true>>; 20 21type JSONType< 22 T extends string, 23 IsPartial extends boolean, 24> = IsPartial extends true ? T | undefined : T; 25 26interface NumberKeywords { 27 minimum?: number; 28 maximum?: number; 29 // In JSON Schema draft 6, exclusiveMinimum and exclusiveMaximum are numbers. 30 // But, for draft 4, they are bools that change the interpretation of max/min. 31 exclusiveMinimum?: boolean; 32 exclusiveMaximum?: boolean; 33 multipleOf?: number; 34 format?: string; 35} 36 37interface StringKeywords { 38 minLength?: number; 39 maxLength?: number; 40 pattern?: string; 41 format?: string; 42} 43 44type UncheckedJSONSchemaType<T, IsPartial extends boolean> = ( 45 | // these two unions allow arbitrary unions of types 46 { 47 anyOf: readonly UncheckedJSONSchemaType<T, IsPartial>[]; 48 } 49 | { 50 oneOf: readonly UncheckedJSONSchemaType<T, IsPartial>[]; 51 } 52 // this union allows for { type: (primitive)[] } style schemas 53 | ({ 54 type: readonly (T extends number 55 ? JSONType<'number' | 'integer', IsPartial> 56 : T extends string 57 ? JSONType<'string', IsPartial> 58 : T extends boolean 59 ? JSONType<'boolean', IsPartial> 60 : T extends null 61 ? JSONType<'null', IsPartial> 62 : never)[]; 63 } & UnionToIntersection< 64 T extends number 65 ? NumberKeywords 66 : T extends string 67 ? StringKeywords 68 : T extends boolean 69 ? // eslint-disable-next-line @typescript-eslint/no-restricted-types 70 {} 71 : never 72 >) 73 // this covers "normal" types; it's last so typescript looks to it first for errors 74 | ((T extends number 75 ? { 76 type: JSONType<'number' | 'integer', IsPartial>; 77 } & NumberKeywords 78 : T extends string 79 ? { 80 type: JSONType<'string', IsPartial>; 81 } & StringKeywords 82 : T extends boolean 83 ? { 84 type: JSONType<'boolean', IsPartial>; 85 } 86 : T extends readonly [any, ...any[]] 87 ? { 88 // JSON AnySchema for tuple 89 type: JSONType<'array', IsPartial>; 90 items: { 91 readonly [K in keyof T]-?: UncheckedJSONSchemaType<T[K], false> & 92 Nullable<T[K]>; 93 } & { length: T['length'] }; 94 minItems: T['length']; 95 } & ({ maxItems: T['length'] } | { additionalItems: false }) 96 : T extends readonly any[] 97 ? { 98 type: JSONType<'array', IsPartial>; 99 items: UncheckedJSONSchemaType<T[0], false>; 100 minItems?: number; 101 maxItems?: number; 102 uniqueItems?: true; 103 additionalItems?: never; 104 } 105 : T extends Record<string, any> 106 ? { 107 // JSON AnySchema for records and dictionaries 108 // "required" is not optional because it is often forgotten 109 // "properties" are optional for more concise dictionary schemas 110 // "patternProperties" and can be only used with interfaces that have string index 111 type: JSONType<'object', IsPartial>; 112 additionalProperties?: 113 | boolean 114 | UncheckedJSONSchemaType<T[string], false>; 115 properties?: IsPartial extends true 116 ? Partial<PropertiesSchema<T>> 117 : PropertiesSchema<T>; 118 patternProperties?: Record< 119 string, 120 UncheckedJSONSchemaType<T[string], false> 121 >; 122 dependencies?: { 123 [K in keyof T]?: Readonly<(keyof T)[]> | PartialSchema<T>; 124 }; 125 dependentSchemas?: { [K in keyof T]?: PartialSchema<T> }; 126 minProperties?: number; 127 maxProperties?: number; 128 } & (IsPartial extends true // "required" is not necessary if it's a non-partial type with no required keys // are listed it only asserts that optional cannot be listed. // "required" type does not guarantee that all required properties 129 ? { required: Readonly<(keyof T)[]> } 130 : [RequiredMembers<T>] extends [never] 131 ? { required?: Readonly<RequiredMembers<T>[]> } 132 : { required: Readonly<RequiredMembers<T>[]> }) 133 : T extends null 134 ? { type: JSONType<'null', IsPartial> } 135 : never) & { 136 allOf?: Readonly<PartialSchema<T>[]>; 137 anyOf?: Readonly<PartialSchema<T>[]>; 138 oneOf?: Readonly<PartialSchema<T>[]>; 139 not?: PartialSchema<T>; 140 }) 141) & { 142 [keyword: string]: any; 143 id?: string; // was not $id until draft 6. 144 $ref?: string; 145 definitions?: Record<string, UncheckedJSONSchemaType<JSON, true>>; 146}; 147 148export type JSONSchemaV4<T> = UncheckedJSONSchemaType<T, false>; 149 150export type JSON = 151 | { [key: string]: JSON } 152 | JSON[] 153 | number 154 | string 155 | boolean 156 | null; 157 158export type PropertiesSchema<T> = { 159 [K in keyof T]-?: 160 | (UncheckedJSONSchemaType<T[K], false> & Nullable<T[K]>) 161 | { $ref: string }; 162}; 163 164export type RequiredMembers<T> = { 165 [K in keyof T]-?: undefined extends T[K] ? never : K; 166}[keyof T]; 167 168type Nullable<T> = undefined extends T 169 ? { 170 enum?: Readonly<(T | null)[]>; // `null` must be explicitly included in "enum" for `null` to pass 171 default?: T | null; 172 } 173 : { 174 enum?: Readonly<T[]>; 175 default?: T; 176 }; 177 178/* eslint-enable @typescript-eslint/no-explicit-any */