eve-esi-types 2.2.0 → 2.2.4

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/esi-types-util.md CHANGED
@@ -8,19 +8,34 @@
8
8
 
9
9
  ## ESI Types Utility Definitions
10
10
 
11
- ### IsParameterizedPath
11
+ ### TESIRequestFunctionSignature
12
12
 
13
- `IsParameterizedPath<EP, A, B>` is a type to determine if a path is parameterized. If it is, it returns `A`, otherwise it returns `B`.
13
+ `TESIRequestFunctionSignature<ActualOpt>` is a type that defines the signature of an ESI request function,
14
+ which sends a request to a specified endpoint and returns a response.
14
15
 
15
- ```typescript
16
- type IsParameterizedPath<EP, A, B> = EP extends `${string}/{${string}}/${string | ""}` ? A : B;
16
+ ```ts
17
+ type TESIRequestFunctionSignature<ActualOpt> = <
18
+ M extends TESIEntryMethod,
19
+ EP extends keyof TESIResponseOKMap[M],
20
+ P2 extends IfParameterizedPath<EP, Opt>,
21
+ Opt extends IdentifyParameters<TESIResponseOKMap[M][EP], ActualOpt>,
22
+ R extends InferESIResponseResult<M, EP>
23
+ >(method: M, endpoint: EP, pathParams?: P2, options?: Opt) => Promise<R>;
24
+ ```
25
+
26
+ ### IfParameterizedPath
27
+
28
+ `IfParameterizedPath<EP, Opt>` if parameterized path then specify number type, otherwise will be `Opt` type.
29
+
30
+ ```ts
31
+ type IfParameterizedPath<EP, Opt> = EP extends `${string}/{${string}}/${string | ""}` ? number | number[]: Opt;
17
32
  ```
18
33
 
19
34
  ### IdentifyParameters
20
35
 
21
36
  `IdentifyParameters<Entry, Opt>` is a type to identify the required parameters for a given entry type.
22
37
 
23
- ```typescript
38
+ ```ts
24
39
  type IdentifyParameters<Entry, Opt> = Opt & Pick<Entry, Exclude<keyof Entry, "result">>;
25
40
  ```
26
41
 
@@ -28,7 +43,7 @@ type IdentifyParameters<Entry, Opt> = Opt & Pick<Entry, Exclude<keyof Entry, "re
28
43
 
29
44
  `InferESIResponseResult<M extends TESIEntryMethod, EP extends keyof TESIResponseOKMap[M]>` is a type to infer the result type of an ESI response based on the method and endpoint.
30
45
 
31
- ```typescript
46
+ ```ts
32
47
  type InferESIResponseResult<
33
48
  M extends TESIEntryMethod,
34
49
  EP extends keyof TESIResponseOKMap[M]
@@ -39,7 +54,7 @@ type InferESIResponseResult<
39
54
 
40
55
  `TESIEntryMethod` represents the HTTP methods supported by ESI.
41
56
 
42
- ```typescript
57
+ ```ts
43
58
  type TESIEntryMethod = keyof TESIResponseOKMap;
44
59
  ```
45
60
 
@@ -47,7 +62,7 @@ type TESIEntryMethod = keyof TESIResponseOKMap;
47
62
 
48
63
  `TEndPointGet` represents the endpoints for the "get" method.
49
64
 
50
- ```typescript
65
+ ```ts
51
66
  type TEndPointGet = keyof TESIResponseOKMap["get"];
52
67
  ```
53
68
 
@@ -55,7 +70,7 @@ type TEndPointGet = keyof TESIResponseOKMap["get"];
55
70
 
56
71
  `TEndPointPost` represents the endpoints for the "post" method.
57
72
 
58
- ```typescript
73
+ ```ts
59
74
  type TEndPointPost = keyof TESIResponseOKMap["post"];
60
75
  ```
61
76
 
@@ -63,7 +78,7 @@ type TEndPointPost = keyof TESIResponseOKMap["post"];
63
78
 
64
79
  `TEndPointPut` represents the endpoints for the "put" method.
65
80
 
66
- ```typescript
81
+ ```ts
67
82
  type TEndPointPut = keyof TESIResponseOKMap["put"];
68
83
  ```
