tornapi-typescript 2.0.2 → 3.0.0

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/dist/index.d.ts CHANGED
@@ -22,6 +22,7 @@ export type UserCrimeUniquesRewardAmmoEnum = "standard" | "special";
22
22
  export type RaceStatusEnum = "open" | "in_progress" | "finished";
23
23
  export type TornHofCategory = "level" | "busts" | "rank" | "traveltime" | "workstats" | "networth" | "revives" | "defends" | "offences" | "attacks" | "awards" | "racingwins" | "racingpoints" | "racingskill";
24
24
  export type TornFactionHofCategory = "respect" | "chains" | "rank";
25
+ export type TornOrganizedCrimePositionId = "P1" | "P2" | "P3" | "P4" | "P5" | "P6";
25
26
  export type FactionTerritoryWarResultEnum = "success_assault" | "fail_assault" | "end_with_nap" | "end_with_destroy_attack" | "end_with_destroy_defense" | "end_with_peace_treaty";
26
27
  export type FactionAttackResult = "None" | "Attacked" | "Mugged" | "Hospitalized" | "Arrested" | "Looted" | "Lost" | "Stalemate" | "Assist" | "Escape" | "Timeout" | "Special" | "Bounty" | "Interrupted";
27
28
  export type RaceCarUpgradeCategory = "Aerodynamics" | "Brakes" | "Engine" | "Exhaust and Induction" | "Fuel" | "Safety" | "Suspension" | "Transmission" | "Weight Reduction" | "Wheels and Tyres";
@@ -1807,6 +1808,8 @@ export interface FactionCrimeReward {
1807
1808
  }
