eve-esi-types 2.2.0 → 2.2.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.
@@ -0,0 +1,26 @@
1
+ /*!
2
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3
+ // Copyright (C) 2025 jeffy-g <hirotom1107@gmail.com>
4
+ // Released under the MIT license
5
+ // https://opensource.org/licenses/mit-license.php
6
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
+ */
8
+ import * as util from "./rq-util.mjs";
9
+ /**
10
+ * @typedef {import("./v2").TESIResponseOKMap} TESIResponseOKMap
11
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
12
+ */
13
+ /** #### Sample of `TESIRequestFunctionSignature`
14
+ *
15
+ * + This is a minimal implementation using `TESIRequestFunctionSignature`.
16
+ * If the response contains "page", only the first page can be retrieved.
17
+ *
18
+ * @type {TESIRequestFunctionSignature<ESIRequestOptions>}
19
+ * @param method - The HTTP method to use for the request
20
+ * @param endpoint - The Path of the ESI endpoint to send the request to
21
+ * @param pathParams - An object of parameters to include in the request
22
+ * @param options - An object of options to include in the request
23
+ * @returns A Promise object containing the response data
24
+ * @throws {ESIRequesError}
25
+ */
26
+ export declare const request: TESIRequestFunctionSignature<util.ESIRequestOptions>;
package/minimal-rq.mjs ADDED
@@ -0,0 +1,78 @@
1
+ /*!
2
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3
+ // Copyright (C) 2025 jeffy-g <hirotom1107@gmail.com>
4
+ // Released under the MIT license
5
+ // https://opensource.org/licenses/mit-license.php
6
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
+ */
8
+ /// <reference types="./v2"/>
9
+ // - - - - - - - - - - - - - - - - - - - -
10
+ // imports
11
+ // - - - - - - - - - - - - - - - - - - - -
12
+ import * as util from "./rq-util.mjs";
13
+ // - - - - - - - - - - - - - - - - - - - -
14
+ // constants, types
15
+ // - - - - - - - - - - - - - - - - - - - -
16
+ // shorthands
17
+ const log = console.log;
18
+ const DEBUG = util.isDebug();
19
+ /**
20
+ * @typedef {import("./v2").TESIResponseOKMap} TESIResponseOKMap
21
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
22
+ */
23
+ // - - - - - - - - - - - - - - - - - - - -
24
+ // main functions
25
+ // - - - - - - - - - - - - - - - - - - - -
26
+ // node scripts/minimal-rq.mjs
27
+ /** #### Sample of `TESIRequestFunctionSignature`
28
+ *
29
+ * + This is a minimal implementation using `TESIRequestFunctionSignature`.
30
+ * If the response contains "page", only the first page can be retrieved.
31
+ *
32
+ * @type {TESIRequestFunctionSignature<ESIRequestOptions>}
33
+ * @param method - The HTTP method to use for the request
34
+ * @param endpoint - The Path of the ESI endpoint to send the request to
35
+ * @param pathParams - An object of parameters to include in the request
36
+ * @param options - An object of options to include in the request
37
+ * @returns A Promise object containing the response data
38
+ * @throws {ESIRequesError}
39
+ */
40
+ export const request = (method, endpoint, pathParams, opt) => {
41
+ if (typeof pathParams === "number") {
42
+ // @ts-ignore
43
+ pathParams = [pathParams];
44
+ }
45
+ if (Array.isArray(pathParams)) {
46
+ // @ts-ignore actualy endp is string
47
+ endpoint = util.replaceCbt(endpoint, pathParams);
48
+ }
49
+ // When only options are provided
50
+ // @ts-ignore
51
+ const actualOpt = /** @type {ESIRequestOptions} */ (opt || pathParams || {});
52
+ const { rqopt, qss } = util.initOptions(method, actualOpt);
53
+ // @ts-ignore actualy endp is string
54
+ const endpointUrl = util.curl(endpoint);
55
+ const url = `${endpointUrl}?${new URLSearchParams(qss) + ""}`;
56
+ DEBUG && log(url);
57
+ return fetch(url, rqopt).then(res => res.json()).catch(reason => {
58
+ throw new util.ESIRequesError(reason.message ? reason.message : reason);
59
+ });
60
+ };
61
+ // It should complete correctly.
62
+ /**
63
+ * @param {TESIRequestFunctionSignature<ESIRequestOptions>} fn
64
+ */
65
+ async function getEVEStatus(fn) {
66
+ const sdeVersion = await util.getSDEVersion();
67
+ log(`sdeVersion: ${sdeVersion}`.blue);
68
+ await util.fireRequestsDoesNotRequireAuth(fn);
69
+ return fn("get", "/status/");
70
+ }
71
+ // type following and run
72
+ // node minimal-rq.mjs
73
+ getEVEStatus(request).then(eveStatus => log(eveStatus));
74
+ // {
75
+ // "players": 16503,
76
+ // "server_version": "2794925",
77
+ // "start_time": "2025-01-21T11:02:34Z"
78
+ // }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve-esi-types",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Extracted the main type of ESI. use for ESI request response types (version 2 only)",
5
5
  "main": "v2/index.d.ts",