69
84
 
@@ -71,7 +86,7 @@ type TEndPointPut = keyof TESIResponseOKMap["put"];
71
86
 
72
87
  `TEndPointDelete` represents the endpoints for the "delete" method.
73
88
 
74
- ```typescript
89
+ ```ts
75
90
  type TEndPointDelete = keyof TESIResponseOKMap["delete"];
76
91
  ```
77
92
 
@@ -79,7 +94,7 @@ type TEndPointDelete = keyof TESIResponseOKMap["delete"];
79
94
 
80
95
  `TESIResponseGetEntry<K extends TEndPointGet>` represents the entry details for the "get" method.
81
96
 
82
- ```typescript
97
+ ```ts
83
98
  type TESIResponseGetEntry<K extends TEndPointGet> = TESIResponseOKMap["get"][K];
84
99
  ```
85
100
 
@@ -87,7 +102,7 @@ type TESIResponseGetEntry<K extends TEndPointGet> = TESIResponseOKMap["get"][K];
87
102
 
88
103
  `TESIResponsePutEntry<K extends TEndPointPut>` represents the entry details for the "put" method.
89
104
 
90
- ```typescript
105
+ ```ts
91
106
  type TESIResponsePutEntry<K extends TEndPointPut> = TESIResponseOKMap["put"][K];
92
107
  ```
93
108
 
@@ -95,7 +110,7 @@ type TESIResponsePutEntry<K extends TEndPointPut> = TESIResponseOKMap["put"][K];
95
110
 
96
111
  `TESIResponsePostEntry<K extends TEndPointPost>` represents the entry details for the "post" method.
97
112
 
98
- ```typescript
113
+ ```ts
99
114
  type TESIResponsePostEntry<K extends TEndPointPost> = TESIResponseOKMap["post"][K];
100
115
  ```
101
116
 
