eve-esi-types 2.3.4 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -16
- package/esi-types-util3.md +186 -0
- package/lib/request-api.d.mts +6 -7
- package/lib/request-api.mjs +14 -12
- package/lib/rq-util.d.mts +27 -7
- package/lib/rq-util.mjs +38 -36
- package/lib/tagged-request-api.d.mts +9 -12
- package/lib/tagged-request-api.mjs +18 -19
- package/minimal-rq.mjs +18 -16
- package/package.json +1 -1
- package/tagged-rq.mjs +24 -8
- package/v2/esi-tagged-types.d.ts +28 -24
- package/v2/index.d.ts +163 -57
- package/v2/response-map.d.ts +138 -18
- package/v2/types-index.d.ts +1 -1
- package/v2.d.mts +4 -14
- package/v2.mjs +26 -21
- package/esi-types-util.md +0 -127
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
/**
|
|
10
10
|
* @file eve-esi-types/lib/tagged-request-api.mts
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
12
|
+
import { request2 } from "./request-api.mjs";
|
|
13
13
|
/**
|
|
14
|
-
* @import {
|
|
14
|
+
* @import { TESIRequestFunctionMethods2 } from "../v2"
|
|
15
15
|
*/
|
|
16
16
|
/**
|
|
17
17
|
* @typedef {`${string}${"" | `,${string}`}`} TMethodList
|
|
@@ -36,37 +36,36 @@ const ESITagMethodMapping = [
|
|
|
36
36
|
"Wars:get"
|
|
37
37
|
];
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* + The `ESI request API object` constructed by `injectESIRequestBody` lists narrowed endpoints by accessing the camel-cased "tags" members.
|
|
39
|
+
* Decorates the ESI request body into a tagged ESI request map.
|
|
42
40
|
*
|
|
43
41
|
* @example
|
|
44
42
|
* import * as taggedApi from "eve-esi-types/lib/tagged-request-api.mjs";
|
|
45
43
|
*
|
|
46
|
-
* const esiRequest = taggedApi.
|
|
44
|
+
* const esiRequest = taggedApi.decoreateESIRequestBody(...);
|
|
47
45
|
* const ret = await esiRequest.universe.get("/universe/structures/", { query: { filter: "market" }});
|
|
48
46
|
*
|
|
49
47
|
* @template {Record<string, unknown>} Opt - The options type for the request.
|
|
50
|
-
* @param {
|
|
51
|
-
* @returns {XESI.
|
|
52
|
-
* @since 2.3
|
|
48
|
+
* @param {TESIRequestFunctionSignature2<Opt>} requestBody - The function signature for the ESI request.
|
|
49
|
+
* @returns {XESI.TaggedESIRequestMap2<Opt>} - The tagged ESI request map.
|
|
53
50
|
*/
|
|
54
|
-
export function
|
|
55
|
-
const rq = /** @type {XESI.
|
|
51
|
+
export function decoreateESIRequestBody(requestBody) {
|
|
52
|
+
const rq = /** @type {XESI.TaggedESIRequestMap2<Opt>} */ ({});
|
|
56
53
|
// DEVNOTE: 2025/03/08 - In reality, you only need one function instance for each of "get", "post", "put", and "delete",
|
|
57
54
|
// so you can just refer to the cached functions as a map.
|
|
58
|
-
const methodMap = /** @type {
|
|
55
|
+
const methodMap = /** @type {TESIRequestFunctionMethods2<Opt>} */ ({});
|
|
59
56
|
/** @type {TESIEntryMethod[]} */ (["get", "post", "put", "delete"]).forEach((method) => {
|
|
60
|
-
methodMap[method] = /** @type {
|
|
57
|
+
methodMap[method] = /** @type {TESIRequestFunctionEachMethod2<typeof method, Opt>} */ (
|
|
58
|
+
// @ts-expect-error Type peeling due to differences in inference process
|
|
59
|
+
(e, opt) => requestBody(method, e, opt));
|
|
61
60
|
});
|
|
62
61
|
for (const tagEntry of ESITagMethodMapping) {
|
|
63
62
|
const [tag, methodList] = /** @type {[tag: XESI.ESITags, methods: TMethodList]} */ (tagEntry.split(":"));
|
|
64
63
|
const methods = /** @type {TESIEntryMethod[]} */ (methodList.split(","));
|
|
65
|
-
const entry = /** @type {XESI.
|
|
64
|
+
const entry = /** @type {XESI.ESITaggedEndpointRequest2<typeof tag, Opt>} */ ({});
|
|
66
65
|
for (const method of methods) {
|
|
67
66
|
// However, from the point of view of type annotation, the parameters are different, so you need to cast it as `as type` instead of `satisfies`.
|
|
68
67
|
// @ts-expect-error
|
|
69
|
-
entry[method] = /** @type {XESI.
|
|
68
|
+
entry[method] = /** @type {XESI.TaggedEndpointRequestFunction2<typeof method, typeof tag, Opt>} */ (methodMap[method]);
|
|
70
69
|
}
|
|
71
70
|
const camelCased = /** @type {XESI.LCamelCase<XESI.ESITags>} */ (tag[0].toLowerCase() + tag.slice(1).replace(/\s(.)/g, "$1"));
|
|
72
71
|
rq[camelCased] = entry;
|
|
@@ -77,9 +76,9 @@ export function injectESIRequestBody(requestBody) {
|
|
|
77
76
|
* @import { ESIRequestOptions } from "./rq-util.mjs";
|
|
78
77
|
*/
|
|
79
78
|
/**
|
|
80
|
-
* Injects the minimal implementation of ESI requests into `XESI.
|
|
79
|
+
* Injects the minimal implementation of ESI requests into `XESI.TaggedESIRequestMap2`.
|
|
81
80
|
*
|
|
82
|
-
* @since 2.
|
|
83
|
-
* @type {XESI.
|
|
81
|
+
* @since 2.x
|
|
82
|
+
* @type {XESI.TaggedESIRequestMap2<ESIRequestOptions>}
|
|
84
83
|
*/
|
|
85
|
-
export const esi =
|
|
84
|
+
export const esi = decoreateESIRequestBody(request2);
|
package/minimal-rq.mjs
CHANGED
|
@@ -10,55 +10,56 @@
|
|
|
10
10
|
// imports
|
|
11
11
|
// - - - - - - - - - - - - - - - - - - - -
|
|
12
12
|
import * as util from "./lib/rq-util.mjs";
|
|
13
|
-
import {
|
|
13
|
+
import { request2 } from "./lib/request-api.mjs";
|
|
14
14
|
// - - - - - - - - - - - - - - - - - - - -
|
|
15
15
|
// constants, types
|
|
16
16
|
// - - - - - - - - - - - - - - - - - - - -
|
|
17
17
|
// shorthands
|
|
18
18
|
const log = util.getUniversalLogger("[request-mini]: ");
|
|
19
19
|
/**
|
|
20
|
-
* @typedef {import("./v2").
|
|
21
|
-
* @typedef {import("./v2").
|
|
20
|
+
* @typedef {import("./v2").IESIRequestFunction2<util.ESIRequestOptions>} IESIRequestFunction2
|
|
21
|
+
* @typedef {import("./v2").TESIRequestFunctionMethods2<util.ESIRequestOptions>} TESIRequestFunctionMethods2
|
|
22
22
|
*/
|
|
23
23
|
// - - - - - - - - - - - - - - - - - - - -
|
|
24
24
|
// main functions
|
|
25
25
|
// - - - - - - - - - - - - - - - - - - - -
|
|
26
26
|
//
|
|
27
|
-
// Delegates implementation to `request` (
|
|
27
|
+
// Delegates implementation to `request` (TESIRequestFunctionMethods2)
|
|
28
28
|
//
|
|
29
|
-
const esiMethods = /** @type {
|
|
29
|
+
const esiMethods = /** @type {TESIRequestFunctionMethods2} */ ({});
|
|
30
30
|
/** @type {TESIEntryMethod[]} */ (["get", "post", "put", "delete"]).forEach((method) => {
|
|
31
|
-
esiMethods[method] = /** @type {
|
|
32
|
-
|
|
31
|
+
esiMethods[method] = /** @type {TESIRequestFunctionEachMethod2<typeof method>} */ (function (endpoint, opt) {
|
|
32
|
+
// @ts-expect-error
|
|
33
|
+
return request2(method, endpoint, opt);
|
|
33
34
|
});
|
|
34
35
|
});
|
|
35
36
|
// It should complete correctly.
|
|
36
37
|
/**
|
|
37
|
-
* @param {
|
|
38
|
+
* @param {IESIRequestFunction2} fn
|
|
38
39
|
*/
|
|
39
|
-
async function
|
|
40
|
+
async function getEVEStatus2(fn) {
|
|
40
41
|
await util.getSDEVersion().then(sdeVersion => log(`sdeVersion: ${sdeVersion}`.blue));
|
|
41
42
|
await util.fireRequestsDoesNotRequireAuth(fn);
|
|
42
43
|
CaseIESIRequestFunctionMethods: {
|
|
43
44
|
await util.fireRequestsDoesNotRequireAuth(esiMethods);
|
|
44
45
|
}
|
|
45
46
|
const { clog, rlog } = util.getLogger();
|
|
46
|
-
|
|
47
|
+
CaseIESIRequestFunction2: {
|
|
47
48
|
const ID_CCP_Zoetrope = 2112625428;
|
|
48
49
|
// - - - - - - - - - - - -
|
|
49
50
|
// Character
|
|
50
51
|
// - - - - - - - - - - - -
|
|
51
52
|
// Here, I borrow data from "CCP Zoetrope".
|
|
52
|
-
rlog("- - - - - - - > run as
|
|
53
|
+
rlog("- - - - - - - > run as IESIRequestFunction2<ESIRequestOptions>".red);
|
|
53
54
|
clog();
|
|
54
|
-
await fn.get("/characters/{character_id}/", ID_CCP_Zoetrope).then(log);
|
|
55
|
+
await fn.get("/characters/{character_id}/", { pathParams: ID_CCP_Zoetrope }).then(log);
|
|
55
56
|
clog('(portrait)');
|
|
56
|
-
await fn.get(
|
|
57
|
+
await fn.get(`/characters/${ID_CCP_Zoetrope}/portrait/`).then(log);
|
|
57
58
|
clog('(affiliation)');
|
|
58
59
|
const affiliation = await fn.post("/characters/affiliation/", { body: [ID_CCP_Zoetrope] });
|
|
59
60
|
log(affiliation);
|
|
60
61
|
clog('(corporation)');
|
|
61
|
-
await fn.get(
|
|
62
|
+
await fn.get(`/corporations/${affiliation[0].corporation_id}/`).then(log);
|
|
62
63
|
rlog("get:/incursions/".green);
|
|
63
64
|
await fn.get("/incursions/").then(log);
|
|
64
65
|
// - - - - - - - - - - - -
|
|
@@ -68,7 +69,8 @@ async function getEVEStatus(fn) {
|
|
|
68
69
|
const ids = await fn.post("/universe/ids/", { body: ["the forge", "plex"] });
|
|
69
70
|
log(ids.inventory_types, ids.regions);
|
|
70
71
|
rlog(`get:/markets/${ids?.regions?.[0].id}/orders/?type_id=${ids?.inventory_types?.[0].id}, item PLEX`.green);
|
|
71
|
-
const orders = await fn.get("/markets/{region_id}/orders/",
|
|
72
|
+
const orders = await fn.get("/markets/{region_id}/orders/", {
|
|
73
|
+
pathParams: ids?.regions?.[0].id || 0,
|
|
72
74
|
query: {
|
|
73
75
|
// page: 1,
|
|
74
76
|
order_type: "sell",
|
|
@@ -80,7 +82,7 @@ async function getEVEStatus(fn) {
|
|
|
80
82
|
return fn.get("/status/");
|
|
81
83
|
}
|
|
82
84
|
const runTest = () => {
|
|
83
|
-
|
|
85
|
+
getEVEStatus2(request2).then(eveStatus => log(eveStatus));
|
|
84
86
|
};
|
|
85
87
|
// type following and run
|
|
86
88
|
// node minimal-rq.mjs -debug
|
package/package.json
CHANGED
package/tagged-rq.mjs
CHANGED
|
@@ -5,19 +5,35 @@
|
|
|
5
5
|
// https://opensource.org/licenses/mit-license.php
|
|
6
6
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
7
7
|
*/
|
|
8
|
+
/// <reference types="./v2"/>
|
|
8
9
|
/**
|
|
9
10
|
* @file tagged-rq.mts
|
|
10
11
|
* @command node tagged-rq.mjs -x
|
|
11
12
|
*/
|
|
12
|
-
import { esi
|
|
13
|
-
//
|
|
13
|
+
import { esi } from "./lib/tagged-request-api.mjs";
|
|
14
|
+
// import * as util from "./lib/rq-util.mjs";
|
|
14
15
|
// Furthermore, the endpoint selected is narrowed down by "tags" and "method".
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
esi.assets.get("/characters/2112625428/assets/", {
|
|
17
|
+
auth: true
|
|
18
|
+
}).then(console.log).catch(console.log);
|
|
19
|
+
esi.character.get("/characters/{character_id}/", { pathParams: 2112625428 }).then(console.log);
|
|
20
|
+
esi.mail.post("/characters/2112625428/mail/", /** @satisfies {Pick<TESIResponsePostEntry<"/characters/{character_id}/mail/">, "auth" | "body">} */ ({
|
|
21
|
+
auth: true,
|
|
22
|
+
body: {
|
|
23
|
+
subject: "test!!",
|
|
24
|
+
body: "",
|
|
25
|
+
recipients: [{
|
|
26
|
+
recipient_id: 2112625428, recipient_type: "character"
|
|
27
|
+
}]
|
|
28
|
+
},
|
|
29
|
+
// token: "s.s.s"
|
|
30
|
+
})).then(console.log).catch(console.log);
|
|
31
|
+
esi.universe.get("/universe/structures/", { query: { filter: "market" } }).then(console.log);
|
|
32
|
+
esi.universe.post("/universe/ids/", {
|
|
18
33
|
body: ["the forge", "plex"]
|
|
19
34
|
}).then(console.log);
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
esi.fittings.delete("/characters/{character_id}/fittings/{fitting_id}/", {
|
|
36
|
+
pathParams: [1234, 56789],
|
|
22
37
|
auth: true
|
|
23
|
-
})
|
|
38
|
+
});
|
|
39
|
+
esi.character.post("/characters/affiliation/").catch(console.log);
|
package/v2/esi-tagged-types.d.ts
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
* THIS DTS IS AUTO GENERATED, DO NOT EDIT
|
|
10
10
|
*
|
|
11
11
|
* @file eve-esi-types/v2/esi-tagged-types.d.ts
|
|
12
|
-
* @summary This file is auto-generated and defines version
|
|
12
|
+
* @summary This file is auto-generated and defines version 3.0.0 of the EVE Online ESI response types.
|
|
13
13
|
*/
|
|
14
|
-
import { TESIResponseOKMap } from "./index.d.ts";
|
|
14
|
+
import { TESIResponseOKMap, TPathParamsNever } from "./index.d.ts";
|
|
15
15
|
export * from "./index.d.ts";
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -30,13 +30,13 @@ export declare type LCamelCase<S extends string> = S extends `${infer P1} ${infe
|
|
|
30
30
|
? `${Lowercase<P1>}${Capitalize<P2>}` : Lowercase<S>;
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
declare
|
|
34
|
-
METHOD
|
|
35
|
-
TAGs
|
|
36
|
-
}
|
|
37
|
-
declare type InferSomethingBy<Tag, AsType extends EInferSomethingBy = EInferSomethingBy
|
|
33
|
+
declare type EInferSomethingBy = {
|
|
34
|
+
readonly METHOD: 0;
|
|
35
|
+
readonly TAGs: 1;
|
|
36
|
+
};
|
|
37
|
+
declare type InferSomethingBy<Tag, AsType extends EInferSomethingBy = EInferSomethingBy["METHOD"]> = {
|
|
38
38
|
[M in TESIEntryMethod]: TESIResponseOKMap[M] extends Record<`/${string}/`, { tag: infer ActualTag }>
|
|
39
|
-
? AsType extends EInferSomethingBy
|
|
39
|
+
? AsType extends EInferSomethingBy["TAGs"]
|
|
40
40
|
? ActualTag : ActualTag extends Tag
|
|
41
41
|
? M
|
|
42
42
|
: never
|
|
@@ -50,7 +50,7 @@ declare type InferSomethingBy<Tag, AsType extends EInferSomethingBy = EInferSome
|
|
|
50
50
|
* @template M - The HTTP method.
|
|
51
51
|
* @date 2025/2/28
|
|
52
52
|
*/
|
|
53
|
-
export declare type ESITags = InferSomethingBy<never, EInferSomethingBy
|
|
53
|
+
export declare type ESITags = InferSomethingBy<never, EInferSomethingBy["TAGs"]>
|
|
54
54
|
|
|
55
55
|
// - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
56
56
|
// Utility Type `InferMethod`
|
|
@@ -67,7 +67,7 @@ export declare type InferMethod<Tag> = InferSomethingBy<Tag>
|
|
|
67
67
|
// type XPlanetary = InferMethod<"Planetary Interaction">;
|
|
68
68
|
|
|
69
69
|
// - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
70
|
-
// Utility Type `
|
|
70
|
+
// Utility Type `TaggedEndpointRequestFunction2`
|
|
71
71
|
// - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
72
72
|
/**
|
|
73
73
|
* Creates a function type for making requests to tagged endpoints.
|
|
@@ -86,15 +86,19 @@ export declare type InferMethod<Tag> = InferSomethingBy<Tag>
|
|
|
86
86
|
* @returns A promise that resolves to the response.
|
|
87
87
|
* @date 2025/2/28
|
|
88
88
|
*/
|
|
89
|
-
export declare type
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
export declare type TaggedEndpointRequestFunction2<M extends TESIEntryMethod, Tag extends ESITags, ActualOpt = {}> = <
|
|
90
|
+
RealEP extends ReplacePathParams<keyof TESIResponseOKMap[M] & string> | keyof TESIResponseOKMap[M],
|
|
91
|
+
EP extends InferEndpointOrigin<RealEP, SelectEndpointByTag<Tag, M>> extends never ? RealEP: InferEndpointOrigin<RealEP, SelectEndpointByTag<Tag, M>>,
|
|
92
|
+
PathParams extends RealEP extends EP ? IfNeedPathParams<EP>: TPathParamsNever,
|
|
93
|
+
Opt extends IdentifyParameters<TESIResponseOKMap[M][EP], ActualOpt & PathParams>,
|
|
94
|
+
R extends InferESIResponseResult<M, EP>,
|
|
95
|
+
// RealEPX = ReplacePathParamsX<RealEPX>,
|
|
96
|
+
// EPX = ReplacePathParams<EP>,
|
|
97
|
+
>(endpoint: RealEP, options?: Opt) => Promise<R>;
|
|
98
|
+
|
|
95
99
|
|
|
96
100
|
// - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
97
|
-
// Utility Type `
|
|
101
|
+
// Utility Type `ESITaggedEndpointRequest2`
|
|
98
102
|
// - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
99
103
|
/**
|
|
100
104
|
* Maps tags to their corresponding endpoint request functions.
|
|
@@ -102,9 +106,9 @@ export declare type TaggedEndpointRequestFunction<M extends TESIEntryMethod, Tag
|
|
|
102
106
|
* @template Tag - The tag to map.
|
|
103
107
|
* @date 2025/2/28
|
|
104
108
|
*/
|
|
105
|
-
export declare type
|
|
109
|
+
export declare type ESITaggedEndpointRequest2<Tag extends ESITags, ActualOpt = {}> = {
|
|
106
110
|
[tag in Tag]: {
|
|
107
|
-
[method in InferMethod<Tag>]:
|
|
111
|
+
[method in InferMethod<Tag>]: TaggedEndpointRequestFunction2<method, tag, ActualOpt>;
|
|
108
112
|
};
|
|
109
113
|
}[Tag];
|
|
110
114
|
|
|
@@ -132,22 +136,22 @@ export declare type SelectEndpointByTag<
|
|
|
132
136
|
|
|
133
137
|
/**
|
|
134
138
|
* Maps lower camel case tags to their corresponding endpoint request functions.
|
|
135
|
-
* @date 2025/
|
|
139
|
+
* @date 2025/3/12
|
|
136
140
|
*/
|
|
137
|
-
export declare type
|
|
138
|
-
[tag in ESITags as LCamelCase<tag>]:
|
|
141
|
+
export declare type TaggedESIRequestMap2<ActualOpt = {}> = {
|
|
142
|
+
[tag in ESITags as LCamelCase<tag>]: ESITaggedEndpointRequest2<tag, ActualOpt>;
|
|
139
143
|
};
|
|
140
144
|
|
|
141
145
|
/**
|
|
142
146
|
* Creates a partial map of lower camel case tags to their corresponding endpoint request functions.
|
|
143
147
|
* ```ts
|
|
144
148
|
* // implements "factionWarfare", "wallet"
|
|
145
|
-
* const esiRq:
|
|
149
|
+
* const esiRq: TaggedESIRequestMapPartial2<"factionWarfare" | "wallet">;
|
|
146
150
|
* ```
|
|
147
151
|
*
|
|
148
152
|
* @template Props - The properties to require in the partial map.
|
|
149
153
|
* @date 2025/2/28
|
|
150
154
|
*/
|
|
151
|
-
export declare type
|
|
155
|
+
export declare type TaggedESIRequestMapPartial2<Props extends LCamelCase<ESITags>> = RequireThese<Partial<TaggedESIRequestMap2>, Props>;
|
|
152
156
|
|
|
153
157
|
export as namespace XESI;
|
package/v2/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* THIS DTS IS AUTO GENERATED, DO NOT EDIT
|
|
10
10
|
*
|
|
11
11
|
* @file eve-esi-types/v2/index.d.ts
|
|
12
|
-
* @summary This file is auto-generated and defines version
|
|
12
|
+
* @summary This file is auto-generated and defines version 3.0.0 of the EVE Online ESI response types.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import type { TESIResponseOKMap } from "./response-map.d.ts";
|
|
@@ -25,49 +25,78 @@ import type { PickPathParameters, InferKeysLen } from "./util.d.ts";
|
|
|
25
25
|
* @example
|
|
26
26
|
* ```ts
|
|
27
27
|
* // @ ts-expect-error
|
|
28
|
-
* export const request:
|
|
28
|
+
* export const request: IESIRequestFunction2<ESIRequestOptions> = (method, endpoint, opt) => {
|
|
29
29
|
* // Implementation for "get" | "post" | "put" | "delete" request
|
|
30
30
|
* };
|
|
31
31
|
* // You can easily implement "get" | "post" | "put" | "delete" requests
|
|
32
32
|
* // with code like the following:
|
|
33
33
|
* (["get", "post", "put", "delete"] as (keyof typeof request)[]).forEach((method) => {
|
|
34
|
-
* request[method] = function (this: typeof request, endpoint,
|
|
35
|
-
* return this(method, endpoint,
|
|
36
|
-
* } as
|
|
34
|
+
* request[method] = function (this: typeof request, endpoint, opt) {
|
|
35
|
+
* return this(method, endpoint, opt);
|
|
36
|
+
* } as TESIRequestFunctionEachMethod2<typeof method>;
|
|
37
37
|
* });
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
|
-
export interface
|
|
41
|
-
extends
|
|
40
|
+
export interface IESIRequestFunction2<ActualOpt>
|
|
41
|
+
extends TESIRequestFunctionSignature2<ActualOpt>, TESIRequestFunctionMethods2<ActualOpt> {
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Represents the methods available for making ESI requests.
|
|
46
46
|
*
|
|
47
47
|
* + This interface is used when you already have implementation code such as
|
|
48
|
-
*
|
|
48
|
+
* TESIRequestFunctionSignature2 and you want to implement additional shorthand methods.
|
|
49
49
|
*
|
|
50
50
|
* @template ActualOpt - The actual type of the options.
|
|
51
51
|
*
|
|
52
52
|
* @example
|
|
53
53
|
* ```ts
|
|
54
|
-
* export const request:
|
|
54
|
+
* export const request: TESIRequestFunctionSignature2<ESIRequestOptions> = (method, endpoint, opt) => {
|
|
55
55
|
* // Implementation for "get" | "post" | "put" | "delete" request
|
|
56
56
|
* };
|
|
57
57
|
* // You can easily implement "get" | "post" | "put" | "delete" requests
|
|
58
58
|
* // with code like the following:
|
|
59
|
-
* const esiMethods = {} as
|
|
60
|
-
* (["get", "post", "put", "delete"] as (keyof
|
|
61
|
-
* esiMethods[method] = function (endpoint,
|
|
62
|
-
* return request(method, endpoint,
|
|
63
|
-
* } as
|
|
59
|
+
* const esiMethods = {} as TESIRequestFunctionMethods2<ESIRequestOptions>;
|
|
60
|
+
* (["get", "post", "put", "delete"] as (keyof TESIRequestFunctionMethods2)[]).forEach((method) => {
|
|
61
|
+
* esiMethods[method] = function (endpoint, opt) {
|
|
62
|
+
* return request(method, endpoint, opt);
|
|
63
|
+
* } as TESIRequestFunctionEachMethod2<typeof method>;
|
|
64
64
|
* });
|
|
65
65
|
* ```
|
|
66
66
|
*/
|
|
67
|
-
export type
|
|
68
|
-
[method in TESIEntryMethod]:
|
|
67
|
+
export type TESIRequestFunctionMethods2<ActualOpt = {}> = {
|
|
68
|
+
[method in TESIEntryMethod]: TESIRequestFunctionEachMethod2<method, ActualOpt>;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* List of "x-cached-seconds"
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* // const cacheSecGet: 3600 | 300 | 604800 | 120 | 5 | 600 | 86400 | 60 | 30 | 1200 | 1800 | 30758400
|
|
76
|
+
* const cacheSecGet: TESICachedSeconds<"get">;
|
|
77
|
+
* // const cache5sec: 5
|
|
78
|
+
* const cache5s: TESICachedSeconds<"put">;
|
|
79
|
+
* // const cache3600s: 3600
|
|
80
|
+
* const cache3600s: TESICachedSeconds<"post">;
|
|
81
|
+
* // "/characters/affiliation/"
|
|
82
|
+
* const cache3600sEndpoint: TESICachedSeconds<"post", 1>;
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare type TESICachedSeconds<
|
|
86
|
+
Method extends TESIEntryMethod, AsEndpoint = void
|
|
87
|
+
> = {
|
|
88
|
+
[M in TESIEntryMethod]: {
|
|
89
|
+
[EP in keyof TESIResponseOKMap[M]]: TESIResponseOKMap[M][EP]["cachedSeconds"] extends number
|
|
90
|
+
? AsEndpoint extends void
|
|
91
|
+
? TESIResponseOKMap[M][EP]["cachedSeconds"]: EP
|
|
92
|
+
: never
|
|
93
|
+
}[keyof TESIResponseOKMap[M]];
|
|
94
|
+
}[Method];
|
|
95
|
+
// const cacheSecGet: TESICachedSeconds<"get">;
|
|
96
|
+
// const cache5sec: TESICachedSeconds<"put">;
|
|
97
|
+
// const cache3600sEndpoint: TESICachedSeconds<"post", 1>;
|
|
98
|
+
export declare type TPathParamsNever = { pathParams?: never };
|
|
99
|
+
|
|
71
100
|
declare global {
|
|
72
101
|
|
|
73
102
|
/**
|
|
@@ -75,63 +104,140 @@ declare global {
|
|
|
75
104
|
*/
|
|
76
105
|
type RequireThese<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
77
106
|
|
|
107
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
108
|
+
// Version 3 types
|
|
109
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
78
110
|
/**
|
|
79
|
-
*
|
|
111
|
+
* ### ESI request function with real endpoint signature
|
|
80
112
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* @returns {number | [number, number] | Opt}
|
|
84
|
-
* Returns `number` if there is one parameter, `[number, number]` if there are two parameters, otherwise `Opt`.
|
|
85
|
-
*/
|
|
86
|
-
type IfParameterizedPath<EP, Opt> = EP extends `${string}/{${string}}${string}`
|
|
87
|
-
? PickPathParameters<EP> extends never
|
|
88
|
-
? Opt : InferKeysLen<PickPathParameters<EP>> extends 1
|
|
89
|
-
? number : [number, number]
|
|
90
|
-
: Opt;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* ### ESI request function all in one signature
|
|
94
|
-
*
|
|
95
|
-
* TESIRequestFunctionSignature is a type that defines the signature of an ESI request function.
|
|
113
|
+
* TESIRequestFunctionSignature2 is a type that defines the signature of an ESI request function
|
|
114
|
+
* where the endpoint can be a real endpoint or a parameterized endpoint.
|
|
96
115
|
*
|
|
97
116
|
* This function sends a request to a specified endpoint and returns a response.
|
|
98
117
|
*
|
|
99
|
-
* @template ActualOpt - The actual type of the option.
|
|
100
|
-
* Required parameters inferred by typescript are merged.
|
|
118
|
+
* @template ActualOpt - The actual type of the option.
|
|
101
119
|
* @template M - The HTTP method to use for the request
|
|
102
|
-
* @template
|
|
103
|
-
* @template
|
|
104
|
-
* @template
|
|
105
|
-
*
|
|
120
|
+
* @template RealEP - The real path of the ESI endpoint to send the request to
|
|
121
|
+
* @template EP - The parameterized path of the ESI endpoint to send the request to
|
|
122
|
+
* @template PathParams - Parameters to include in the request if the endpoint is parameterized
|
|
123
|
+
* @template Opt - Options to include in the request. If there is a required parameter, its type will be merged with `ActualOpt`
|
|
106
124
|
* @template R - The response type
|
|
125
|
+
*
|
|
126
|
+
* @param method - The HTTP method to use for the request (e.g., "get", "post").
|
|
127
|
+
* @param endpoint - The real path of the ESI endpoint to send the request to.
|
|
128
|
+
* @param options - An optional object containing additional options for the request.
|
|
129
|
+
*
|
|
130
|
+
* @returns A Promise object containing the response data, with the type inferred based on the method and endpoint.
|
|
107
131
|
*/
|
|
108
|
-
type
|
|
132
|
+
type TESIRequestFunctionSignature2<ActualOpt> = <
|
|
109
133
|
M extends TESIEntryMethod,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
134
|
+
// "/characters/123/fittings/456/"
|
|
135
|
+
RealEP extends ReplacePathParams<keyof TESIResponseOKMap[M] & string> | keyof TESIResponseOKMap[M],
|
|
136
|
+
// "/characters/{character_id}/fittings/{fitting_id}/"
|
|
137
|
+
EP extends InferEndpointOrigin<RealEP, keyof TESIResponseOKMap[M]> extends never ? RealEP: InferEndpointOrigin<RealEP, keyof TESIResponseOKMap[M]>,
|
|
138
|
+
// If RealEP points to an endpoint origin (not a replaced endpoint), the path parameter is required
|
|
139
|
+
PathParams extends RealEP extends EP ? IfNeedPathParams<EP>: TPathParamsNever,
|
|
140
|
+
Opt extends IdentifyParameters<TESIResponseOKMap[M][EP], ActualOpt & PathParams>,
|
|
113
141
|
R extends InferESIResponseResult<M, EP>
|
|
114
|
-
>(method: M, endpoint:
|
|
142
|
+
>(method: M, endpoint: RealEP, options?: Opt) => Promise<R>;
|
|
115
143
|
|
|
116
144
|
/**
|
|
117
|
-
* Represents a function that
|
|
145
|
+
* Represents a function that can make ESI requests for a specific HTTP method.
|
|
118
146
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* @
|
|
123
|
-
*
|
|
124
|
-
*
|
|
147
|
+
* This type is used to define functions that send requests to specific ESI endpoints using a given HTTP method.
|
|
148
|
+
*
|
|
149
|
+
* @template M - The HTTP method to use for the request.
|
|
150
|
+
* @template ActualOpt - The actual type of the options.
|
|
151
|
+
*
|
|
152
|
+
* @template RealEP - The real path of the ESI endpoint to send the request to.
|
|
153
|
+
* @template EP - The parameterized path of the ESI endpoint to send the request to.
|
|
154
|
+
* @template PathParams - Parameters to include in the request if the endpoint is parameterized.
|
|
155
|
+
* @template Opt - Options to include in the request. If there is a required parameter, its type will be merged with `ActualOpt`.
|
|
156
|
+
* @template R - The response type.
|
|
157
|
+
*
|
|
158
|
+
* @param endpoint - The real path of the ESI endpoint to send the request to.
|
|
125
159
|
* @param options - An optional object containing additional options for the request.
|
|
126
|
-
*
|
|
160
|
+
*
|
|
127
161
|
* @returns A Promise object containing the response data, with the type inferred based on the method and endpoint.
|
|
128
162
|
*/
|
|
129
|
-
type
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
163
|
+
type TESIRequestFunctionEachMethod2<M extends TESIEntryMethod, ActualOpt = {}> = <
|
|
164
|
+
RealEP extends ReplacePathParams<keyof TESIResponseOKMap[M] & string> | keyof TESIResponseOKMap[M],
|
|
165
|
+
EP extends InferEndpointOrigin<RealEP, keyof TESIResponseOKMap[M]> extends never ? RealEP: InferEndpointOrigin<RealEP, keyof TESIResponseOKMap[M]>,
|
|
166
|
+
PathParams extends RealEP extends EP ? IfNeedPathParams<EP>: TPathParamsNever,
|
|
167
|
+
Opt extends IdentifyParameters<TESIResponseOKMap[M][EP], ActualOpt & PathParams>,
|
|
133
168
|
R extends InferESIResponseResult<M, EP>
|
|
134
|
-
>(endpoint:
|
|
169
|
+
>(endpoint: RealEP, options?: Opt) => Promise<R>;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Replaces path parameters in a string with numbers.
|
|
173
|
+
*
|
|
174
|
+
* @template T - The string representing the endpoint path.
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* type Example = ReplacePathParams<"/characters/{character_id}/fittings/{fitting_id}/">;
|
|
178
|
+
* // Result: `/characters/${number}/fittings/${number}/`
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
type ReplacePathParams<T extends string> = T extends `${infer Start}{${infer Param}}${infer End}`
|
|
182
|
+
? `${Start}${number}${ReplacePathParams<End>}` : T;
|
|
183
|
+
|
|
184
|
+
// // type Example = ReplacePathParamsX<"/characters/1234/fittings/{fitting_id}/">;
|
|
185
|
+
// // Result: `characters/${number}/fittings/${number}/`
|
|
186
|
+
// type ReplacePathParamsX<T extends string> =
|
|
187
|
+
// T extends `/${infer Start}/${infer Param}/${infer End}` ? `${Start}/${number}/${ReplacePathParams<End>}`
|
|
188
|
+
// : T;
|
|
189
|
+
/**
|
|
190
|
+
* Determines if the endpoint requires path parameters.
|
|
191
|
+
*
|
|
192
|
+
* @template EP - The string representing the endpoint path.
|
|
193
|
+
* @returns {TPathParamsNever | { pathParams: IfParameterizedPath<EP> }}
|
|
194
|
+
* Returns an object with `pathParams` if the endpoint requires parameters, otherwise returns `TPathParamsNever`.
|
|
195
|
+
* @example
|
|
196
|
+
* ```ts
|
|
197
|
+
* type Example = IfNeedPathParams<"/characters/{character_id}/fittings/{fitting_id}/">;
|
|
198
|
+
* // Result: { pathParams: [number, number] }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
type IfNeedPathParams<EP> = IfParameterizedPath<EP> extends never ? TPathParamsNever :
|
|
202
|
+
EP extends ReplacePathParams<EP> ? TPathParamsNever : { pathParams: IfParameterizedPath<EP> };
|
|
203
|
+
/**
|
|
204
|
+
* Infers the original endpoint path from a real endpoint path.
|
|
205
|
+
*
|
|
206
|
+
* @template RealEP - The real endpoint path.
|
|
207
|
+
* @returns {string} The original endpoint path with parameters.
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* type EPOrigin = InferEndpointOrigin<"/characters/123/fittings/456/", TEndPointDelete>;
|
|
211
|
+
* // Result: "/characters/{character_id}/fittings/{fitting_id}/"
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
type InferEndpointOrigin<RealEP extends unknown, Endpoints> = {
|
|
215
|
+
[EP in Endpoints]: RealEP extends ReplacePathParams<EP>
|
|
216
|
+
? EP : never;
|
|
217
|
+
}[Endpoints];
|
|
218
|
+
// type InferEndpointOrigin<RealEP extends string> = {
|
|
219
|
+
// [Method in TESIEntryMethod]: {
|
|
220
|
+
// [EP in keyof TESIResponseOKMap[Method]]: RealEP extends ReplacePathParams<EP>
|
|
221
|
+
// ? EP : never;
|
|
222
|
+
// }[keyof TESIResponseOKMap[Method]]
|
|
223
|
+
// }[TESIEntryMethod];
|
|
224
|
+
|
|
225
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
226
|
+
// Version 2 types
|
|
227
|
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
228
|
+
/**
|
|
229
|
+
* If `EP` (endpoint) is a parameterized path, determines the required number of replacements.
|
|
230
|
+
*
|
|
231
|
+
* @template EP The string representing the endpoint path.
|
|
232
|
+
* @template Opt The type to return if `EP` is not parameterized.
|
|
233
|
+
* @returns {number | [number, number] | Opt}
|
|
234
|
+
* Returns `number` if there is one parameter, `[number, number]` if there are two parameters, otherwise `Opt`.
|
|
235
|
+
*/
|
|
236
|
+
type IfParameterizedPath<EP, Opt = never> = EP extends `${string}/{${string}}${string}`
|
|
237
|
+
? PickPathParameters<EP> extends never
|
|
238
|
+
? Opt : InferKeysLen<PickPathParameters<EP>> extends 1
|
|
239
|
+
? number : [number, number]
|
|
240
|
+
: Opt;
|
|
135
241
|
|
|
136
242
|
/**
|
|
137
243
|
* Identifies the required parameters for a given entry type.
|
|
@@ -143,7 +249,7 @@ declare global {
|
|
|
143
249
|
//* ctt
|
|
144
250
|
type IdentifyParameters<
|
|
145
251
|
Entry, Opt,
|
|
146
|
-
Keys = Exclude<keyof Entry, "result" | "tag">
|
|
252
|
+
Keys = Exclude<keyof Entry, "result" | "tag" | "cachedSeconds">
|
|
147
253
|
> = RequireThese<Opt, Keys> & Pick<Entry, Keys>;
|
|
148
254
|
/*/
|
|
149
255
|
type IdentifyParameters<
|