6
6
  "scripts": {
@@ -12,10 +12,10 @@
12
12
  },
13
13
  "files": [
14
14
  "v2",
15
+ "*.d.mts",
15
16
  "v2.mjs",
16
- "v2.d.mts",
17
17
  "rq-util.mjs",
18
- "rq-util.d.mts",
18
+ "minimal-rq.mjs",
19
19
  "LICENSE",
20
20
  "*.md",
21
21
  "package.json",
@@ -35,5 +35,8 @@
35
35
  "bugs": {
36
36
  "url": "https://github.com/jeffy-g/eve-esi-types/issues"
37
37
  },
38
- "homepage": "https://github.com/jeffy-g/eve-esi-types#readme"
38
+ "homepage": "https://github.com/jeffy-g/eve-esi-types#readme",
39
+ "devDependencies": {
40
+ "colors": "^1.4.0"
41
+ }
39
42
  }
package/rq-util.d.mts CHANGED
@@ -5,9 +5,7 @@
5
5
  // https://opensource.org/licenses/mit-license.php
6
6
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
7
  */
8
- /**
9
- * @file rq-util.d.mts
10
- */
8
+ import "colors";
11
9
  /**
12
10
  * this always `https://esi.evetech.net`
13
11
  */
@@ -38,6 +36,13 @@ export type ESIRequestOptions = {
38
36
  * Can be an empty object if no authentication is required.description
39
37
  */
40
38
  token?: TAcccessToken;
39
+ /**
40
+ * whether an authorization header is required
41
+ *
42
+ * + When using the `Web Fetch API`, avoid extra `OPTIONS` requests and reduce extra http requests
43
+ *
44
+ * @date 2020/1/23
45
+ */
41
46
  auth?: true;
42
47
  };
43
48
  /**
@@ -52,6 +57,19 @@ export declare class ESIErrorLimitReachedError extends ESIRequesError {
52
57
  constructor();
53
58
  valueOf(): number;
54
59
  }
60
+ /**
61
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
62
+ */
63
+ export declare const isDebug: () => boolean;
64
+ /**
65
+ * @param method
66
+ * @param opt
67
+ * @returns
68
+ */
69
+ export declare const initOptions: (method: string, opt: ESIRequestOptions) => {
70
+ rqopt: RequestInit;
71
+ qss: Record<string, string>;
72
+ };
55
73
  /**
56
74
  * fetch the extra pages
57
75
  *
@@ -82,3 +100,15 @@ export declare const replaceCbt: (endpoint: string, ids: number[]) => string;
82
100
  * + The version parameter can be omitted by using `<version>/<endpoint>`
83
101
  */
84
102
  export declare const curl: (endp: string) => string;
103
+ /**
104
+ * @date 2020/03/31
105
+ * @version 2.0 fix version date string problem (v1.0
106
+ * @type {() => Promise<string>}
107
+ */
108
+ export declare function getSDEVersion(): Promise<string>;
109
+ /**
110
+ * #### Fire a request that does not require authentication.
111
+ *
112
+ * @param {TESIRequestFunctionSignature<ESIRequestOptions>} fn
113
+ */
114
+ export declare function fireRequestsDoesNotRequireAuth(fn: TESIRequestFunctionSignature<ESIRequestOptions>): Promise<void>;
package/rq-util.mjs CHANGED
@@ -5,9 +5,10 @@
5
5
  // https://opensource.org/licenses/mit-license.php
6
6
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
7
  */