@@ -103,6 +118,6 @@ type TESIResponsePostEntry<K extends TEndPointPost> = TESIResponseOKMap["post"][
103
118
 
104
119
  `TESIResponseDeleteEntry<K extends TEndPointDelete>` represents the entry details for the "delete" method.
105
120
 
106
- ```typescript
121
+ ```ts
107
122
  type TESIResponseDeleteEntry<K extends TEndPointDelete> = TESIResponseOKMap["delete"][K];
108
123
  ```
@@ -0,0 +1,29 @@
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
+ import type { IESIRequestFunction } from "./v2";
10
+ /**
11
+ * @typedef {import("./v2").TESIResponseOKMap} TESIResponseOKMap
12
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
13
+ * @typedef {import("./v2").IESIRequestFunction<util.ESIRequestOptions>} IESIRequestFunction
14
+ * @typedef {import("./v2").TESIRequestFunctionMethods<util.ESIRequestOptions>} TESIRequestFunctionMethods
15
+ */
16
+ /** #### Sample of `TESIRequestFunctionSignature`
17
+ *
18
+ * + This is a minimal implementation using `TESIRequestFunctionSignature`.
19
+ * If the response contains "page", only the first page can be retrieved.
20
+ *
21
+ * @type {IESIRequestFunction}
22
+ * @param method - The HTTP method to use for the request
23
+ * @param endpoint - The Path of the ESI endpoint to send the request to
24
+ * @param pathParams - An object of parameters to include in the request
25
+ * @param options - An object of options to include in the request
26
+ * @returns A Promise object containing the response data
27
+ * @throws {ESIRequesError}
28
+ */
29
+ export declare const request: IESIRequestFunction<util.ESIRequestOptions>;
package/minimal-rq.mjs ADDED
@@ -0,0 +1,134 @@
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
+ * @typedef {import("./v2").IESIRequestFunction<util.ESIRequestOptions>} IESIRequestFunction
23
+ * @typedef {import("./v2").TESIRequestFunctionMethods<util.ESIRequestOptions>} TESIRequestFunctionMethods
24
+ */
25
+ // - - - - - - - - - - - - - - - - - - - -
26
+ // main functions
27
+ // - - - - - - - - - - - - - - - - - - - -
28
+ /** #### Sample of `TESIRequestFunctionSignature`
29
+ *
30
+ * + This is a minimal implementation using `TESIRequestFunctionSignature`.
31
+ * If the response contains "page", only the first page can be retrieved.
32
+ *
33
+ * @type {IESIRequestFunction}
34
+ * @param method - The HTTP method to use for the request
35
+ * @param endpoint - The Path of the ESI endpoint to send the request to
36
+ * @param pathParams - An object of parameters to include in the request
37
+ * @param options - An object of options to include in the request
38
+ * @returns A Promise object containing the response data
39
+ * @throws {ESIRequesError}
40
+ */
41
+ // @ts-expect-error
42
+ export const request = (method, endpoint, pathParams, opt) => {
43
+ if (typeof pathParams === "number") {
44
+ // @ts-expect-error
45
+ pathParams = [pathParams];
46
+ }
47
+ if (Array.isArray(pathParams)) {
48
+ // @ts-expect-error actualy endp is string
49
+ endpoint = util.replaceCbt(endpoint, pathParams);
50
+ }
51
+ // When only options are provided
52
+ const actualOpt = /** @type {NonNullable<typeof opt>} */ (opt || pathParams || {});
53
+ const { rqopt, qss } = util.initOptions(method, actualOpt);
54
+ // @ts-expect-error actualy endp is string
55
+ const endpointUrl = util.curl(endpoint);
56
+ const up = new URLSearchParams(qss);
57
+ const url = `${endpointUrl}${up.size ? `?${up}` : ""}`;
58
+ DEBUG && log(url);
59
+ return fetch(url, rqopt).then(res => res.json()).catch(reason => {
60
+ throw new util.ESIRequesError(reason.message ? reason.message : reason);
61
+ });
62
+ };
63
+ //
64
+ // implements rest methods of `request` (IESIRequestFunction)
65
+ //
66
+ /** @type {TESIEntryMethod[]} */ (["get", "post", "put", "delete"]).forEach((method) => {
67
+ request[method] = /** @type {TESIRequestFunctionEachMethod<typeof method>} */ (function (endpoint, params, opt) {
68
+ return this(method, endpoint, params, opt);
69
+ });
70
+ });
71
+ //
72
+ // Delegates implementation to `request` (TESIRequestFunctionMethods)
73
+ //
74
+ const esiMethods = /** @type {TESIRequestFunctionMethods} */ ({});
75
+ ["get", "post", "put", "delete"].forEach((method) => {
76
+ esiMethods[method] = function (endpoint, params, opt) {
77
+ // @ts-ignore
78
+ return request(method, endpoint, params, opt);
79
+ };
80
+ });
81
+ // It should complete correctly.
82
+ /**
83
+ * @param {IESIRequestFunction} fn
84
+ */
85
+ async function getEVEStatus(fn) {
86
+ await util.getSDEVersion().then(sdeVersion => log(`sdeVersion: ${sdeVersion}`.blue));
87
+ await util.fireRequestsDoesNotRequireAuth(fn);
88
+ CaseIESIRequestFunctionMethods: {
89
+ await util.fireRequestsDoesNotRequireAuth(esiMethods);
90
+ }
91
+ const { clog, rlog } = util.getLogger();
92
+ CaseIESIRequestFunction: {
93
+ // - - - - - - - - - - - -
94
+ // Character
95
+ // - - - - - - - - - - - -
96
+ // Here, I borrow data from "CCP Zoetrope".
97
+ rlog("- - - - - - - > run as IESIRequestFunction<ESIRequestOptions>".red);
98
+ clog();
99
+ await fn.get("/characters/{character_id}/", 2112625428).then(log);
100
+ clog('(portrait)');
101
+ await fn.get("/characters/{character_id}/portrait/", 2112625428).then(log);
102
+ clog('(affiliation)');
103
+ const affiliation = await fn.post("/characters/affiliation/", { body: [2112625428] });
104
+ log(affiliation);
105
+ clog('(corporation)');
106
+ await fn.get("/corporations/{corporation_id}/", affiliation[0].corporation_id).then(log);
107
+ rlog("get:/incursions/".green);
108
+ await fn.get("/incursions/").then(log);
109
+ // - - - - - - - - - - - -
110
+ // Miscellaneous
111
+ // - - - - - - - - - - - -
112
+ rlog("post:/universe/ids/".green);
113
+ const ids = await fn.post("/universe/ids/", { body: ["the forge", "plex"] });
114
+ log(ids.inventory_types, ids.regions);
115
+ rlog(`get:/markets/${ids?.regions?.[0].id}/orders/?type_id=${ids?.inventory_types?.[0].id}, item PLEX`.green);
116
+ const orders = await fn.get("/markets/{region_id}/orders/", ids?.regions?.[0].id, {
117
+ query: {
118
+ // page: 1,
119
+ order_type: "sell",
120
+ type_id: ids?.inventory_types?.[0].id
121
+ }
122
+ });
123
+ log(orders.sort((a, b) => a.price - b.price).slice(0, 2));
124
+ }
125
+ return fn.get("/status/");
126
+ }
127
+ // type following and run
128
+ // node minimal-rq.mjs -debug
129
+ getEVEStatus(request).then(eveStatus => log(eveStatus));
130
+ // {
131
+ // "players": 16503,
132
+ // "server_version": "2794925",
133
+ // "start_time": "2025-01-21T11:02:34Z"
134
+ // }
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "eve-esi-types",
3
- "version": "2.2.0",
3
+ "version": "2.2.4",
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": {
7
- "test": "node v2.mjs"
7
+ "test": "node v2.mjs -debug",
8
+ "test:mini": "node minimal-rq.mjs -debug"
8
9
  },
9
10
  "repository": {
10
11
  "type": "git",
@@ -12,10 +13,8 @@
12
13
  },
13
14
  "files": [
14
15
  "v2",
15
- "v2.mjs",
16
- "v2.d.mts",
17
- "rq-util.mjs",
18
- "rq-util.d.mts",
16
+ "*.d.mts",
17
+ "*.mjs",
19
18
  "LICENSE",
20
19
  "*.md",
21
20
  "package.json",
@@ -35,5 +34,8 @@
35
34
  "bugs": {
36
35
  "url": "https://github.com/jeffy-g/eve-esi-types/issues"
37
36
  },
38
- "homepage": "https://github.com/jeffy-g/eve-esi-types#readme"
37
+ "homepage": "https://github.com/jeffy-g/eve-esi-types#readme",
38
+ "devDependencies": {
39
+ "colors.ts": "^1.0.20"
40
+ }
39
41
  }
package/rq-util.d.mts CHANGED
@@ -5,9 +5,8 @@
5
5
  // https://opensource.org/licenses/mit-license.php
6
6
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
7
  */
8
- /**
9
- * @file rq-util.d.mts
10
- */
8
+ import "colors.ts";
9
+ import type { TESIRequestFunctionMethods } from "./v2";
11
10
  /**
12
11
  * this always `https://esi.evetech.net`
13
12
  */
@@ -38,6 +37,13 @@ export type ESIRequestOptions = {
38
37
  * Can be an empty object if no authentication is required.description
39
38
  */
40
39
  token?: TAcccessToken;
40
+ /**
41
+ * whether an authorization header is required
42
+ *
43
+ * + When using the `Web Fetch API`, avoid extra `OPTIONS` requests and reduce extra http requests
44
+ *
45
+ * @date 2020/1/23
46
+ */
41
47
  auth?: true;
42
48
  };
43
49
  /**
@@ -52,6 +58,19 @@ export declare class ESIErrorLimitReachedError extends ESIRequesError {
52
58
  constructor();
53
59
  valueOf(): number;
54
60
  }
61
+ /**
62
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
63
+ */
64
+ export declare const isDebug: () => boolean;
65
+ /**
66
+ * @param {string} method
67
+ * @param {ESIRequestOptions} opt
68
+ * @returns
69
+ */
70
+ export declare const initOptions: (method: string, opt: ESIRequestOptions) => {
71
+ rqopt: RequestInit;
72
+ qss: Record<string, string>;
73
+ };
55
74
  /**
56
75
  * fetch the extra pages
57
76
  *
@@ -59,11 +78,11 @@ export declare class ESIErrorLimitReachedError extends ESIRequesError {
59
78
  *
60
79
  * @param {string} endpointUrl
61
80
  * @param {RequestInit} rqopt request options
62
- * @param {Record<string, any>} qs queries
81
+ * @param {URLSearchParams} rqp queries
63
82
  * @param {number} pc pageCount
64
83
  * @param {(minus?: number) => void=} increment
65
84
  */
66
- export declare const fetchP: <T extends unknown>(endpointUrl: string, rqopt: RequestInit, qs: Record<string, any>, pc: number, increment?: (minus?: Truthy) => void) => Promise<T | null>;
85
+ export declare const fetchP: <T extends unknown>(endpointUrl: string, rqopt: RequestInit, rqp: URLSearchParams, pc: number, increment?: (minus?: Truthy) => void) => Promise<T | null>;
67
86
  /** ### replace (C)urly (B)races (T)oken
68
87
  *
69
88
  * @example
@@ -79,6 +98,22 @@ export declare const replaceCbt: (endpoint: string, ids: number[]) => string;
79
98
  /**
80
99
  *
81
100
  * @param {string} endp this means endpoint url fragment like `/characters/{character_id}/` or `/characters/{character_id}/agents_research/`
82
- * + The version parameter can be omitted by using `<version>/<endpoint>`
101
+ * + The version parameter is forced to apply `latest`
83
102
  */
84
103
  export declare const curl: (endp: string) => string;
104
+ /**
105
+ * @date 2020/03/31
106
+ * @version 2.1
107
+ * @type {() => Promise<string>}
108
+ */
109
+ export declare function getSDEVersion(): Promise<string>;
110
+ export declare function getLogger(): {
111
+ clog: (...args: any[]) => void;
112
+ rlog: (...args: any[]) => void;
113
+ };
114
+ /**
115
+ * #### Fire a request that does not require authentication.
116
+ *
117
+ * @param {TESIRequestFunctionSignature<ESIRequestOptions> | TESIRequestFunctionMethods} fn
118
+ */
119
+ export declare function fireRequestsDoesNotRequireAuth(fn: TESIRequestFunctionSignature<ESIRequestOptions> | TESIRequestFunctionMethods<ESIRequestOptions>): Promise<void>;
package/rq-util.mjs CHANGED
@@ -5,9 +5,11 @@
5
5
  // https://opensource.org/licenses/mit-license.php
6
6
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
7
  */
8
- /**
9
- * @file rq-util.d.mts
10
- */
8
+ /// <reference types="./v2"/>
9
+ // - - - - - - - - - - - - - - - - - - - -
10
+ // imports
11
+ // - - - - - - - - - - - - - - - - - - - -
12
+ import "colors.ts";
11
13
  // - - - - - - - - - - - - - - - - - - - -
12
14
  // constants, types
13
15
  // - - - - - - - - - - - - - - - - - - - -
@@ -38,6 +40,48 @@ export class ESIErrorLimitReachedError extends ESIRequesError {
38
40
  return 420;
39
41
  }
40
42
  }