1808
1809
  export interface FactionCrimeSlot {
1809
1810
  position: string;
1811
+ position_id: TornOrganizedCrimePositionId;
1812
+ position_number: number;
1810
1813
  item_requirement: {
1811
1814
  id: ItemId;
1812
1815
  /** Shows if the item is reusable or consumed during the crime. */
@@ -2048,6 +2051,11 @@ export interface KeyInfoResponse {
2048
2051
  forum: ForumSelectionName[];
2049
2052
  key: KeySelectionName[];
2050
2053
  };
2054
+ user: {
2055
+ faction_id: FactionId | null;
2056
+ company_id: CompanyId | null;
2057
+ id: UserId;
2058
+ };
2051
2059
  access: {
2052
2060
  level: number;
2053
2061
  type: ApiKeyAccessTypeEnum;
@@ -2339,7 +2347,7 @@ export interface TornOrganizedCrimeScope {
2339
2347
  return: number;
2340
2348
  }
2341
2349
  export interface TornOrganizedCrimeSlot {
2342
- id: string;
2350
+ id: TornOrganizedCrimePositionId;
2343
2351
  name: string;
2344
2352
  required_item: TornOrganizedCrimeRequiredItem | null;
2345
2353
  }
@@ -2444,7 +2452,7 @@ export interface TornCalendarResponse {
2444
2452
  events: TornCalendarActivity[];
2445
2453
  };
2446
2454
  }
2447
- export interface TornHof {
2455
+ export interface TornHofBasic {
2448
2456
  id: UserId;
2449
2457
  username: string;
2450
2458
  faction_id: FactionId;
@@ -2458,6 +2466,10 @@ export interface TornHof {
2458
2466
  value: number | string | number;
2459
2467
  rank: string;
2460
2468
  }
2469
+ export interface TornHofWithOffenses extends TornHofBasic {
2470
+ criminal_offenses: number;
2471
+ }
2472
+ export type TornHof = TornHofBasic | TornHofWithOffenses;
2461
2473
  export interface TornHofResponse {
2462
2474
  hof: TornHof[];
2463
2475
  _metadata: RequestMetadataWithLinks;
@@ -3297,6 +3309,10 @@ export interface UserV1 extends BaseSchema {
3297
3309
  bazaarcustomers: number;
3298
3310
  bazaarprofit: number;
3299
3311
  bazaarsales: number;
3312
+ itemmarketsales: number;
3313
+ itemmarketcustomers: number;
3314
+ itemmarketrevenue: number;
3315
+ itemmarketfees: number;
3300
3316
  bestactivestreak: number;
3301
3317
  bestdamage: number;
3302
3318
  bestkillstreak: number;
@@ -6398,10 +6414,10 @@ export type SectionV1 = keyof SectionsV1Map;
6398
6414
  export type SectionV2 = keyof SectionsV2Map;
6399
6415
  export type SelectionV1<Sec extends SectionV1> = keyof SectionsV1Map[Sec]["selections"];
6400
6416
  export type SelectionV2<Sec extends SectionV2> = keyof SectionsV2Map[Sec]["selections"];
6401
- export type ParamsV1<Sec extends SectionV1, Sel extends keyof SectionsV1Map[Sec]["selections"]> = SectionsV1Map[Sec]["selections"][Sel] extends {
6417
+ export type ParamsV1<Sec extends SectionV1, Sel extends SelectionV1<Sec>> = SectionsV1Map[Sec]["selections"][Sel] extends {
6402
6418
  params: any;
6403
6419
  } ? SectionsV1Map[Sec]["selections"][Sel]["params"] : never;
6404
- export type ParamsV2<Sec extends SectionV2, Sel extends keyof SectionsV2Map[Sec]["selections"]> = SectionsV2Map[Sec]["selections"][Sel] extends {
6420
+ export type ParamsV2<Sec extends SectionV2, Sel extends SelectionV2<Sec>> = SectionsV2Map[Sec]["selections"][Sel] extends {
6405
6421
  params: any;
6406
6422
  } ? SectionsV2Map[Sec]["selections"][Sel]["params"] : never;
6407
6423
  export type GetArgumentV1<Sec extends SectionV1, Sel extends keyof SectionsV1Map[Sec]["selections"]> = ParamsV1<Sec, Sel> extends never ? {
@@ -6459,11 +6475,44 @@ export type CacheV2<Sec extends SectionV2, Sel extends keyof SectionsV2Map[Sec][
6459
6475
  set: (key: GetArgumentV2<Sec, Sel>, value: GetResponseV2<Sec, Sel>, expiry: number) => void | Promise<void>;
6460
6476
  };
6461
6477
  type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
6462
- export declare function tornApiGetV1<Sec extends SectionV1, Sel extends SelectionV1<Sec>>({ section, selections, id, params, key, comment, cache, expiry, }: GetArgumentV1<Sec, Sel> & {
6478
+ export interface HTTPClient {
6479
+ getJson(url: URL): Promise<any>;
6480
+ }
6481
+ export declare class FetchHTTPClient implements HTTPClient {
6482
+ getJson(url: URL): Promise<any>;
6483
+ }
6484
+ interface ClientOptions {
6485
+ httpClient?: HTTPClient;
6486
+ defaultComment?: string;
6487
+ }
6488
+ export declare class TornApiClient {
6489
+ private readonly httpClient;
6490
+ private readonly defaultComment?;
6491
+ constructor(options?: ClientOptions);
6492
+ getV1<Sec extends SectionV1, Sel extends SelectionV1<Sec>>({ section, selections, id, params, key, comment, cache, expiry, }: GetArgumentV1<Sec, Sel> & {
6493
+ cache?: CacheV1<Sec, Sel>;
6494
+ expiry?: number;
6495
+ }): Promise<GetResponseV1<Sec, Sel>>;
6496
+ getV2<Sec extends SectionV2, Sel extends SelectionV2<Sec>>({ section, selections, id, params, key, comment, cache, expiry, }: GetArgumentV2<Sec, Sel> & {
6497
+ cache?: CacheV2<Sec, Sel>;
6498
+ expiry?: number;
6499
+ }): Promise<GetResponseV2<Sec, Sel>>;
6500
+ private handleError;
6501
+ private populateUrl;
6502
+ }
6503
+ /**
6504
+ * @deprecated Move to TornApiClient instead of using this. Will be removed in an upcoming version.
6505
+ * @see TornApiClient
6506
+ */
6507
+ export declare function tornApiGetV1<Sec extends SectionV1, Sel extends SelectionV1<Sec>>(options: GetArgumentV1<Sec, Sel> & {
6463
6508
  cache?: CacheV1<Sec, Sel>;
6464
6509
  expiry?: number;
6465
6510
  }): Promise<GetResponseV1<Sec, Sel>>;
6466
- export declare function tornApiGetV2<Sec extends SectionV2, Sel extends SelectionV2<Sec>>({ section, selections, id, params, key, comment, cache, expiry, }: GetArgumentV2<Sec, Sel> & {
6511
+ /**
6512
+ * @deprecated Move to TornApiClient instead of using this. Will be removed in an upcoming version.
6513
+ * @see TornApiClient
6514
+ */
6515
+ export declare function tornApiGetV2<Sec extends SectionV2, Sel extends SelectionV2<Sec>>(options: GetArgumentV2<Sec, Sel> & {
6467
6516
  cache?: CacheV2<Sec, Sel>;
6468
6517
  expiry?: number;
6469
6518
  }): Promise<GetResponseV2<Sec, Sel>>;
package/dist/index.js CHANGED
@@ -34,81 +34,80 @@ export var TornApiError;
34
34
  TornApiError[TornApiError["SELECTION_ONLY_AVAILABLE_API_V2"] = 23] = "SELECTION_ONLY_AVAILABLE_API_V2";
35
35
  TornApiError[TornApiError["CLOSED_TEMPORARILY"] = 24] = "CLOSED_TEMPORARILY";
36
36
  })(TornApiError || (TornApiError = {}));
37
- export async function tornApiGetV1({ section, selections, id, params = {}, key, comment, cache, expiry, }) {
38
- const cached = await cache?.get({
39
- section,
40
- selections,
41
- id,
42
- params,
43
- key,
44
- });
45
- if (cached)
46
- return cached;
47
- const url = new URL(`https://api.torn.com/${section}/${id ?? ""}`);
48
- selections?.length &&
49
- url.searchParams.set("selections", selections.join(","));
50
- url.searchParams.set("key", key);
51
- if (comment)
52
- url.searchParams.set("comment", comment);
53
- Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
54
- return await fetch(url)
55
- .then((res) => res.json())
56
- .then(addToCache)
57
- .catch(handleError);
58
- function handleError(e) {
59
- console.error(e);
60
- return { error: { code: -1, error: generateErrorString(e) } };
61
- function generateErrorString(e) {
62
- switch (typeof e) {
63
- case "string":
64
- return e;
65
- case "object": {
66
- if (e instanceof Error)
67
- return e.message;
68
- return JSON.stringify(e);
69
- }
70
- default:
71
- return e.toString();
72
- }
73
- }
37
+ export class FetchHTTPClient {
38
+ async getJson(url) {
39
+ const response = await fetch(url);
40
+ return await response.json();
74
41
  }
75
- function addToCache(response) {
76
- if ("error" in response)
42
+ }
43
+ export class TornApiClient {
44
+ httpClient;
45
+ defaultComment;
46
+ constructor(options = {}) {
47
+ this.httpClient = options.httpClient ?? new FetchHTTPClient();
48
+ this.defaultComment = options.defaultComment;
49
+ }
50
+ async getV1({ section, selections, id, params = {}, key, comment, cache, expiry, }) {
51
+ const cached = await cache?.get({
52
+ section,
53
+ selections,
54
+ id,
55
+ params,
56
+ key,
57
+ });
58
+ if (cached)
59
+ return cached;
60
+ const url = new URL(`https://api.torn.com/${section}/${id ?? ""}`);
61
+ this.populateUrl(url, key, (selections ?? []), comment, params ?? {});
62
+ return this.httpClient
63
+ .getJson(url)
64
+ .then(addToCache)
65
+ .catch(this.handleError);
66
+ function addToCache(response) {
67
+ if ("error" in response)
68
+ return response;
69
+ cache?.set({
70
+ section,
71
+ selections,
72
+ id,
73
+ params,
74
+ key,
75
+ }, response, expiry ?? Date.now() + 30_000);
77
76
  return response;
78
- cache?.set({
77
+ }
78
+ }
79
+ async getV2({ section, selections, id, params = {}, key, comment, cache, expiry, }) {
80
+ const cached = await cache?.get({
79
81
  section,
80
82
  selections,
81
83
  id,
82
84
  params,
83
85
  key,
84
- }, response, expiry ?? Date.now() + 30_000);
85
- return response;
86
+ });
87
+ if (cached)
88
+ return cached;
89
+ const url = new URL(`https://api.torn.com/v2/${section}/${id ?? ""}`);
90
+ this.populateUrl(url, key, (selections ?? []), comment, params ?? {});
91
+ return this.httpClient
92
+ .getJson(url)
93
+ .then(addToCache)
94
+ .catch(this.handleError);
95
+ function addToCache(response) {
96
+ if ("error" in response)
97
+ return response;
98
+ cache?.set({
99
+ section,
100
+ selections,
101
+ id,
102
+ params,
103
+ key,
104
+ }, response, expiry ?? Date.now() + 30_000);
105
+ return response;
106
+ }
86
107
  }
87
- }
88
- export async function tornApiGetV2({ section, selections, id, params = {}, key, comment, cache, expiry, }) {
89
- const cached = await cache?.get({
90
- section,
91
- selections,
92
- id,
93
- params,
94
- key,
95
- });
96
- if (cached)
97
- return cached;
98
- const url = new URL(`https://api.torn.com/v2/${section}/${id ?? ""}`);
99
- selections?.length &&
100
- url.searchParams.set("selections", selections.join(","));
101
- url.searchParams.set("key", key);
102
- if (comment)
103
- url.searchParams.set("comment", comment);
104
- Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
105
- return await fetch(url)
106
- .then((res) => res.json())
107
- .then(addToCache)
108
- .catch(handleError);
109
- function handleError(e) {
110
- console.error(e);
111
- return { error: { code: -1, error: generateErrorString(e) } };
108
+ handleError(error) {
109
+ console.error(error);
110
+ return { error: { code: -1, error: generateErrorString(error) } };
112
111
  function generateErrorString(e) {
113
112
  switch (typeof e) {
114
113
  case "string":
@@ -123,16 +122,30 @@ export async function tornApiGetV2({ section, selections, id, params = {}, key,
123
122
  }
124
123
  }
125
124
  }
126
- function addToCache(response) {
127
- if ("error" in response)
128
- return response;
129
- cache?.set({
130
- section,
131
- selections,
132
- id,
133
- params,
125
+ populateUrl(url, key, selections, comment, params) {
126
+ const allParams = {
134
127
  key,
135
- }, response, expiry ?? Date.now() + 30_000);
136
- return response;
128
+ comment: comment ?? this.defaultComment,
129
+ selections: selections.length ? selections.join(",") : undefined,
130
+ ...params,
131
+ };
132
+ Object.entries(allParams)
133
+ .filter((entry) => !!entry[1])
134
+ .forEach(([key, value]) => url.searchParams.set(key, value));
137
135
  }
138
136
  }
137
+ const DEFAULT_CLIENT = new TornApiClient();
138
+ /**
139
+ * @deprecated Move to TornApiClient instead of using this. Will be removed in an upcoming version.
140
+ * @see TornApiClient
141
+ */
142
+ export async function tornApiGetV1(options) {
143
+ return DEFAULT_CLIENT.getV1(options);
144
+ }
145
+ /**
146
+ * @deprecated Move to TornApiClient instead of using this. Will be removed in an upcoming version.
147
+ * @see TornApiClient
148
+ */
149
+ export async function tornApiGetV2(options) {
150
+ return DEFAULT_CLIENT.getV2(options);
151
+ }
package/dist/index.ts CHANGED
@@ -4303,6 +4303,14 @@ export type TornHofCategory =
4303
4303
 
4304
4304
  export type TornFactionHofCategory = "respect" | "chains" | "rank";
4305
4305
 
4306
+ export type TornOrganizedCrimePositionId =
4307
+ | "P1"
4308
+ | "P2"
4309
+ | "P3"
4310
+ | "P4"
4311
+ | "P5"
4312
+ | "P6";
4313
+
4306
4314
  export type FactionTerritoryWarResultEnum =
4307
4315
  | "success_assault"
4308
4316
  | "fail_assault"
@@ -7050,6 +7058,8 @@ export interface FactionCrimeReward {
7050
7058
 
7051
7059
  export interface FactionCrimeSlot {
7052
7060
  position: string;
7061
+ position_id: TornOrganizedCrimePositionId;
7062
+ position_number: number;
7053
7063
  item_requirement: {
7054
7064
  id: ItemId;
7055
7065
  /** Shows if the item is reusable or consumed during the crime. */
@@ -7325,6 +7335,11 @@ export interface KeyInfoResponse {
7325
7335
  forum: ForumSelectionName[];
7326
7336
  key: KeySelectionName[];
7327
7337
  };
7338
+ user: {
7339
+ faction_id: FactionId | null;
7340
+ company_id: CompanyId | null;
7341
+ id: UserId;
7342
+ };
7328
7343
  access: {
7329
7344
  level: number;
7330
7345
  type: ApiKeyAccessTypeEnum;
@@ -7668,7 +7683,7 @@ export interface TornOrganizedCrimeScope {
7668
7683
  }
7669
7684
 
7670
7685
  export interface TornOrganizedCrimeSlot {
7671
- id: string;
7686
+ id: TornOrganizedCrimePositionId;
7672
7687
  name: string;
7673
7688
  required_item: TornOrganizedCrimeRequiredItem | null;
7674
7689
  }
@@ -7791,7 +7806,7 @@ export interface TornCalendarResponse {
7791
7806
  };
7792
7807
  }
7793
7808
 
7794
- export interface TornHof {
7809
+ export interface TornHofBasic {
7795
7810
  id: UserId;
7796
7811
  username: string;
7797
7812
  faction_id: FactionId;
@@ -7806,6 +7821,12 @@ export interface TornHof {
7806
7821
  rank: string;
7807
7822
  }
7808
7823
 
7824
+ export interface TornHofWithOffenses extends TornHofBasic {
7825
+ criminal_offenses: number;
7826
+ }
7827
+
7828
+ export type TornHof = TornHofBasic | TornHofWithOffenses;
7829
+
7809
7830
  export interface TornHofResponse {
7810
7831
  hof: TornHof[];
7811
7832
  _metadata: RequestMetadataWithLinks;
@@ -8668,6 +8689,10 @@ export interface UserV1 extends BaseSchema {
8668
8689
  bazaarcustomers: number;
8669
8690
  bazaarprofit: number;
8670
8691
  bazaarsales: number;
8692
+ itemmarketsales: number;
8693
+ itemmarketcustomers: number;
8694
+ itemmarketrevenue: number;
8695
+ itemmarketfees: number;
8671
8696
  bestactivestreak: number;
8672
8697
  bestdamage: number;
8673
8698
  bestkillstreak: number;
@@ -11902,16 +11927,21 @@ export type SelectionV2<Sec extends SectionV2> =
11902
11927
 
11903
11928
  export type ParamsV1<
11904
11929
  Sec extends SectionV1,
11905
- Sel extends keyof SectionsV1Map[Sec]["selections"],
11906
- > = SectionsV1Map[Sec]["selections"][Sel] extends { params: any }
11930
+ Sel extends SelectionV1<Sec>,
11931
+ > = SectionsV1Map[Sec]["selections"][Sel] extends {
11932
+ params: any;
11933
+ }
11907
11934
  ? SectionsV1Map[Sec]["selections"][Sel]["params"]
11908
11935
  : never;
11909
11936
  export type ParamsV2<
11910
11937
  Sec extends SectionV2,
11911
- Sel extends keyof SectionsV2Map[Sec]["selections"],
11912
- > = SectionsV2Map[Sec]["selections"][Sel] extends { params: any }
11938
+ Sel extends SelectionV2<Sec>,
11939
+ > = SectionsV2Map[Sec]["selections"][Sel] extends {
11940
+ params: any;
11941
+ }
11913
11942
  ? SectionsV2Map[Sec]["selections"][Sel]["params"]
11914
11943
  : never;
11944
+
11915
11945
  export type GetArgumentV1<
11916
11946
  Sec extends SectionV1,
11917
11947
  Sel extends keyof SectionsV1Map[Sec]["selections"],
@@ -12022,123 +12052,145 @@ type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (
12022
12052
  ? I
12023
12053
  : never;
12024
12054
 
12025
- export async function tornApiGetV1<
12026
- Sec extends SectionV1,
12027
- Sel extends SelectionV1<Sec>,
12028
- >({
12029
- section,
12030
- selections,
12031
- id,
12032
- params = {} as any,
12033
- key,
12034
- comment,
12035
- cache,
12036
- expiry,
12037
- }: GetArgumentV1<Sec, Sel> & {
12038
- cache?: CacheV1<Sec, Sel>;
12039
- expiry?: number;
12040
- }): Promise<GetResponseV1<Sec, Sel>> {
12041
- const cached = await cache?.get({
12055
+ export interface HTTPClient {
12056
+ getJson(url: URL): Promise<any>;
12057
+ }
12058
+
12059
+ export class FetchHTTPClient implements HTTPClient {
12060
+ async getJson(url: URL): Promise<any> {
12061
+ const response = await fetch(url);
12062
+
12063
+ return await response.json();
12064
+ }
12065
+ }
12066
+
12067
+ interface ClientOptions {
12068
+ httpClient?: HTTPClient;
12069
+ defaultComment?: string;
12070
+ }
12071
+
12072
+ export class TornApiClient {
12073
+ private readonly httpClient: HTTPClient;
12074
+ private readonly defaultComment?: string;
12075
+
12076
+ constructor(options: ClientOptions = {}) {
12077
+ this.httpClient = options.httpClient ?? new FetchHTTPClient();
12078
+ this.defaultComment = options.defaultComment;
12079
+ }
12080
+
12081
+ async getV1<Sec extends SectionV1, Sel extends SelectionV1<Sec>>({
12042
12082
  section,
12043
12083
  selections,
12044
12084
  id,
12045
- params,
12085
+ params = {} as any,
12046
12086
  key,
12047
- } as GetArgumentV1<Sec, Sel>);
12048
- if (cached) return cached;
12049
-
12050
- const url = new URL(`https://api.torn.com/${section}/${id ?? ""}`);
12051
- selections?.length &&
12052
- url.searchParams.set("selections", selections.join(","));
12053
- url.searchParams.set("key", key);
12054
- if (comment) url.searchParams.set("comment", comment);
12055
- Object.entries<string>(params as any).forEach(([k, v]) =>
12056
- url.searchParams.set(k, v),
12057
- );
12058
-
12059
- return await fetch(url)
12060
- .then((res) => res.json())
12061
- .then(addToCache)
12062
- .catch(handleError);
12063
-
12064
- function handleError(e: unknown) {
12065
- console.error(e);
12066
- return { error: { code: -1, error: generateErrorString(e) } };
12087
+ comment,
12088
+ cache,
12089
+ expiry,
12090
+ }: GetArgumentV1<Sec, Sel> & {
12091
+ cache?: CacheV1<Sec, Sel>;
12092
+ expiry?: number;
12093
+ }): Promise<GetResponseV1<Sec, Sel>> {
12094
+ const cached = await cache?.get({
12095
+ section,
12096
+ selections,
12097
+ id,
12098
+ params,
12099
+ key,
12100
+ } as GetArgumentV1<Sec, Sel>);
12101
+ if (cached) return cached;
12102
+
12103
+ const url = new URL(`https://api.torn.com/${section}/${id ?? ""}`);
12104
+ this.populateUrl(
12105
+ url,
12106
+ key,
12107
+ (selections ?? []) as string[],
12108
+ comment,
12109
+ params ?? {},
12110
+ );
12067
12111
 
12068
- function generateErrorString(e: unknown): string {
12069
- switch (typeof e) {
12070
- case "string":
12071
- return e;
12072
- case "object": {
12073
- if (e instanceof Error) return e.message;
12074
- return JSON.stringify(e);
12075
- }
12076
- default:
12077
- return (e as any).toString();
12078
- }
12112
+ return this.httpClient
12113
+ .getJson(url)
12114
+ .then(addToCache)
12115
+ .catch(this.handleError);
12116
+
12117
+ function addToCache(
12118
+ response: GetResponseV1<Sec, Sel>,
12119
+ ): GetResponseV1<Sec, Sel> {
12120
+ if ("error" in (response as any)) return response;
12121
+ cache?.set(
12122
+ {
12123
+ section,
12124
+ selections,
12125
+ id,
12126
+ params,
12127
+ key,
12128
+ } as GetArgumentV1<Sec, Sel>,
12129
+ response,
12130
+ expiry ?? Date.now() + 30_000,
12131
+ );
12132
+ return response;
12079
12133
  }
12080
12134
  }
12081
12135
 
12082
- function addToCache(
12083
- response: GetResponseV1<Sec, Sel>,
12084
- ): GetResponseV1<Sec, Sel> {
12085
- if ("error" in (response as any)) return response;
12086
- cache?.set(
12087
- {
12088
- section,
12089
- selections,
12090
- id,
12091
- params,
12092
- key,
12093
- } as GetArgumentV1<Sec, Sel>,
12094
- response,
12095
- expiry ?? Date.now() + 30_000,
12096
- );
12097
- return response;
12098
- }
12099
- }
12100
- export async function tornApiGetV2<
12101
- Sec extends SectionV2,
12102
- Sel extends SelectionV2<Sec>,
12103
- >({
12104
- section,
12105
- selections,
12106
- id,
12107
- params = {} as any,
12108
- key,
12109
- comment,
12110
- cache,
12111
- expiry,
12112
- }: GetArgumentV2<Sec, Sel> & {
12113
- cache?: CacheV2<Sec, Sel>;
12114
- expiry?: number;
12115
- }): Promise<GetResponseV2<Sec, Sel>> {
12116
- const cached = await cache?.get({
12136
+ async getV2<Sec extends SectionV2, Sel extends SelectionV2<Sec>>({
12117
12137
  section,
12118
12138
  selections,
12119
12139
  id,
12120
- params,
12140
+ params = {} as any,
12121
12141
  key,
12122
- } as GetArgumentV2<Sec, Sel>);
12123
- if (cached) return cached;
12124
-
12125
- const url = new URL(`https://api.torn.com/v2/${section}/${id ?? ""}`);
12126
- selections?.length &&
12127
- url.searchParams.set("selections", selections.join(","));
12128
- url.searchParams.set("key", key);
12129
- if (comment) url.searchParams.set("comment", comment);
12130
- Object.entries<string>(params as any).forEach(([k, v]) =>
12131
- url.searchParams.set(k, v),
12132
- );
12133
-
12134
- return await fetch(url)
12135
- .then((res) => res.json())
12136
- .then(addToCache)
12137
- .catch(handleError);
12138
-
12139
- function handleError(e: unknown) {
12140
- console.error(e);
12141
- return { error: { code: -1, error: generateErrorString(e) } };
12142
+ comment,
12143
+ cache,
12144
+ expiry,
12145
+ }: GetArgumentV2<Sec, Sel> & {
12146
+ cache?: CacheV2<Sec, Sel>;
12147
+ expiry?: number;
12148
+ }): Promise<GetResponseV2<Sec, Sel>> {
12149
+ const cached = await cache?.get({
12150
+ section,
12151
+ selections,
12152
+ id,
12153
+ params,
12154
+ key,
12155
+ } as GetArgumentV2<Sec, Sel>);
12156
+ if (cached) return cached;
12157
+
12158
+ const url = new URL(`https://api.torn.com/v2/${section}/${id ?? ""}`);
12159
+ this.populateUrl(
12160
+ url,
12161
+ key,
12162
+ (selections ?? []) as string[],
12163
+ comment,
12164
+ params ?? {},
12165
+ );
12166
+
12167
+ return this.httpClient
12168
+ .getJson(url)
12169
+ .then(addToCache)
12170
+ .catch(this.handleError);
12171
+
12172
+ function addToCache(
12173
+ response: GetResponseV2<Sec, Sel>,
12174
+ ): GetResponseV2<Sec, Sel> {
12175
+ if ("error" in (response as any)) return response;
12176
+ cache?.set(
12177
+ {
12178
+ section,
12179
+ selections,
12180
+ id,
12181
+ params,
12182
+ key,
12183
+ } as GetArgumentV2<Sec, Sel>,
12184
+ response,
12185
+ expiry ?? Date.now() + 30_000,
12186
+ );
12187
+ return response;
12188
+ }
12189
+ }
12190
+
12191
+ private handleError(error: unknown) {
12192
+ console.error(error);
12193
+ return { error: { code: -1, error: generateErrorString(error) } };
12142
12194
 
12143
12195
  function generateErrorString(e: unknown): string {
12144
12196
  switch (typeof e) {
@@ -12154,21 +12206,58 @@ export async function tornApiGetV2<
12154
12206
  }
12155
12207
  }
12156
12208
 
12157
- function addToCache(
12158
- response: GetResponseV2<Sec, Sel>,
12159
- ): GetResponseV2<Sec, Sel> {
12160
- if ("error" in (response as any)) return response;
12161
- cache?.set(
12162
- {
12163
- section,
12164
- selections,
12165
- id,
12166
- params,
12167
- key,
12168
- } as GetArgumentV2<Sec, Sel>,
12169
- response,
12170
- expiry ?? Date.now() + 30_000,
12171
- );
12172
- return response;
12209
+ private populateUrl(
12210
+ url: URL,
12211
+ key: string,
12212
+ selections: string[],
12213
+ comment: string | undefined,
12214
+ params: Record<string, string | undefined>,
12215
+ ): void {
12216
+ const allParams: Record<string, string | undefined> = {
12217
+ key,
12218
+ comment: comment ?? this.defaultComment,
12219
+ selections: selections.length ? selections.join(",") : undefined,
12220
+ ...params,
12221
+ };
12222
+
12223
+ Object.entries(allParams)
12224
+ .filter<[string, string]>(
12225
+ (entry): entry is [string, string] => !!entry[1],
12226
+ )
12227
+ .forEach(([key, value]) => url.searchParams.set(key, value));
12173
12228
  }
12174
12229
  }
12230
+
12231
+ const DEFAULT_CLIENT = new TornApiClient();
12232
+
12233
+ /**
12234
+ * @deprecated Move to TornApiClient instead of using this. Will be removed in an upcoming version.
12235
+ * @see TornApiClient
12236
+ */
12237
+ export async function tornApiGetV1<
12238
+ Sec extends SectionV1,
12239
+ Sel extends SelectionV1<Sec>,
12240
+ >(
12241
+ options: GetArgumentV1<Sec, Sel> & {
12242
+ cache?: CacheV1<Sec, Sel>;
12243
+ expiry?: number;
12244
+ },
12245
+ ): Promise<GetResponseV1<Sec, Sel>> {
12246
+ return DEFAULT_CLIENT.getV1(options);
12247
+ }
12248
+
12249
+ /**
12250
+ * @deprecated Move to TornApiClient instead of using this. Will be removed in an upcoming version.
12251
+ * @see TornApiClient
12252
+ */
12253
+ export async function tornApiGetV2<
12254
+ Sec extends SectionV2,
12255
+ Sel extends SelectionV2<Sec>,
12256
+ >(
12257
+ options: GetArgumentV2<Sec, Sel> & {
12258
+ cache?: CacheV2<Sec, Sel>;
12259
+ expiry?: number;
12260
+ },
12261
+ ): Promise<GetResponseV2<Sec, Sel>> {
12262
+ return DEFAULT_CLIENT.getV2(options);
12263
+ }
package/dist/openapi.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "info": {
4
4
  "title": "Torn API",
5
5
  "description": "\n * The development of Torn's API v2 is still ongoing.\n * If selections remain unaltered, they will default to the API v1 version.\n * Unlike API v1, API v2 accepts both selections and IDs as path and query parameters.\n * If any discrepancies or errors are found, please submit a [bug report](https://www.torn.com/forums.php#/p=forums&f=19&b=0&a=0) on the Torn Forums.\n * In case you're using bots to check for changes on openapi.json file, make sure to specificy a custom user-agent header - CloudFlare sometimes prevents requests from default user-agents.",
6
- "version": "2.0.2"
6
+ "version": "3.0.0"
7
7
  },
8
8
  "servers": [
9
9
  {
@@ -11585,6 +11585,17 @@
11585
11585
  "rank"
11586
11586
  ]
11587
11587
  },
11588
+ "TornOrganizedCrimePositionId": {
11589
+ "type": "string",
11590
+ "enum": [
11591
+ "P1",
11592
+ "P2",
11593
+ "P3",
11594
+ "P4",
11595
+ "P5",
11596
+ "P6"
11597
+ ]
11598
+ },
11588
11599
  "FactionTerritoryWarResultEnum": {
11589
11600
  "type": "string",
11590
11601
  "enum": [
@@ -20724,6 +20735,8 @@
20724
20735
  "FactionCrimeSlot": {
20725
20736
  "required": [
20726
20737
  "position",
20738
+ "position_id",
20739
+ "position_number",
20727
20740
  "item_requirement",
20728
20741
  "user",
20729
20742
  "checkpoint_pass_rate"
@@ -20732,6 +20745,13 @@
20732
20745
  "position": {
20733
20746
  "type": "string"
20734
20747
  },
20748
+ "position_id": {
20749
+ "$ref": "#/components/schemas/TornOrganizedCrimePositionId"
20750
+ },
20751
+ "position_number": {
20752
+ "type": "integer",
20753
+ "format": "int32"
20754
+ },
20735
20755
  "item_requirement": {
20736
20756
  "description": "Details of item required for the slot, if applicable.",
20737
20757
  "oneOf": [
@@ -21896,7 +21916,8 @@
21896
21916
  "info": {
21897
21917
  "required": [
21898
21918
  "selections",
21899
- "access"
21919
+ "access",
21920
+ "user"
21900
21921
  ],
21901
21922
  "properties": {
21902
21923
  "selections": {
@@ -21969,6 +21990,41 @@
21969
21990
  },
21970
21991
  "type": "object"
21971
21992
  },
21993
+ "user": {
21994
+ "required": [
21995
+ "id",
21996
+ "faction_id",
21997
+ "company_id"
21998
+ ],
21999
+ "properties": {
22000
+ "faction_id": {
22001
+ "description": "Null only if the user is not in a faction.",
22002
+ "oneOf": [
22003
+ {
22004
+ "$ref": "#/components/schemas/FactionId"
22005
+ },
22006
+ {
22007
+ "type": "null"
22008
+ }
22009
+ ]
22010
+ },
22011
+ "company_id": {
22012
+ "description": "Null only if the user is not in a company.",
22013
+ "oneOf": [
22014
+ {
22015
+ "$ref": "#/components/schemas/CompanyId"
22016
+ },
22017
+ {
22018
+ "type": "null"
22019
+ }
22020
+ ]
22021
+ },
22022
+ "id": {
22023
+ "$ref": "#/components/schemas/UserId"
22024
+ }
22025
+ },
22026
+ "type": "object"
22027
+ },
21972
22028
  "access": {
21973
22029
  "required": [
21974
22030
  "level",
@@ -21988,6 +22044,8 @@
21988
22044
  "type": "boolean"
21989
22045
  },
21990
22046
  "faction_id": {
22047
+ "description": "This field is replaced with 'user'.'faction_id' field and will be removed on 1st of September 2025. Populated only if 'faction' field is true.",
22048
+ "deprecated": true,
21991
22049
  "oneOf": [
21992
22050
  {
21993
22051
  "$ref": "#/components/schemas/FactionId"
@@ -22001,6 +22059,8 @@
22001
22059
  "type": "boolean"
22002
22060
  },
22003
22061
  "company_id": {
22062
+ "description": "This field is replaced with 'user'.'company_id' field and will be removed on 1st of September 2025. Populated only if 'company' field is true.",
22063
+ "deprecated": true,
22004
22064
  "oneOf": [
22005
22065
  {
22006
22066
  "$ref": "#/components/schemas/CompanyId"
@@ -23476,7 +23536,7 @@
23476
23536
  ],
23477
23537
  "properties": {
23478
23538
  "id": {
23479
- "type": "string"
23539
+ "$ref": "#/components/schemas/TornOrganizedCrimePositionId"
23480
23540
  },
23481
23541
  "name": {
23482
23542
  "type": "string"
@@ -23982,7 +24042,7 @@
23982
24042
  },
23983
24043
  "type": "object"
23984
24044
  },
23985
- "TornHof": {
24045
+ "TornHofBasic": {
23986
24046
  "required": [
23987
24047
  "id",
23988
24048
  "username",
@@ -24056,6 +24116,35 @@
24056
24116
  },
24057
24117
  "type": "object"
24058
24118
  },
24119
+ "TornHofWithOffenses": {
24120
+ "allOf": [
24121
+ {
24122
+ "$ref": "#/components/schemas/TornHofBasic"
24123
+ },
24124
+ {
24125
+ "required": [
24126
+ "criminal_offenses"
24127
+ ],
24128
+ "properties": {
24129
+ "criminal_offenses": {
24130
+ "type": "integer",
24131
+ "format": "int32"
24132
+ }
24133
+ },
24134
+ "type": "object"
24135
+ }
24136
+ ]
24137
+ },
24138
+ "TornHof": {
24139
+ "oneOf": [
24140
+ {
24141
+ "$ref": "#/components/schemas/TornHofBasic"
24142
+ },
24143
+ {
24144
+ "$ref": "#/components/schemas/TornHofWithOffenses"
24145
+ }
24146
+ ]
24147
+ },
24059
24148
  "TornHofResponse": {
24060
24149
  "required": [
24061
24150
  "hof",
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "tornapi-typescript",
3
3
  "type": "module",
4
- "version": "2.0.2",
4
+ "version": "3.0.0",
5
5
  "scripts": {
6
6
  "generate-types": "tsc && node build/index.js"
7
7
  },
8
8
  "devDependencies": {
9
9
  "@scalar/openapi-types": "^0.3.5",
10
- "@types/node": "^22.16.0",
10
+ "@types/node": "^22.16.4",
11
11
  "prettier": "^3.6.2",
12
12
  "typeconv": "^2.3.1",
13
13
  "typescript": "^5.8.3"