8
- /**
9
- * @file rq-util.d.mts
10
- */
8
+ // - - - - - - - - - - - - - - - - - - - -
9
+ // imports
10
+ // - - - - - - - - - - - - - - - - - - - -
11
+ import "colors";
11
12
  // - - - - - - - - - - - - - - - - - - - -
12
13
  // constants, types
13
14
  // - - - - - - - - - - - - - - - - - - - -
@@ -38,6 +39,49 @@ export class ESIErrorLimitReachedError extends ESIRequesError {
38
39
  return 420;
39
40
  }
40
41
  }
42
+ /**
43
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
44
+ */
45
+ // - - - - - - - - - - - - - - - - - - - -
46
+ // utility functions
47
+ // - - - - - - - - - - - - - - - - - - - -
48
+ export const isDebug = () => {
49
+ return process.argv.includes("-debug");
50
+ };
51
+ /**
52
+ * @param method
53
+ * @param opt
54
+ * @returns
55
+ */
56
+ export const initOptions = (method, opt) => {
57
+ /** @type {RequestInit} */
58
+ const rqopt = {
59
+ method,
60
+ mode: "cors",
61
+ cache: "no-cache",
62
+ // @ts-ignore
63
+ signal: opt.cancelable?.signal,
64
+ headers: {}
65
+ };
66
+ const qss = {
67
+ language: "en",
68
+ };
69
+ if (opt.query) {
70
+ // Object.assign(query, options.query); Object.assign is too slow
71
+ const oqs = opt.query;
72
+ Object.keys(oqs).forEach(k => qss[k] = oqs[k]);
73
+ }
74
+ if (opt.auth) {
75
+ // @ts-ignore The header is indeed an object
76
+ rqopt.headers.authorization = `Bearer ${opt.token}`;
77
+ }
78
+ if (opt.body) { // means "POST" method etc
79
+ // @ts-ignore The header is indeed an object
80
+ rqopt.headers["content-type"] = "application/json";
81
+ rqopt.body = JSON.stringify(opt.body);
82
+ }
83
+ return { rqopt, qss };
84
+ };
41
85
  /**
42
86
  * fetch the extra pages
43
87
  *
@@ -105,3 +149,114 @@ export const curl = (endp) => {
105
149
  endp = endp.replace(/^\/+|\/+$/g, "");
106
150
  return `${BASE}/latest/${endp}/`;
107
151
  };
152
+ /**
153
+ * @date 2020/03/31
154
+ * @version 2.0 fix version date string problem (v1.0
155
+ * @type {() => Promise<string>}
156
+ */
157
+ export async function getSDEVersion() {
158
+ const sdeZipUrl = "https://eve-static-data-export.s3-eu-west-1.amazonaws.com/tranquility/sde.zip";
159
+ const date = await fetch(sdeZipUrl, { method: "head", mode: "cors" }).then((/** @type {Response} */ res) => res.headers.get("last-modified")).catch(reason => {
160
+ console.log(reason);
161
+ return new Date();
162
+ });
163
+ if (date) {
164
+ const YMD = new Date(date).toLocaleString(void 0, {
165
+ year: "numeric",
166
+ month: "2-digit",
167
+ day: "2-digit",
168
+ // DEVNOTE: 191215 - "-" character appeared in node v13.3.0 (maybe
169
+ }).replace(/(-|\/|:| )/g, (match, $1) => {
170
+ switch ($1) {
171
+ case "-":
172
+ case "/":
173
+ case ":": return "";
174
+ case " ": return "@";
175
+ }
176
+ return match;
177
+ });
178
+ return `sde-${YMD}-TRANQUILITY`;
179
+ }
180
+ else {
181
+ return "sde-202Xxxxx-TRANQUILITY";
182
+ }
183
+ }
184
+ // It should complete correctly.
185
+ /**
186
+ * #### Fire a request that does not require authentication.
187
+ *
188
+ * @param {TESIRequestFunctionSignature<ESIRequestOptions>} fn
189
+ */
190
+ export async function fireRequestsDoesNotRequireAuth(fn) {
191
+ const clog = console.log.bind(console, '- - -> Get the character data of "CCP Zoetrope"'.magenta);
192
+ const rlog = console.log.bind(console, '- - -> Run ESI request'.cyan);
193
+ try {
194
+ // - - - - - - - - - - - -
195
+ // Character
196
+ // - - - - - - - - - - - -
197
+ // Here, I borrow data from "CCP Zoetrope".
198
+ clog();
199
+ await fn("get", "/characters/{character_id}/", 2112625428).then(log);
200
+ clog('(portrait)');
201
+ await fn("get", "/characters/{character_id}/portrait/", 2112625428).then(log);
202
+ clog('(affiliation)');
203
+ const affiliation = await fn("post", "/characters/affiliation/", { body: [2112625428] });
204
+ log(affiliation);
205
+ clog('(corporation)');
206
+ await fn("get", "/corporations/{corporation_id}/", affiliation[0].corporation_id).then(log);
207
+ rlog("get:/incursions/".green);
208
+ await fn("get", "/incursions/").then(log);
209
+ // - - - - - - - - - - - -
210
+ // Miscellaneous
211
+ // - - - - - - - - - - - -
212
+ rlog("post:/universe/ids/".green);
213
+ const ids = await fn("post", "/universe/ids/", { body: ["the forge", "plex"] });
214
+ log(ids);
215
+ rlog(`get:/markets/${ids?.regions?.[0].id}/orders/?type_id=${ids?.inventory_types?.[0].id}, item PLEX`.green);
216
+ const orders = await fn("get", "/markets/{region_id}/orders/", ids?.regions?.[0].id, {
217
+ query: {
218
+ // page: 1,
219
+ order_type: "sell",
220
+ type_id: ids?.inventory_types?.[0].id
221
+ }
222
+ });
223
+ log(orders.sort((a, b) => a.price - b.price).slice(0, 5));
224
+ rlog("get:/universe/structures/?filter=market".green);
225
+ // query patameter `filter` is optional
226
+ const structures = await fn("get", "/universe/structures/", {
227
+ query: {
228
+ filter: "market"
229
+ }
230
+ });
231
+ log(`/universe/structures/[0]=${structures[0]}, length=${structures.length}`);
232
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
233
+ // The following is code to observe the behavior of completion by generics.
234
+ // Authentication is required, so an error will occur.
235
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
236
+ let ok = await fn("get", "/characters/{character_id}/ship/", 994562, {
237
+ auth: true,
238
+ ignoreError: true,
239
+ token: "token.token.token"
240
+ });
241
+ // in this case, "categories" and "search" is required
242
+ await fn("get", "/characters/{character_id}/search/", 994562, {
243
+ query: {
244
+ categories: ["agent"],
245
+ search: "ok"
246
+ },
247
+ auth: true
248
+ });
249
+ // in this case, "order_type" is required
250
+ await fn("get", "/markets/{region_id}/orders/", 994562, {
251
+ query: {
252
+ order_type: "all"
253
+ },
254
+ });
255
+ // TODO: want TypeScript semantics to throw an error because there is a required query parameter, but it's not possible
256
+ await fn("get", "/characters/{character_id}/search/");
257
+ log(ok);
258
+ }
259
+ catch (e) {
260
+ console.error("Failed to request -", e);
261
+ }
262
+ }
package/tsconfig.json CHANGED
@@ -4,6 +4,7 @@
4
4
  "skipDefaultLibCheck": true,