43
+ /**
44
+ * @typedef {import("./rq-util.mjs").ESIRequestOptions} ESIRequestOptions
45
+ */
46
+ // - - - - - - - - - - - - - - - - - - - -
47
+ // utility functions
48
+ // - - - - - - - - - - - - - - - - - - - -
49
+ export const isDebug = () => {
50
+ return process.argv.includes("-debug");
51
+ };
52
+ /**
53
+ * @param {string} method
54
+ * @param {ESIRequestOptions} opt
55
+ * @returns
56
+ */
57
+ export const initOptions = (method, opt) => {
58
+ /** @type {RequestInit} */
59
+ const rqopt = {
60
+ method,
61
+ mode: "cors",
62
+ cache: "no-cache",
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
  *
@@ -45,13 +89,12 @@ export class ESIErrorLimitReachedError extends ESIRequesError {
45
89
  *
46
90
  * @param {string} endpointUrl
47
91
  * @param {RequestInit} rqopt request options
48
- * @param {Record<string, any>} qs queries
92
+ * @param {URLSearchParams} rqp queries
49
93
  * @param {number} pc pageCount
50
94
  * @param {(minus?: number) => void=} increment
51
95
  */
52
- export const fetchP = async (endpointUrl, rqopt, qs, pc, increment = () => { }) => {
96
+ export const fetchP = async (endpointUrl, rqopt, rqp, pc, increment = () => { }) => {
53
97
  const rqs = [];
54
- const rqp = new URLSearchParams(qs);
55
98
  for (let i = 2; i <= pc;) {
56
99
  rqp.set("page", (i++) + "");
57
100
  increment();
@@ -99,9 +142,145 @@ export const replaceCbt = (endpoint, ids) => {
99
142
  /**
100
143
  *
101
144
  * @param {string} endp this means endpoint url fragment like `/characters/{character_id}/` or `/characters/{character_id}/agents_research/`
102
- * + The version parameter can be omitted by using `<version>/<endpoint>`
145
+ * + The version parameter is forced to apply `latest`
103
146
  */
104
147
  export const curl = (endp) => {
105
148
  endp = endp.replace(/^\/+|\/+$/g, "");
106
149
  return `${BASE}/latest/${endp}/`;
107
150
  };
151
+ /**
152
+ * @date 2020/03/31
153
+ * @version 2.1
154
+ * @type {() => Promise<string>}
155
+ */
156
+ export async function getSDEVersion() {
157
+ const sdeZipUrl = "https://eve-static-data-export.s3-eu-west-1.amazonaws.com/tranquility/sde.zip";
158
+ try {
159
+ const res = await fetch(sdeZipUrl, { method: "head", mode: "cors" });
160
+ const date = res.headers.get("last-modified");
161
+ if (date) {
162
+ const YMD = new Date(date).toLocaleDateString('en-CA').replace(/-/g, '');
163
+ return `sde-${YMD}-TRANQUILITY`;
164
+ }
165
+ else {
166
+ console.error("Failed to retrieve 'last-modified' header.");
167
+ return "sde-202Xxxxx-TRANQUILITY";
168
+ }
169
+ }
170
+ catch (e) {
171
+ console.error("Error fetching SDE version:", e);
172
+ return "sde-202Xxxxx-TRANQUILITY";
173
+ }
174
+ }
175
+ export function getLogger() {
176
+ const clog = console.log.bind(console, '- - -> Get the character data of "CCP Zoetrope"'.magenta);
177
+ const rlog = console.log.bind(console, '- - -> Run ESI request'.cyan);
178
+ return { clog, rlog };
179
+ }
180
+ /**
181
+ * Need typescript v5.5 later
182
+ * @import * as ESI from "./v2";
183
+ * @typedef {ESI.TESIResponseOKMap} TESIResponseOKMap
184
+ * @typedef {ESI.IESIRequestFunction<ESIRequestOptions>} IESIRequestFunction
185
+ * @typedef {ESI.TESIRequestFunctionMethods<ESIRequestOptions>} TESIRequestFunctionMethods
186
+ */
187
+ /**
188
+ * #### Fire a request that does not require authentication.
189
+ *
190
+ * @template {TESIEntryMethod} M
191
+ * @template {keyof TESIResponseOKMap[M]} EP
192
+ * @template {IfParameterizedPath<EP, Opt>} P2
193
+ * @template {IdentifyParameters<TESIResponseOKMap[M][EP], ESIRequestOptions>} Opt
194
+ * @template {InferESIResponseResult<M, EP>} R
195
+ *
196
+ * @param {TESIRequestFunctionSignature<ESIRequestOptions> | TESIRequestFunctionMethods} fn
197
+ * @param {M} method
198
+ * @param {EP} endpoint
199
+ * @param {P2} [pathParams]
200
+ * @param {Opt} [opt]
201
+ * @returns {Promise<R>}
202
+ */
203
+ function fireWithoutAuth(fn, method, endpoint, pathParams, opt) {
204
+ if (typeof fn === "function") {
205
+ return fn(method, endpoint, pathParams, opt);
206
+ }
207
+ return fn[method](endpoint, pathParams, opt);
208
+ }
209
+ // It should complete correctly.
210
+ /**
211
+ * #### Fire a request that does not require authentication.
212
+ *
213
+ * @param {TESIRequestFunctionSignature<ESIRequestOptions> | TESIRequestFunctionMethods} fn
214
+ */
215
+ export async function fireRequestsDoesNotRequireAuth(fn) {
216
+ const { clog, rlog } = getLogger();
217
+ try {
218
+ // - - - - - - - - - - - -
219
+ // Character
220
+ // - - - - - - - - - - - -
221
+ // Here, I borrow data from "CCP Zoetrope".
222
+ clog();
223
+ await fireWithoutAuth(fn, "get", "/characters/{character_id}/", 2112625428).then(log);
224
+ clog('(portrait)');
225
+ await fireWithoutAuth(fn, "get", "/characters/{character_id}/portrait/", 2112625428).then(log);
226
+ clog('(affiliation)');
227
+ const affiliation = await fireWithoutAuth(fn, "post", "/characters/affiliation/", { body: [2112625428] });
228
+ log(affiliation);
229
+ clog('(corporation)');
230
+ await fireWithoutAuth(fn, "get", "/corporations/{corporation_id}/", affiliation[0].corporation_id).then(log);
231
+ rlog("get:/incursions/".green);
232
+ await fireWithoutAuth(fn, "get", "/incursions/").then(log);
233
+ // - - - - - - - - - - - -
234
+ // Miscellaneous
235
+ // - - - - - - - - - - - -
236
+ rlog("post:/universe/ids/".green);
237
+ const ids = await fireWithoutAuth(fn, "post", "/universe/ids/", { body: ["the forge", "plex"] });
238
+ log(ids.inventory_types, ids.regions);
239
+ rlog(`get:/markets/${ids?.regions?.[0].id}/orders/?type_id=${ids?.inventory_types?.[0].id}, item PLEX`.green);
240
+ const orders = await fireWithoutAuth(fn, "get", "/markets/{region_id}/orders/", ids?.regions?.[0].id, {
241
+ query: {
242
+ // page: 1,
243
+ order_type: "sell",
244
+ type_id: ids?.inventory_types?.[0].id
245
+ }
246
+ });
247
+ log(orders.sort((a, b) => a.price - b.price).slice(0, 2));
248
+ rlog("get:/universe/structures/?filter=market".green);
249
+ // query patameter `filter` is optional
250
+ const structures = await fireWithoutAuth(fn, "get", "/universe/structures/", {
251
+ query: {
252
+ filter: "market"
253
+ }
254
+ });
255
+ log(`/universe/structures/[0]=${structures[0]}, length=${structures.length}`);
256
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
257
+ // The following is code to observe the behavior of completion by generics.
258
+ // Authentication is required, so an error will occur.
259
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
260
+ let ok = await fireWithoutAuth(fn, "get", "/characters/{character_id}/ship/", 994562, {
261
+ auth: true,
262
+ ignoreError: true,
263
+ token: "token.token.token"
264
+ });
265
+ // in this case, "categories" and "search" is required
266
+ await fireWithoutAuth(fn, "get", "/characters/{character_id}/search/", 994562, {
267
+ query: {
268
+ categories: ["agent"],
269
+ search: "ok"
270
+ },
271
+ auth: true
272
+ });
273
+ // in this case, "order_type" is required
274
+ await fireWithoutAuth(fn, "get", "/markets/{region_id}/orders/", 994562, {
275
+ query: {
276
+ order_type: "all"
277
+ },
278
+ });
279
+ // TODO: want TypeScript semantics to throw an error because there is a required query parameter, but it's not possible
280
+ await fireWithoutAuth(fn, "get", "/characters/{character_id}/search/");
281
+ log(ok);
282
+ }
283
+ catch (e) {
284
+ console.error("Failed to request -", e);
285
+ }
286
+ }
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,13 @@
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
- "exclude": []
23
+ "exclude": [
24
+ "./scripts/auth-*"
25
+ ]
23
26
  }