eve-esi-types
Version:
Extracted the main type of ESI. use for ESI request response types (version 2 only)
423 lines (402 loc) • 16.9 kB
TypeScript
/*!
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Copyright (C) 2025 jeffy-g <hirotom1107@gmail.com>
// Released under the MIT license
// https://opensource.org/licenses/mit-license.php
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
/**
* THIS DTS IS AUTO GENERATED, DO NOT EDIT
*
* @file eve-esi-types/v2/experimental-esi-types.d.ts
* @summary This file is auto-generated and defines version 3.2.11 of the EVE Online ESI response types.
*/
import type {
Split,
UnionToTuple,
RestrictKeys,
_ESIResponseType,
ESIEntryExtraKeys,
PickPathParameters,
ExtractPathParamKeys,
CombineIntersection,
} from "./index.d.ts";
/**
* Resolves the final request-parameter shape and response type for an ESI endpoint,
* and indicates whether any parameters are actually required.
*
* @template M The HTTP method (e.g. `"get"`, `"post"`) of the request.
* @template EPx The endpoint path, constrained to `ESIEndpointOf<M>` or a string.
* @template Opt A record type of user-supplied options (e.g. query/body/path params).
* @template PathParams A record type representing the path-parameter properties.
* @template EntryWithParams
* By default, the merged type of the raw ESI response payload
* (`_ESIResponseType<M, EPx>`) and `PathParams`.
* @template RequireKeys
* The keys in `EntryWithParams` that represent actual request parameters,
* i.e. all keys minus the built-in ESI metadata (`result`, `tag`, `cachedSeconds`).
* @template FinalOpt
* The flattened intersection of:
* - the subset of `Opt` whose keys are in `RequireKeys`, and
* - a `Pick` of `EntryWithParams` over those same keys.
*
* @example
* ```ts
* // /characters/{character_id}/attributes/
* type ExampleEntry = {
* result: GetCharactersCharacterIdAttributesOk;
* tag: "Skills";
* cachedSeconds: 120;
* auth: true;
* };
* type ExampleOpt = { auth: true; token: string };
* type ExamplePath = { character_id: number };
*
* // Suppose _ESIResponseType<"get", "/characters/{character_id}/attributes/"> = ExampleEntry
* type Desc = ResolveEndpointRequest<
* "get",
* "/characters/{character_id}/attributes/",
* ExampleOpt,
* ExamplePath
* >;
* // Desc resolves to:
* // [
* // { auth: true; token: string; character_id: number; },
* // GetCharactersCharacterIdAttributesOk,
* // 1
* // ]
* ```
*
* @see {@link ESIEndpointOf}
* @see {@link _ESIResponseType}
*/
export type ResolveEndpointRequest<
M extends TESIEntryMethod,
EPx extends ESIEndpointOf<M> | string,
Opt extends Record<string, unknown>,
PathParams extends Record<string, unknown>,
EntryWithParams = _ESIResponseType<M, EPx> & PathParams,
RequireKeys extends keyof EntryWithParams = Exclude<keyof EntryWithParams, ESIEntryExtraKeys>,
FinalOpt = CombineIntersection< RestrictKeys<Opt, RequireKeys> & Pick<EntryWithParams, RequireKeys> >
> = [
[RequireKeys] extends [never] ? [FinalOpt?] : [FinalOpt],
EntryWithParams extends { result: infer R } ? R : never,
];
type TESIRequestFunctionContext<
Mtd extends TESIEntryMethod = TESIEntryMethod,
REP extends ReplacePathParams<ESIEndpointOf<Mtd>> | ESIEndpointOf<Mtd> = ReplacePathParams<ESIEndpointOf<Mtd>> | ESIEndpointOf<Mtd>,
ActualOpt extends Record<string, unknown> = Record<string, unknown>,
EPO extends ResolvedEndpoint<Mtd, REP> = ResolvedEndpoint<Mtd, REP>,
PPM extends InferPathParams<REP, EPO> = InferPathParams<REP, EPO>,
Opt extends IdentifyParameters<Mtd, EPO, ActualOpt, PPM> = IdentifyParameters<Mtd, EPO, ActualOpt, PPM>,
Ret extends InferESIResponseResult<Mtd, EPO> = InferESIResponseResult<Mtd, EPO>,
HasOpt = HasRequireParams<Mtd, EPO, PPM>,
> = {
method: Mtd; endpoint: REP;
} & (HasOpt extends 1 ? { options: Opt } : { options?: Opt }) & {
result?: Ret;
};
// - - - - - - - - - - - - - - - - - - - - - - - - - -
// TESIRequestFunctionWithContext
// - - - - - - - - - - - - - - - - - - - - - - - - - -
export type TESIRequestFunctionWithContext<
CTX extends TESIRequestFunctionContext,
Mtd extends TESIEntryMethod = CTX["method"],
// @ts-expect-error TODO: 2025/4/24
REP extends ReplacePathParams<ESIEndpointOf<Mtd>> | ESIEndpointOf<Mtd> = CTX["endpoint"],
ActualOpt extends Record<string, unknown> = CTX["options"]
> = (context: CTX) => Promise<NonNullable<CTX["result"]>>;
/**
* Infers the response result type of an ESI endpoint based on a union of HTTP method and endpoint.
*
* This utility type takes an endpoint union (`EPU`) in the format `${TESIEntryMethod}:${ESIEndpointAll}`
* and infers the response result type from the corresponding ESI response map.
*
* @template EPU A union of HTTP method and endpoint in the format `${TESIEntryMethod}:${ESIEndpointAll}`.
*
* @remarks
* This type uses advanced TypeScript features such as template literal types and conditional types
* to infer the response result type of a given ESI endpoint.
*
* @example
* ``` ts
* type ResponseResult = InferESIResponseResultFromUnion<"get:/characters/{character_id}/">;
* // Result: The inferred response result type for the given method and endpoint.
* ```
*/
export type InferESIResponseResultFromUnion<
EP extends unknown
// EP extends ESIEndpointUnions
> = EP extends `${infer M}:${infer EPRest}`
//* ctt
? M extends TESIEntryMethod
? EPRest extends ESIEndpointOf<M>
? _ESIResponseType<M, EPRest> extends { result: infer U }
? U : never
: never
: never
: never;
/*/
? EPRest extends (
M extends TESIEntryMethod ? ESIEndpointOf<M> : never
)
? _ESIResponseType<M, EPRest> extends { result: infer U }
? U : never
: never
: never;
//*/
// - - - - - - - - - - - - - - - - - - - - - - - - - -
// Next Endpoint
// - - - - - - - - - - - - - - - - - - - - - - - - - -
/**
* @experimental
*
* Resolves the next applicable ESI endpoint based on the current endpoint and its response type.
*
* This utility type determines which endpoints can be chained after the current endpoint (`EP`),
* based on the response type (`BaseResut`) and the URL pattern of potential next endpoints.
*
* @template M The HTTP method type (e.g., "get", "post", etc.), which must extend `TESIEntryMethod`.
* @template EP The current ESI endpoint under inspection; it extends `ESIEndpointOf<M>`.
* @template BaseResut Defaults to `InferESIResponseResult<M, EP>`; it is the inferred response result of the endpoint.
* @template Endpoints Defaults to `ESIEndpointOf<M>`; represents the union of all endpoints for method `M` to be considered as potential next endpoints.
*
* @remarks
* This type uses advanced TypeScript features such as conditional types, template literal types, and type inference
* to perform endpoint validation and chaining.
*
* @example
* ```ts
* type NextEndpoint = ResolveNextEndpoint<"get", "/universe/graphics/">;
* // Result: Union of endpoints like "/universe/graphics/{graphic_id}/" if they match the template and response type constraint.
* ```
*/
export type ResolveNextEndpoint<
M extends TESIEntryMethod,
EP extends Exclude<ESIEndpointOf<M>, symbol> = Exclude<ESIEndpointOf<M>, symbol>,
BaseResut extends InferESIResponseResult<M, EP> = InferESIResponseResult<M, EP>,
// Endpoints extends ESIEndpointAll = ESIEndpointAll,
Endpoints extends ESIEndpointOf<M> = ESIEndpointOf<M>,
> = {
[NextEP in Endpoints]: NextEP extends `${EP}${string}{${string}}/${string}`
? ValidateNextEndpoint<BaseResut, NextEP> extends 1
? NextEP : never
// ? [EP, NextEP, BaseResut] : never
: never;
}[Endpoints];
export type SplitEndpointUnion<
S extends ESIEndpointUnions, D extends string = ":",
AR extends any[] = Split<S, D>
> = AR[0] extends TESIEntryMethod
? AR[1] extends Exclude<ESIEndpointOf<AR[0]>, symbol>
? AR: never
: never;
// // Test cases
// type Test1 = SplitEndpointUnion<"post:/universe/ids/">;
/**
* Resolves the next applicable ESI endpoint based on a union of HTTP method and endpoint.
*
* This utility type determines which endpoints can be chained after the current endpoint (`EP`),
* based on the response type (`BaseResut`) and the URL pattern of potential next endpoints.
*
* @template EPU A union of HTTP method and endpoint in the format `${TESIEntryMethod}:${ESIEndpointAll}`.
* @template M The HTTP method extracted from `EPU`.
* @template EP The current endpoint extracted from `EPU`.
* @template BaseResut The inferred response result of the endpoint.
* @template Endpoints The union of all endpoints for the given method.
*
* @remarks
* This type uses advanced TypeScript features such as conditional types and template literal types
* to infer the next valid endpoint based on the current endpoint and its response type.
*
* @example
* ``` ts
* type NextEndpoint = ResolveNextEndpointFromUnion<"get:/universe/graphics/">;
* // Result: Union of endpoints like "/universe/graphics/{graphic_id}/" if they match the template and response type constraint.
* ```
*/
export type ResolveNextEndpointFromUnion<
EPU extends ESIEndpointUnions,
SplitM_EP extends [TESIEntryMethod, any] = SplitEndpointUnion<EPU>,
M extends TESIEntryMethod = SplitM_EP[0],
EP extends Exclude<ESIEndpointOf<M>, symbol> = SplitM_EP[1],
BaseResut extends InferESIResponseResult<M, EP> = InferESIResponseResult<M, EP>,
Endpoints extends ESIEndpointOf<M> = ESIEndpointOf<M>,
> = {
[NextEP in Endpoints]: NextEP extends `${EP}${string}{${string}}/${string}`
? ValidateNextEndpoint<BaseResut, NextEP> extends 1
? NextEP : never
// ? [EP, NextEP, BaseResut] : never
: never;
}[Endpoints];
/**
* Validates whether a given endpoint can be the next endpoint in a chain based on the response type of the current endpoint.
*
* This utility type checks if the response type (`Entry`) of the current endpoint satisfies the requirements
* for the next endpoint (`NextEP`), such as having the necessary path parameters.
*
* @template BaseResut The response type of the current endpoint (e.g., `number[]` or an array of objects).
* @template NextEP The next endpoint to validate.
* @template Debug Optional debug flag; if set to `1`, additional debug information is returned.
*
* @remarks
* This type assumes that if the response type is `number[]`, the next endpoint is always valid. For object arrays,
* it checks if the required path parameters can be inferred from the response type.
*
* ```ts
* type IsValid = ValidateNextEndpoint<GetCharactersCharacterIdMailOk, "/characters/{character_id}/mail/{mail_id}/">;
* // or
* type IsValid = ValidateNextEndpoint<GetCharactersCharacterIdMail_200Ok[], "/characters/{character_id}/mail/{mail_id}/">;
* // Result: 1 if valid, 0 otherwise.
* ```
*/
export type ValidateNextEndpoint<
BaseResut extends unknown, // number[] or SomeType[]
NextEP extends string,
Debug = 0,
> =
// If it is simply a number[], it is unconditionally assumed that there is a next endpoint.
BaseResut extends number[] ? 1 : ValidateEndpointParamsInArray<BaseResut, NextEP, Debug>;
/**
* Validates whether the elements of an object array satisfy the path parameter requirements
* for a given endpoint.
*
* @template BaseResut The response type of the current endpoint (e.g., an array of objects).
* @template NextEP The next endpoint to validate.
* @template Debug Optional debug flag; if set to `1`, additional debug information is returned.
* @template PathParams Defaults to `ExtractPathParamsTuple<NextEP>`; represents the path parameters of the next endpoint.
*
* @remarks
* This type assumes that if the response type is an array of objects, it checks whether the required
* path parameters can be inferred from the properties of the objects in the array.
*
* @example
* ```ts
* type IsValid = ValidateEndpointParamsInArray<GetCharactersCharacterIdMailOk, "/characters/{character_id}/mail/{mail_id}/">;
* // or
* type IsValid = ValidateEndpointParamsInArray<GetCharactersCharacterIdMail_200Ok[], "/characters/{character_id}/mail/{mail_id}/">;
* // Result: 1 if valid, 0 otherwise.
* ```
*/
type ValidateEndpointParamsInArray<
BaseResut extends unknown, // SomeType[]
NextEP extends string,
Debug = 0,
PathParams extends any[] = ExtractPathParamKeys<NextEP>,
> = BaseResut extends (infer O)[]
? PathParams[1] extends keyof O ? NonNullable<O[PathParams[1]]> extends number
? Debug extends 1 // development
? [O, PathParams] : 1
: 0
: 0
: 0;
/**
* `ResolveNextEndpointLoos` is a utility type that infers the next endpoint based on the current endpoint and method.
*
* DONE: 2025/4/11 15:45:01
* ``` jsonc
* // Infer the next parameterized endpoint to request from the EP
* // Does not validate the EP result, just infers the next endpoint to request
* ```
*
* @template M The HTTP method to use for the request.
* @template EP The endpoint from which the next parameterized endpoint to request is inferred.
* @template Endpoints The possible endpoints for the given method.
*
* ```ts
* type NextEndpoint = ResolveNextEndpointLoos<"get", "/markets/groups/">;
* // Result: "/markets/groups/{market_group_id}/"
* ```
* @remarks
* This type is useful for chaining requests or determining the next endpoint to call based on the current endpoint.
* It does not validate the response type of the endpoint, only the URL pattern.
*/
export type ResolveNextEndpointLoos<
M extends TESIEntryMethod,
/* ctt
// DEVNOTE: By applying "skipLibCheck=true", typescript semantics error will not occur.
EP extends ESIEndpointOf<M> = ESIEndpointOf<M>,
Endpoints extends ESIEndpointOf<M> = ESIEndpointOf<M>,
/*/
// This fix is required for skipLibCheck=false
EP extends Exclude<ESIEndpointOf<M>, symbol> = Exclude<ESIEndpointOf<M>, symbol>,
Endpoints extends ESIEndpointOf<M> = ESIEndpointOf<M>,
//*/
> = {
[NextEP in Endpoints]: NextEP extends `${EP}{${string}}${string}` ? NextEP : never
}[Endpoints];
/**
* @see For the meaning of this type of comment trick, see {@link ResolveNextEndpointLoos} line comment.
*/
export type ESIEndpointUnions = {
[M in TESIEntryMethod]: `${M}:${
/* ctt
ESIEndpointOf<M>
/*/
Exclude<ESIEndpointOf<M>, symbol>
//*/
}`;
}[TESIEntryMethod];
// - - - - - - - - - - - - - - - - - - - - - - - - - -
// Filter Endpoint
// - - - - - - - - - - - - - - - - - - - - - - - - - -
/**
* Filters ESI endpoints based on the response type.
*
* This utility type iterates over all ESI endpoint unions (`ESIEndpointUnions`) and checks
* if the inferred response type (`InferESIResponseResultFromUnion<EPU>`) matches the specified type `T`.
* If it matches, the endpoint is included; otherwise, it is excluded.
*
* @template T The response type to filter endpoints by.
*
* @example
* ``` ts
* type NumberEndpoints = FilterEndpointUnionsByResponse<number>;
* // Result: Union of endpoints whose response type is `number`.
* ```
*/
export type FilterEndpointUnionsByResponse<T> = {
[EPU in ESIEndpointUnions]: InferESIResponseResultFromUnion<EPU> extends T ? EPU : never;
}[ESIEndpointUnions];
/**
* Extracts valid next ESI endpoints from a filtered list of endpoints.
*
* This utility type iterates over a list of filtered endpoints (`EPUs`) and applies
* `ResolveNextEndpoint2` to determine if the endpoint is valid. If valid, the endpoint
* is included in the result; otherwise, it is excluded.
*
* @template EPUs The list of filtered endpoints to process.
*
* @example
* ``` ts
* type ValidEndpoints = ExtractValidNextEndpoints<FilterEndpointsByResponse<number[]>>;
* // Result: Union of valid next endpoints.
* ```
*/
export type ExtractValidNextEndpoints<
T = number[], EPUs extends ESIEndpointUnions = FilterEndpointUnionsByResponse<T>,
Debug = 0
> = {
// [EPU in EPUs]: ResolveNextEndpointFromUnion<EPU>;
[EPU in EPUs]: Debug extends 1
? ResolveNextEndpointFromUnion<EPU> extends never
? never
: [EPU, ResolveNextEndpointFromUnion<EPU>] // array
// : { [X in EPU]: ResolveNextEndpointFromUnion<EPU> } // map
: ResolveNextEndpointFromUnion<EPU>;
}[EPUs];
export type ExtractValidNextEndpointsOrMap<
T = number[],
EPUs = FilterEndpointUnionsByResponse<T>,
Debug = 0
> = EPUs extends infer EPU
? EPU extends EPUs
? EPU extends ESIEndpointUnions
? ResolveNextEndpointFromUnion<EPU> extends never
? never
: Debug extends 1 ? { readonly [K in EPU]: UnionToTuple<ResolveNextEndpointFromUnion<EPU>> }
// : Debug extends 1 ? { readonly [K in EPU]: ResolveNextEndpointFromUnion<EPU> }
: ResolveNextEndpointFromUnion<EPU>
: never
: never
: never;