All files / src/lib types.ts

0% Statements 0/0
0% Branches 1/1
0% Functions 1/1
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183                                                                                                                                                                                                                                                                                                                                                                             
import type { RouteConfig } from '@hono/zod-openapi';
 
/**
 * The union type representing all standard HTTP status codes and a special code `-1`.
 */
export type StatusCode =
  | 100
  | 102
  | 103
  | 200
  | 201
  | 202
  | 203
  | 206
  | 207
  | 208
  | 226
  | 300
  | 301
  | 302
  | 303
  | 305
  | 306
  | 307
  | 308
  | 400
  | 401
  | 402
  | 403
  | 404
  | 405
  | 406
  | 407
  | 408
  | 409
  | 410
  | 411
  | 412
  | 413
  | 414
  | 415
  | 416
  | 417
  | 418
  | 421
  | 422
  | 423
  | 424
  | 425
  | 426
  | 428
  | 429
  | 431
  | 451
  | 500
  | 501
  | 502
  | 503
  | 504
  | 505
  | 506
  | 507
  | 508
  | 510
  | 511
  | -1;
 
/**
 * The `ResponseConfig | ReferenceObject` provided by @hono/zod-openapi.
 */
export type ResponsesEntry = NonNullable<RouteConfig['responses']>[StatusCode];
/**
 * The type representing user-defined responses configuration.
 */
export type ResponsesConfig = Partial<Record<StatusCode, ResponsesEntry>>;
/**
 * The type representing user-defined status codes extracted from the user-defined responses configuration.
 *
 * @template M - The user-defined status codes type (M extends ResponsesConfig).
 * @extends {ResponsesConfig}
 */
export type UserDefinedStatusCode<M extends ResponsesConfig> = Extract<StatusCode, keyof M>;
 
/**
 * The type that identifies duplicate elements in a tuple. \
 * If there are no duplicates, it returns an empty tuple.
 *
 * @template Elm - The type of elements in the tuple (Elm extends UserDefinedStatusCode<ResponsesConfig>).
 * @extends {UserDefinedStatusCode<ResponsesConfig>}
 * @template Arr - The tuple type to check for duplicates (Arr extends Readonly<Elm[]>).
 * @extends {Readonly<Elm[]>}
 * @template Seen - The tuple type that keeps track of seen elements (default is an empty tuple).
 * @extends {Readonly<Elm[]>}
 * @template Duplication - The tuple type that accumulates duplicate elements (default is an empty tuple).
 * @extends {Readonly<Elm[]>}
 */
export type DuplicateStatusCode<
  Elm extends UserDefinedStatusCode<ResponsesConfig>,
  Arr extends Readonly<Elm[]>,
  Seen extends Readonly<Elm[]> = [],
  Duplication extends Readonly<Elm[]> = []
> = Arr extends Readonly<[infer Head extends Elm, ...infer Tail extends Elm[]]>
  ? Head extends Seen[number]
    ? DuplicateStatusCode<Elm, Tail, Seen, [...Duplication, Head]>
    : DuplicateStatusCode<Elm, Tail, [...Seen, Head], Duplication>
  : Duplication;
 
/**
 * The type that checks for duplicates in a tuple. \
 * If duplicates are found, it returns `never`; otherwise, it returns `Arr`.
 *
 * @template Elm - The type of elements in the tuple (Elm extends UserDefinedStatusCode<ResponsesConfig>).
 * @extends {UserDefinedStatusCode<ResponsesConfig>}
 * @template Arr - The tuple type to check for uniqueness (Arr extends Readonly<Elm[]>).
 * @extends {Readonly<Elm[]>}
 * @template Seen - The tuple type that keeps track of seen elements (default is an empty tuple).
 * @extends {Readonly<Elm[]>}
 */
export type UniqueTuple<
  Elm extends UserDefinedStatusCode<ResponsesConfig>,
  Arr extends Readonly<Elm[]>,
  Seen extends Readonly<Elm[]> = []
> = Arr extends Readonly<[infer Head extends Elm, ...infer Tail extends Elm[]]>
  ? Head extends Seen[number]
    ? never
    : Readonly<[Head, ...UniqueTuple<Elm, Tail, [...Seen, Head]>]>
  : Arr;
 
/**
 * The type that if Elm satisfies `Elm extends never`, it returns zod-openapi-share defined error type (`{ __error: 'Status codes have to be unique.'; __duplicate_status_codes: DuplicateStatusCode<Elm, T>;}`); otherwise, it returns `Arr`.
 *
 * @template Elm - The type of elements in the tuple (Elm extends UserDefinedStatusCode<ResponsesConfig>).
 * @extends {UserDefinedStatusCode<ResponsesConfig>}
 * @template T - The tuple type to check for uniqueness (T extends Readonly<Elm[]>).
 * @extends {Readonly<Elm[]>}
 */
export type NeverWrapper<Elm extends UserDefinedStatusCode<ResponsesConfig>, T extends Readonly<Elm[]>> = UniqueTuple<
  Elm,
  T
> extends never
  ? {
      __error: 'Status codes have to be unique.';
      __duplicate_status_codes: DuplicateStatusCode<Elm, T>;
    }
  : UniqueTuple<Elm, T>;
 
/**
 * The type that merges the `responses` property of a route config with user-defined status codes.
 *
 * @template R - The route config type (R extends RouteConfig).
 * @extends {RouteConfig}
 * @template M - The user-defined status codes type (M extends ResponsesConfig).
 * @extends {ResponsesConfig}
 * @template T - The tuple type of user-defined status codes (T extends Readonly<UserDefinedStatusCode<M>[]>).
 * @extends {Readonly<UserDefinedStatusCode<M>[]>}
 */
export type MergeRouteResponses<
  R extends RouteConfig,
  M extends ResponsesConfig,
  T extends Readonly<UserDefinedStatusCode<M>[]>
> = Omit<R, 'responses'> & {
  responses: NonNullable<R['responses']> & Pick<M, T[number]>;
};
 
/**
 * The interface that defines the methods of createOpenAPISchema class.
 *
 * @template M - The user-defined status codes type (M extends ResponsesConfig).
 * @extends {ResponsesConfig}
 *
 * @template T - The tuple type of user-defined status codes (T extends Readonly<UserDefinedStatusCode<M>[]>).
 * @extends {Readonly<UserDefinedStatusCode<M>[]>}
 */
export type CreateSchemaInterface<M extends ResponsesConfig> = {
  // `statusCodes` argument not included
  createSchema<R extends RouteConfig>(route: R): R;
  // `statusCodes` argument included
  createSchema<R extends RouteConfig, const T extends Readonly<UserDefinedStatusCode<M>[]>>(
    route: R,
    statusCodes: NeverWrapper<UserDefinedStatusCode<M>, T>
  ): MergeRouteResponses<R, M, T>;
};