5
5
  "skipLibCheck": true,
6
6
  "declaration": true,
7
+ // "declarationDir": "./dts",
7
8
  "outDir": ".",
8
9
  "target": "esnext",
9
10
  "module": "esnext",
@@ -13,11 +14,11 @@
13
14
  "strict": true,
14
15
  "moduleResolution": "node",
15
16
  "rootDirs": [
16
- "./"
17
+ "./scripts"
17
18
  ]
18
19
  },
19
20
  "include": [
20
- "./*.mts"
21
+ "./scripts/*.mts"
21
22
  ],
22
23
  "exclude": []
23
24
  }
package/v2/index.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * THIS TSD 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 2.2.0 of the EVE Online ESI response types.
12
+ * @summary This file is auto-generated and defines version 2.2.1 of the EVE Online ESI response types.
13
13
  */
14
14
  import "./get_alliances_ok.d.ts";
15
15
  import "./get_alliances_alliance_id_ok.d.ts";
@@ -205,6 +205,30 @@ type RequireThese<T, K extends keyof T> = T & Required<Pick<T, K>>;
205
205
 
206
206
  declare global {
207
207
 
208
+ /**
209
+ * ### ESI request function all in one signature
210
+ *
211
+ * TESIRequestFunctionSignature is a type that defines the signature of an ESI request function.
212
+ *
213
+ * This function sends a request to a specified endpoint and returns a response.
214
+ *
215
+ * @template ActualOpt - The actual type of the option.
216
+ * Required parameters inferred by typescript are merged.
217
+ * @template M - The HTTP method to use for the request
218
+ * @template EP - The Path of the ESI endpoint to send the request to
219
+ * @template P2 - Parameters to include in the request
220
+ * @template Opt - Options to include in the request
221
+ * If there is a required parameter, its type will be merged with `ActualOpt`
222
+ * @template R - The response type
223
+ */
224
+ type TESIRequestFunctionSignature<ActualOpt> = <
225
+ M extends TESIEntryMethod,
226
+ EP extends keyof TESIResponseOKMap[M],
227
+ P2 extends IsParameterizedPath<EP, number | number[], Opt>,
228
+ Opt extends IdentifyParameters<TESIResponseOKMap[M][EP], ActualOpt>,
229
+ R extends InferESIResponseResult<M, EP>
230
+ >(method: M, endpoint: EP, pathParams?: P2, options?: Opt) => Promise<R>;
231
+
208
232
  /**
209
233
  * is parameterized path
210
234
  */
package/v2.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // import type { TESIResponseOKMap } from "eve-esi-types";
2
- import { curl, replaceCbt, fetchP, ESIRequesError, ESIErrorLimitReachedError } from "./rq-util.mjs";
2
+ import { curl, fetchP, replaceCbt, getSDEVersion, ESIRequesError, initOptions, isDebug, ESIErrorLimitReachedError, fireRequestsDoesNotRequireAuth } from "./rq-util.mjs";
3
3
  // - - - - - - - - - - - - - - - - - - - -
4
4
  // constants, types
5
5
  // - - - - - - - - - - - - - - - - - - - -
@@ -9,19 +9,10 @@ const isArray = Array.isArray;
9
9
  /**
10
10
  * enable/disable console.log
11
11
  */
12
- let LOG = false;
12
+ let LOG = isDebug();
13
13
  /**
14
14
  * @typedef {import("./v2").TESIResponseOKMap} TESIResponseOKMap
15
- */
16
- /**
17
- * @typedef {`${string}.${string}.${string}`} TAcccessToken __{Header}.{Payload}.{Signature}__
18
- * @typedef ESIRequestOptions
19
- * @prop {Record<string, any>} [query] query params for ESI request.
20
- * @prop {any} [body] will need it for `POST` request etc.
21
- * @prop {true=} [auth] Can be an empty object if no authentication is required.description
22
- * @prop {TAcccessToken} [token] Can be an empty object if no authentication is required.description
23
- * @prop {boolean} [ignoreError] if want response data with ignore error then can be set to `true`.
24
- * @prop {AbortController} [cancelable] cancel request immediately
15
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
25
16
  */
26
17
  // - - - - - - - - - - - - - - - - - - - -
27
18
  // module vars, functions
@@ -34,39 +25,6 @@ const incrementAx = (minus) => minus ? ax-- : ax++;
34
25
  // - - - - - - - - - - - - - - - - - - - -
35
26
  // main functions
36
27
  // - - - - - - - - - - - - - - - - - - - -
37
- // It should complete correctly.
38
- async function getEVEStatus() {
39
- try {
40
- const ok = await fire("get", "/characters/{character_id}/ship/", 994562, { auth: true });
41
- // query patameter `filter` is optional
42
- await fire("get", "/universe/structures/", {
43
- query: {
44
- // filter: "market"
45
- }
46
- });
47
- // in this case, "categories" and "search" is required
48
- await fire("get", "/characters/{character_id}/search/", 994562, {
49
- query: {
50
- categories: ["agent"],
51
- search: "ok"
52
- },
53
- auth: true
54
- });
55
- // in this case, "order_type" is required
56
- await fire("get", "/markets/{region_id}/orders/", 994562, {
57
- query: {
58
- order_type: "all"
59
- },
60
- });
61
- // TODO: want TypeScript semantics to throw an error because there is a required query parameter, but it's not possible
62
- await fire("get", "/characters/{character_id}/search/");
63
- console.log(ok);
64
- }
65
- catch (error) {
66
- console.error("Failed to get character ship -", error);
67
- }
68
- return fire("get", "/status/");
69
- }
70
28
  /**
71
29
  * fire ESI request
72
30
  * @template {TESIEntryMethod} M
@@ -95,63 +53,32 @@ export async function fire(mthd, endp, pathParams, opt) {
95
53
  // When only options are provided
96
54
  /** @type {Opt} */
97
55
  // @ts-ignore
98
- const actualOpt = pathParams || opt || {};
99
- /** @type {RequestInit} */
100
- const rqopt = {
101
- method: mthd,
102
- mode: "cors",
103
- cache: "no-cache",
104
- // @ts-ignore
105
- signal: actualOpt.cancelable?.signal,
106
- headers: {}
107
- };
108
- const qss = {
109
- language: "en",
110
- };
111
- if (actualOpt.query) {
112
- // Object.assign(queries, options.queries); Object.assign is too slow
113
- const oqs = actualOpt.query;
114
- for (const k of Object.keys(oqs)) {
115
- qss[k] = oqs[k];
116
- }
117
- }
118
- // DEVNOTE: when datasource is not empty string. (e.g - "singularity"
119
- // in this case must specify datasource.
120
- // disabled since `REMOVING DATASOURCE SINGULARITY`
121
- // if (actualOpt.datasource === "singularity") {
122
- // actualOpt.datasource = "tranquility";
123
- // }
124
- if (actualOpt.auth) {
125
- // @ts-ignore The header is indeed an object
126
- rqopt.headers.authorization = `Bearer ${actualOpt.token}`;
127
- }
128
- if (actualOpt.body) { // means "POST" method etc
129
- // @ts-ignore The header is indeed an object
130
- rqopt.headers["content-type"] = "application/json";
131
- rqopt.body = JSON.stringify(actualOpt.body);
132
- }
56
+ const actualOpt = opt || pathParams || {};
57
+ const { rqopt, qss } = initOptions(mthd, actualOpt);
133
58
  // @ts-ignore actualy endp is string
134
59
  const endpointUrl = curl(endp);
60
+ const url = `${endpointUrl}?${new URLSearchParams(qss) + ""}`;
61
+ LOG && log(url);
135
62
  ax++;
136
63
  try {
137
64
  // @ts-ignore A silly type error will appear, but ignore it.
138
- const res = await fetch(`${endpointUrl}?${new URLSearchParams(qss) + ""}`, rqopt).finally(() => ax--);
139
- const stat = res.status;
65
+ const res = await fetch(url, rqopt).finally(() => ax--);
66
+ const { status } = res;
140
67
  if (!res.ok && !actualOpt.ignoreError) {
141
- if (stat === 420) {
68
+ if (status === 420) {
142
69
  actualOpt.cancelable && actualOpt.cancelable.abort();
143
70
  throw new ESIErrorLimitReachedError();
144
71
  }
145
72
  else {
146
73
  // console.log(res);
147
- throw new ESIRequesError(`${res.statusText} (status=${stat})`);
74
+ throw new ESIRequesError(`${res.statusText} (status=${status})`);
148
75
  }
149
76
  }
150
77
  else {
151
78
  // DEVNOTE: - 204 No Content
152
- if (stat === 204) {
79
+ if (status === 204) {
153
80
  // this result is empty, decided to return status code.
154
- return /** @type {R} */ ({ status: stat });
81
+ return /** @type {R} */ ({ status });
155
82
  }
156
83
  /** @type {R} */
157
84
  const data = await res.json();
@@ -185,10 +112,21 @@ export async function fire(mthd, endp, pathParams, opt) {
185
112
  throw new ESIRequesError(`message: ${e.message}, endpoint=${endp}`);
186
113
  }
187
114
  }
115
+ // It should complete correctly.
116
+ /**
117
+ * @param {TESIRequestFunctionSignature<ESIRequestOptions>} fn
118
+ */
119
+ async function getEVEStatus(fn) {
120
+ const sdeVersion = await getSDEVersion();
121
+ log(`sdeVersion: ${sdeVersion}`.blue);
122
+ await fireRequestsDoesNotRequireAuth(fn);
123
+ return fn("get", "/status/");
124
+ }
188
125
  // type following and run
126
+ // bun scripts/v2.mts
189
127
  // node v2.mjs
190
- // or yarn test:v2
191
- getEVEStatus().then(eveStatus => console.log(eveStatus));
128
+ // or yarn test
129
+ getEVEStatus(fire).then(eveStatus => console.log(eveStatus));
192
130
  // {
193
131
  // "players": 16503,
194
132
  // "server_version": "2794925",