tebex-plugin-api 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +22 -2
- package/dist/index.d.mts +405 -0
- package/dist/index.mjs +334 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 heyxmirko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
#
|
|
1
|
+
# vite-plus-starter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A starter for creating a Vite Plus project.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
- Install dependencies:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
vp install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- Run the unit tests:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
vp test
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Build the library:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
vp pack
|
|
23
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
interface TebexClientOptions {
|
|
2
|
+
secret?: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
fetch?: typeof fetch;
|
|
6
|
+
}
|
|
7
|
+
interface RequestOptions {
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
interface Init extends RequestOptions {
|
|
11
|
+
query?: Record<string, string | number | undefined>;
|
|
12
|
+
body?: unknown;
|
|
13
|
+
}
|
|
14
|
+
type Method = "GET" | "POST" | "PUT" | "DELETE";
|
|
15
|
+
declare class Http {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(options: TebexClientOptions);
|
|
18
|
+
request<T>(method: Method, path: string, init?: Init): Promise<T>;
|
|
19
|
+
requestData<T>(method: Method, path: string, init?: Init): Promise<T>;
|
|
20
|
+
}
|
|
21
|
+
interface Ban {
|
|
22
|
+
id: number;
|
|
23
|
+
time: string;
|
|
24
|
+
ip: string;
|
|
25
|
+
payment_email: string;
|
|
26
|
+
reason: string;
|
|
27
|
+
user: {
|
|
28
|
+
ign: string;
|
|
29
|
+
uuid: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
interface CreateBanParams {
|
|
33
|
+
user: string;
|
|
34
|
+
reason?: string;
|
|
35
|
+
ip?: string;
|
|
36
|
+
}
|
|
37
|
+
declare class BansResource {
|
|
38
|
+
private readonly http;
|
|
39
|
+
constructor(http: Http);
|
|
40
|
+
list(options?: RequestOptions): Promise<Ban[]>;
|
|
41
|
+
create(params: CreateBanParams, options?: RequestOptions): Promise<Ban>;
|
|
42
|
+
}
|
|
43
|
+
interface CreateCheckoutParams {
|
|
44
|
+
package_id: number | string;
|
|
45
|
+
username: string;
|
|
46
|
+
}
|
|
47
|
+
interface Checkout {
|
|
48
|
+
url: string;
|
|
49
|
+
expires: string;
|
|
50
|
+
}
|
|
51
|
+
declare class CheckoutResource {
|
|
52
|
+
private readonly http;
|
|
53
|
+
constructor(http: Http);
|
|
54
|
+
create(params: CreateCheckoutParams, options?: RequestOptions): Promise<Checkout>;
|
|
55
|
+
}
|
|
56
|
+
interface CommunityGoal {
|
|
57
|
+
id: number;
|
|
58
|
+
created_at: string;
|
|
59
|
+
updated_at: string;
|
|
60
|
+
account: number;
|
|
61
|
+
name: string;
|
|
62
|
+
description: string;
|
|
63
|
+
image: string;
|
|
64
|
+
target: string;
|
|
65
|
+
current: string;
|
|
66
|
+
repeatable: number;
|
|
67
|
+
last_achieved: string | null;
|
|
68
|
+
times_achieved: number;
|
|
69
|
+
status: "active" | (string & {});
|
|
70
|
+
sale: number;
|
|
71
|
+
}
|
|
72
|
+
declare class CommunityGoalsResource {
|
|
73
|
+
private readonly http;
|
|
74
|
+
constructor(http: Http);
|
|
75
|
+
list(options?: RequestOptions): Promise<CommunityGoal[]>;
|
|
76
|
+
get(id: number | string, options?: RequestOptions): Promise<CommunityGoal>;
|
|
77
|
+
}
|
|
78
|
+
interface Currency {
|
|
79
|
+
iso_4217: string;
|
|
80
|
+
symbol: string;
|
|
81
|
+
}
|
|
82
|
+
interface Player {
|
|
83
|
+
id: number;
|
|
84
|
+
name: string;
|
|
85
|
+
uuid: string;
|
|
86
|
+
}
|
|
87
|
+
interface PackageRef {
|
|
88
|
+
id: number;
|
|
89
|
+
name: string;
|
|
90
|
+
}
|
|
91
|
+
interface Page<T> {
|
|
92
|
+
items: T[];
|
|
93
|
+
page: number;
|
|
94
|
+
lastPage: number;
|
|
95
|
+
total: number;
|
|
96
|
+
hasNext: boolean;
|
|
97
|
+
}
|
|
98
|
+
type BoolString = boolean | "true" | "false";
|
|
99
|
+
interface Coupon {
|
|
100
|
+
id: number;
|
|
101
|
+
code: string;
|
|
102
|
+
effective: {
|
|
103
|
+
type: "cart" | "package" | "category";
|
|
104
|
+
packages: number[];
|
|
105
|
+
categories: number[];
|
|
106
|
+
};
|
|
107
|
+
discount: {
|
|
108
|
+
type: "value" | "percentage";
|
|
109
|
+
percentage: number;
|
|
110
|
+
value: number;
|
|
111
|
+
};
|
|
112
|
+
expire: {
|
|
113
|
+
redeem_unlimited: BoolString;
|
|
114
|
+
expire_never: BoolString;
|
|
115
|
+
limit: number;
|
|
116
|
+
date: string;
|
|
117
|
+
};
|
|
118
|
+
basket_type: "single" | "subscription" | "both";
|
|
119
|
+
start_date: string;
|
|
120
|
+
user_limit: number;
|
|
121
|
+
minimum: number;
|
|
122
|
+
discount_application_method?: number;
|
|
123
|
+
username: string;
|
|
124
|
+
note: string;
|
|
125
|
+
}
|
|
126
|
+
type Discount = {
|
|
127
|
+
discount_type: "percentage";
|
|
128
|
+
discount_percentage: number;
|
|
129
|
+
} | {
|
|
130
|
+
discount_type: "value";
|
|
131
|
+
discount_amount: number;
|
|
132
|
+
};
|
|
133
|
+
type Target = {
|
|
134
|
+
effective_on: "cart";
|
|
135
|
+
} | {
|
|
136
|
+
effective_on: "package";
|
|
137
|
+
packages: number[];
|
|
138
|
+
} | {
|
|
139
|
+
effective_on: "category";
|
|
140
|
+
categories: number[];
|
|
141
|
+
};
|
|
142
|
+
type CreateCouponParams = Discount & Target & {
|
|
143
|
+
code: string;
|
|
144
|
+
redeem_unlimited: boolean;
|
|
145
|
+
expire_limit?: number;
|
|
146
|
+
expire_never: boolean;
|
|
147
|
+
expire_date?: string;
|
|
148
|
+
start_date: string;
|
|
149
|
+
basket_type: "single" | "subscription" | "both";
|
|
150
|
+
minimum?: number;
|
|
151
|
+
discount_application_method?: 0 | 1 | 2;
|
|
152
|
+
username?: string;
|
|
153
|
+
note?: string;
|
|
154
|
+
};
|
|
155
|
+
declare class CouponsResource {
|
|
156
|
+
private readonly http;
|
|
157
|
+
constructor(http: Http);
|
|
158
|
+
list(page?: number, options?: RequestOptions): Promise<Page<Coupon>>;
|
|
159
|
+
get(id: number | string, options?: RequestOptions): Promise<Coupon>;
|
|
160
|
+
create(params: CreateCouponParams, options?: RequestOptions): Promise<Coupon>;
|
|
161
|
+
delete(id: number | string, options?: RequestOptions): Promise<void>;
|
|
162
|
+
}
|
|
163
|
+
interface GiftCard {
|
|
164
|
+
id: number;
|
|
165
|
+
code: string;
|
|
166
|
+
balance: {
|
|
167
|
+
starting: string;
|
|
168
|
+
remaining: string;
|
|
169
|
+
currency: string;
|
|
170
|
+
};
|
|
171
|
+
note: string;
|
|
172
|
+
void: boolean;
|
|
173
|
+
}
|
|
174
|
+
interface CreateGiftCardParams {
|
|
175
|
+
amount: number;
|
|
176
|
+
note?: string;
|
|
177
|
+
expires_at?: string;
|
|
178
|
+
}
|
|
179
|
+
declare class GiftCardsResource {
|
|
180
|
+
private readonly http;
|
|
181
|
+
constructor(http: Http);
|
|
182
|
+
list(options?: RequestOptions): Promise<GiftCard[]>;
|
|
183
|
+
get(id: number | string, options?: RequestOptions): Promise<GiftCard>;
|
|
184
|
+
lookup(code: string, options?: RequestOptions): Promise<GiftCard>;
|
|
185
|
+
create(params: CreateGiftCardParams, options?: RequestOptions): Promise<GiftCard>;
|
|
186
|
+
topUp(id: number | string, amount: number, options?: RequestOptions): Promise<GiftCard>;
|
|
187
|
+
void(id: number | string, options?: RequestOptions): Promise<GiftCard>;
|
|
188
|
+
}
|
|
189
|
+
interface ServerInformation {
|
|
190
|
+
account: {
|
|
191
|
+
id: number;
|
|
192
|
+
domain: string;
|
|
193
|
+
name: string;
|
|
194
|
+
currency: Currency;
|
|
195
|
+
online_mode: boolean;
|
|
196
|
+
game_type: string;
|
|
197
|
+
log_events: boolean;
|
|
198
|
+
};
|
|
199
|
+
server: {
|
|
200
|
+
id: number;
|
|
201
|
+
name: string;
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
declare class InformationResource {
|
|
205
|
+
private readonly http;
|
|
206
|
+
constructor(http: Http);
|
|
207
|
+
get(options?: RequestOptions): Promise<ServerInformation>;
|
|
208
|
+
}
|
|
209
|
+
interface UpdatePackageParams {
|
|
210
|
+
disabled?: boolean;
|
|
211
|
+
name?: string;
|
|
212
|
+
price?: number;
|
|
213
|
+
}
|
|
214
|
+
declare class PackagesResource {
|
|
215
|
+
private readonly http;
|
|
216
|
+
constructor(http: Http);
|
|
217
|
+
update(id: number | string, params: UpdatePackageParams, options?: RequestOptions): Promise<void>;
|
|
218
|
+
}
|
|
219
|
+
type PaymentStatus = "Complete" | "Refund" | "Chargeback" | (string & {});
|
|
220
|
+
interface Payment {
|
|
221
|
+
id: number;
|
|
222
|
+
amount: string;
|
|
223
|
+
date: string;
|
|
224
|
+
currency: Currency;
|
|
225
|
+
status: PaymentStatus;
|
|
226
|
+
player: Player;
|
|
227
|
+
packages: PackageRef[];
|
|
228
|
+
gateway?: {
|
|
229
|
+
id: number;
|
|
230
|
+
name: string;
|
|
231
|
+
};
|
|
232
|
+
email?: string;
|
|
233
|
+
notes?: {
|
|
234
|
+
created_at: string;
|
|
235
|
+
note: string;
|
|
236
|
+
}[];
|
|
237
|
+
creator_code?: string | null;
|
|
238
|
+
}
|
|
239
|
+
interface PaymentField {
|
|
240
|
+
name: string;
|
|
241
|
+
type: "numeric" | "dropdown" | "username" | (string & {});
|
|
242
|
+
description?: string;
|
|
243
|
+
value?: string;
|
|
244
|
+
options?: false | {
|
|
245
|
+
label: string;
|
|
246
|
+
value: string | number;
|
|
247
|
+
}[];
|
|
248
|
+
}
|
|
249
|
+
interface CreatePaymentParams {
|
|
250
|
+
ign: string;
|
|
251
|
+
price: number;
|
|
252
|
+
packages: {
|
|
253
|
+
id: number;
|
|
254
|
+
options?: Record<string, string | number>;
|
|
255
|
+
}[];
|
|
256
|
+
note?: string;
|
|
257
|
+
}
|
|
258
|
+
interface UpdatePaymentParams {
|
|
259
|
+
username?: string;
|
|
260
|
+
status?: "complete" | "chargeback" | "refund";
|
|
261
|
+
}
|
|
262
|
+
declare class PaymentsResource {
|
|
263
|
+
private readonly http;
|
|
264
|
+
constructor(http: Http);
|
|
265
|
+
list(query?: {
|
|
266
|
+
limit?: number;
|
|
267
|
+
}, options?: RequestOptions): Promise<Payment[]>;
|
|
268
|
+
listPaged(page?: number, options?: RequestOptions): Promise<Page<Payment>>;
|
|
269
|
+
get(transaction: string, options?: RequestOptions): Promise<Payment>;
|
|
270
|
+
requiredFields(packageId: number | string, options?: RequestOptions): Promise<PaymentField[]>;
|
|
271
|
+
create(params: CreatePaymentParams, options?: RequestOptions): Promise<void>;
|
|
272
|
+
update(transaction: string, params: UpdatePaymentParams, options?: RequestOptions): Promise<void>;
|
|
273
|
+
addNote(transaction: string, note: string, options?: RequestOptions): Promise<void>;
|
|
274
|
+
}
|
|
275
|
+
interface PlayerLookup {
|
|
276
|
+
player: {
|
|
277
|
+
id: string;
|
|
278
|
+
username: string;
|
|
279
|
+
meta: string;
|
|
280
|
+
plugin_username_id: number;
|
|
281
|
+
};
|
|
282
|
+
banCount: number;
|
|
283
|
+
chargebackRate: number;
|
|
284
|
+
payments: {
|
|
285
|
+
txn_id: string;
|
|
286
|
+
time: number;
|
|
287
|
+
price: number;
|
|
288
|
+
currency: string;
|
|
289
|
+
status: number;
|
|
290
|
+
}[];
|
|
291
|
+
purchaseTotals: Record<string, number>;
|
|
292
|
+
}
|
|
293
|
+
interface ActivePackage {
|
|
294
|
+
txn_id: string;
|
|
295
|
+
date: string;
|
|
296
|
+
quantity: number;
|
|
297
|
+
package: PackageRef;
|
|
298
|
+
}
|
|
299
|
+
declare class PlayersResource {
|
|
300
|
+
private readonly http;
|
|
301
|
+
constructor(http: Http);
|
|
302
|
+
lookup(user: string, options?: RequestOptions): Promise<PlayerLookup>;
|
|
303
|
+
activePackages(playerId: number | string, query?: {
|
|
304
|
+
package?: number;
|
|
305
|
+
}, options?: RequestOptions): Promise<ActivePackage[]>;
|
|
306
|
+
}
|
|
307
|
+
interface DueQueue {
|
|
308
|
+
meta: {
|
|
309
|
+
execute_offline: boolean;
|
|
310
|
+
next_check: number;
|
|
311
|
+
more: boolean;
|
|
312
|
+
};
|
|
313
|
+
players: Player[];
|
|
314
|
+
}
|
|
315
|
+
interface OfflineCommand {
|
|
316
|
+
id: number;
|
|
317
|
+
command: string;
|
|
318
|
+
payment: number;
|
|
319
|
+
package: number;
|
|
320
|
+
conditions: {
|
|
321
|
+
delay: number;
|
|
322
|
+
};
|
|
323
|
+
player: Player;
|
|
324
|
+
}
|
|
325
|
+
interface OfflineCommands {
|
|
326
|
+
meta: {
|
|
327
|
+
limited: boolean;
|
|
328
|
+
};
|
|
329
|
+
commands: OfflineCommand[];
|
|
330
|
+
}
|
|
331
|
+
interface OnlineCommand {
|
|
332
|
+
id: number;
|
|
333
|
+
command: string;
|
|
334
|
+
payment: number;
|
|
335
|
+
package: number;
|
|
336
|
+
conditions: {
|
|
337
|
+
delay: number;
|
|
338
|
+
slots: number;
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
interface OnlineCommands {
|
|
342
|
+
commands: OnlineCommand[];
|
|
343
|
+
}
|
|
344
|
+
declare class QueueResource {
|
|
345
|
+
private readonly http;
|
|
346
|
+
constructor(http: Http);
|
|
347
|
+
get(options?: RequestOptions): Promise<DueQueue>;
|
|
348
|
+
offlineCommands(options?: RequestOptions): Promise<OfflineCommands>;
|
|
349
|
+
onlineCommands(playerId: string | number, options?: RequestOptions): Promise<OnlineCommands>;
|
|
350
|
+
delete(ids: number[], options?: RequestOptions): Promise<void>;
|
|
351
|
+
}
|
|
352
|
+
interface Sale {
|
|
353
|
+
id: number;
|
|
354
|
+
name: string;
|
|
355
|
+
effective: {
|
|
356
|
+
type: "package" | "category" | (string & {});
|
|
357
|
+
packages: number[];
|
|
358
|
+
categories: number[];
|
|
359
|
+
};
|
|
360
|
+
discount: {
|
|
361
|
+
type: "percentage" | "value";
|
|
362
|
+
percentage: number;
|
|
363
|
+
value: number;
|
|
364
|
+
};
|
|
365
|
+
start: number;
|
|
366
|
+
expire: number;
|
|
367
|
+
order: number;
|
|
368
|
+
}
|
|
369
|
+
declare class SalesResource {
|
|
370
|
+
private readonly http;
|
|
371
|
+
constructor(http: Http);
|
|
372
|
+
list(options?: RequestOptions): Promise<Sale[]>;
|
|
373
|
+
}
|
|
374
|
+
export declare class TebexClient {
|
|
375
|
+
readonly information: InformationResource;
|
|
376
|
+
readonly communityGoals: CommunityGoalsResource;
|
|
377
|
+
readonly payments: PaymentsResource;
|
|
378
|
+
readonly packages: PackagesResource;
|
|
379
|
+
readonly checkout: CheckoutResource;
|
|
380
|
+
readonly giftCards: GiftCardsResource;
|
|
381
|
+
readonly coupons: CouponsResource;
|
|
382
|
+
readonly bans: BansResource;
|
|
383
|
+
readonly sales: SalesResource;
|
|
384
|
+
readonly players: PlayersResource;
|
|
385
|
+
readonly queue: QueueResource;
|
|
386
|
+
constructor(options?: TebexClientOptions);
|
|
387
|
+
}
|
|
388
|
+
export declare class TebexError extends Error {
|
|
389
|
+
readonly name = "TebexError";
|
|
390
|
+
readonly status: number;
|
|
391
|
+
readonly code: number | undefined;
|
|
392
|
+
readonly method: string;
|
|
393
|
+
readonly path: string;
|
|
394
|
+
readonly body: unknown;
|
|
395
|
+
constructor(init: {
|
|
396
|
+
message: string;
|
|
397
|
+
status: number;
|
|
398
|
+
code: number | undefined;
|
|
399
|
+
method: string;
|
|
400
|
+
path: string;
|
|
401
|
+
body: unknown;
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
export type { ActivePackage, Ban, BansResource, Checkout, CheckoutResource, CommunityGoal, CommunityGoalsResource, Coupon, CouponsResource, CreateBanParams, CreateCheckoutParams, CreateCouponParams, CreateGiftCardParams, CreatePaymentParams, Currency, DueQueue, GiftCard, GiftCardsResource, InformationResource, OfflineCommand, OfflineCommands, OnlineCommand, OnlineCommands, PackageRef, PackagesResource, Page, Payment, PaymentField, PaymentStatus, PaymentsResource, Player, PlayerLookup, PlayersResource, QueueResource, RequestOptions, Sale, SalesResource, ServerInformation, TebexClientOptions, UpdatePackageParams, UpdatePaymentParams };
|
|
405
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var TebexError = class extends Error {
|
|
3
|
+
name = "TebexError";
|
|
4
|
+
status;
|
|
5
|
+
code;
|
|
6
|
+
method;
|
|
7
|
+
path;
|
|
8
|
+
body;
|
|
9
|
+
constructor(init) {
|
|
10
|
+
super(init.message);
|
|
11
|
+
this.status = init.status;
|
|
12
|
+
this.code = init.code;
|
|
13
|
+
this.method = init.method;
|
|
14
|
+
this.path = init.path;
|
|
15
|
+
this.body = init.body;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
// src/http.ts
|
|
19
|
+
var Http = class {
|
|
20
|
+
#secret;
|
|
21
|
+
#baseUrl;
|
|
22
|
+
#timeout;
|
|
23
|
+
#fetch;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
const secret = options.secret ?? (typeof process === "undefined" ? void 0 : process.env.TEBEX_SECRET);
|
|
26
|
+
if (!secret) throw new TypeError("Missing Tebex secret. Pass `secret` or set the TEBEX_SECRET environment variable.");
|
|
27
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") console.warn("[tebex-plugin-api] Your secret is exposed in the browser. Use this server-side only.");
|
|
28
|
+
this.#secret = secret;
|
|
29
|
+
this.#baseUrl = (options.baseUrl ?? "https://plugin.tebex.io").replace(/\/+$/, "");
|
|
30
|
+
this.#timeout = options.timeout ?? 1e4;
|
|
31
|
+
this.#fetch = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
32
|
+
}
|
|
33
|
+
async request(method, path, init = {}) {
|
|
34
|
+
const url = new URL(this.#baseUrl + path);
|
|
35
|
+
for (const [key, value] of Object.entries(init.query ?? {})) if (value !== void 0) url.searchParams.set(key, String(value));
|
|
36
|
+
const signals = [init.signal, this.#timeout > 0 && AbortSignal.timeout(this.#timeout)].filter((signal) => !!signal);
|
|
37
|
+
const hasBody = init.body !== void 0;
|
|
38
|
+
const response = await this.#fetch(url, {
|
|
39
|
+
method,
|
|
40
|
+
headers: {
|
|
41
|
+
Accept: "application/json",
|
|
42
|
+
"X-Tebex-Secret": this.#secret,
|
|
43
|
+
...hasBody && { "Content-Type": "application/json" }
|
|
44
|
+
},
|
|
45
|
+
body: hasBody ? JSON.stringify(init.body) : null,
|
|
46
|
+
signal: signals.length ? AbortSignal.any(signals) : null
|
|
47
|
+
});
|
|
48
|
+
const text = await response.text();
|
|
49
|
+
const data = text ? parseJson(text) : void 0;
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
const error = typeof data === "object" && data !== null ? data : {};
|
|
52
|
+
throw new TebexError({
|
|
53
|
+
message: typeof error.error_message === "string" ? error.error_message : response.statusText || `HTTP ${response.status}`,
|
|
54
|
+
status: response.status,
|
|
55
|
+
code: typeof error.error_code === "number" ? error.error_code : void 0,
|
|
56
|
+
method,
|
|
57
|
+
path,
|
|
58
|
+
body: data
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
63
|
+
async requestData(method, path, init) {
|
|
64
|
+
return (await this.request(method, path, init)).data;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
function parseJson(text) {
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(text);
|
|
70
|
+
} catch {
|
|
71
|
+
return text;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const segment = (value) => encodeURIComponent(String(value));
|
|
75
|
+
// src/resources/bans.ts
|
|
76
|
+
var BansResource = class {
|
|
77
|
+
http;
|
|
78
|
+
constructor(http) {
|
|
79
|
+
this.http = http;
|
|
80
|
+
}
|
|
81
|
+
list(options) {
|
|
82
|
+
return this.http.requestData("GET", "/bans", options);
|
|
83
|
+
}
|
|
84
|
+
create(params, options) {
|
|
85
|
+
return this.http.requestData("POST", "/bans", {
|
|
86
|
+
...options,
|
|
87
|
+
body: params
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
// src/resources/checkout.ts
|
|
92
|
+
var CheckoutResource = class {
|
|
93
|
+
http;
|
|
94
|
+
constructor(http) {
|
|
95
|
+
this.http = http;
|
|
96
|
+
}
|
|
97
|
+
create(params, options) {
|
|
98
|
+
return this.http.request("POST", "/checkout", {
|
|
99
|
+
...options,
|
|
100
|
+
body: params
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
// src/resources/community-goals.ts
|
|
105
|
+
var CommunityGoalsResource = class {
|
|
106
|
+
http;
|
|
107
|
+
constructor(http) {
|
|
108
|
+
this.http = http;
|
|
109
|
+
}
|
|
110
|
+
list(options) {
|
|
111
|
+
return this.http.request("GET", "/community_goals", options);
|
|
112
|
+
}
|
|
113
|
+
get(id, options) {
|
|
114
|
+
return this.http.request("GET", `/community_goals/${segment(id)}`, options);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
// src/resources/coupons.ts
|
|
118
|
+
var CouponsResource = class {
|
|
119
|
+
http;
|
|
120
|
+
constructor(http) {
|
|
121
|
+
this.http = http;
|
|
122
|
+
}
|
|
123
|
+
async list(page, options) {
|
|
124
|
+
const response = await this.http.request("GET", "/coupons", {
|
|
125
|
+
...options,
|
|
126
|
+
query: { page }
|
|
127
|
+
});
|
|
128
|
+
return {
|
|
129
|
+
items: response.data,
|
|
130
|
+
page: response.pagination.currentPage,
|
|
131
|
+
lastPage: response.pagination.lastPage,
|
|
132
|
+
total: response.pagination.totalResults,
|
|
133
|
+
hasNext: response.pagination.next !== null
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
get(id, options) {
|
|
137
|
+
return this.http.requestData("GET", `/coupons/${segment(id)}`, options);
|
|
138
|
+
}
|
|
139
|
+
create(params, options) {
|
|
140
|
+
return this.http.requestData("POST", "/coupons", {
|
|
141
|
+
...options,
|
|
142
|
+
body: params
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
delete(id, options) {
|
|
146
|
+
return this.http.request("DELETE", `/coupons/${segment(id)}`, options);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
// src/resources/gift-cards.ts
|
|
150
|
+
var GiftCardsResource = class {
|
|
151
|
+
http;
|
|
152
|
+
constructor(http) {
|
|
153
|
+
this.http = http;
|
|
154
|
+
}
|
|
155
|
+
list(options) {
|
|
156
|
+
return this.http.requestData("GET", "/gift-cards", options);
|
|
157
|
+
}
|
|
158
|
+
get(id, options) {
|
|
159
|
+
return this.http.requestData("GET", `/gift-cards/${segment(id)}`, options);
|
|
160
|
+
}
|
|
161
|
+
lookup(code, options) {
|
|
162
|
+
return this.http.requestData("GET", `/gift-cards/lookup/${segment(code)}`, options);
|
|
163
|
+
}
|
|
164
|
+
create(params, options) {
|
|
165
|
+
return this.http.requestData("POST", "/gift-cards", {
|
|
166
|
+
...options,
|
|
167
|
+
body: params
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
topUp(id, amount, options) {
|
|
171
|
+
return this.http.requestData("PUT", `/gift-cards/${segment(id)}`, {
|
|
172
|
+
...options,
|
|
173
|
+
body: { amount: String(amount) }
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
void(id, options) {
|
|
177
|
+
return this.http.requestData("DELETE", `/gift-cards/${segment(id)}`, options);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
// src/resources/information.ts
|
|
181
|
+
var InformationResource = class {
|
|
182
|
+
http;
|
|
183
|
+
constructor(http) {
|
|
184
|
+
this.http = http;
|
|
185
|
+
}
|
|
186
|
+
get(options) {
|
|
187
|
+
return this.http.request("GET", "/information", options);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
// src/resources/packages.ts
|
|
191
|
+
var PackagesResource = class {
|
|
192
|
+
http;
|
|
193
|
+
constructor(http) {
|
|
194
|
+
this.http = http;
|
|
195
|
+
}
|
|
196
|
+
update(id, params, options) {
|
|
197
|
+
return this.http.request("PUT", `/package/${segment(id)}`, {
|
|
198
|
+
...options,
|
|
199
|
+
body: params
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
// src/resources/payments.ts
|
|
204
|
+
var PaymentsResource = class {
|
|
205
|
+
http;
|
|
206
|
+
constructor(http) {
|
|
207
|
+
this.http = http;
|
|
208
|
+
}
|
|
209
|
+
list(query = {}, options) {
|
|
210
|
+
return this.http.request("GET", "/payments", {
|
|
211
|
+
...options,
|
|
212
|
+
query
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async listPaged(page = 1, options) {
|
|
216
|
+
const response = await this.http.request("GET", "/payments", {
|
|
217
|
+
...options,
|
|
218
|
+
query: {
|
|
219
|
+
paged: 1,
|
|
220
|
+
page
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
return {
|
|
224
|
+
items: response.data,
|
|
225
|
+
page: response.current_page,
|
|
226
|
+
lastPage: response.last_page,
|
|
227
|
+
total: response.total,
|
|
228
|
+
hasNext: response.next_page_url !== null
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
get(transaction, options) {
|
|
232
|
+
return this.http.request("GET", `/payments/${segment(transaction)}`, options);
|
|
233
|
+
}
|
|
234
|
+
requiredFields(packageId, options) {
|
|
235
|
+
return this.http.request("GET", `/payments/fields/${segment(packageId)}`, options);
|
|
236
|
+
}
|
|
237
|
+
create(params, options) {
|
|
238
|
+
return this.http.request("POST", "/payments", {
|
|
239
|
+
...options,
|
|
240
|
+
body: params
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
update(transaction, params, options) {
|
|
244
|
+
return this.http.request("PUT", `/payments/${segment(transaction)}`, {
|
|
245
|
+
...options,
|
|
246
|
+
body: params
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
addNote(transaction, note, options) {
|
|
250
|
+
return this.http.request("POST", `/payments/${segment(transaction)}/note`, {
|
|
251
|
+
...options,
|
|
252
|
+
body: { note }
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
// src/resources/players.ts
|
|
257
|
+
var PlayersResource = class {
|
|
258
|
+
http;
|
|
259
|
+
constructor(http) {
|
|
260
|
+
this.http = http;
|
|
261
|
+
}
|
|
262
|
+
lookup(user, options) {
|
|
263
|
+
return this.http.request("GET", `/user/${segment(user)}`, options);
|
|
264
|
+
}
|
|
265
|
+
activePackages(playerId, query = {}, options) {
|
|
266
|
+
return this.http.request("GET", `/player/${segment(playerId)}/packages`, {
|
|
267
|
+
...options,
|
|
268
|
+
query
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
// src/resources/queue.ts
|
|
273
|
+
var QueueResource = class {
|
|
274
|
+
http;
|
|
275
|
+
constructor(http) {
|
|
276
|
+
this.http = http;
|
|
277
|
+
}
|
|
278
|
+
get(options) {
|
|
279
|
+
return this.http.request("GET", "/queue", options);
|
|
280
|
+
}
|
|
281
|
+
offlineCommands(options) {
|
|
282
|
+
return this.http.request("GET", "/queue/offline-commands", options);
|
|
283
|
+
}
|
|
284
|
+
onlineCommands(playerId, options) {
|
|
285
|
+
return this.http.request("GET", `/queue/online-commands/${segment(playerId)}`, options);
|
|
286
|
+
}
|
|
287
|
+
delete(ids, options) {
|
|
288
|
+
return this.http.request("DELETE", "/queue", {
|
|
289
|
+
...options,
|
|
290
|
+
body: { ids }
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
// src/resources/sales.ts
|
|
295
|
+
var SalesResource = class {
|
|
296
|
+
http;
|
|
297
|
+
constructor(http) {
|
|
298
|
+
this.http = http;
|
|
299
|
+
}
|
|
300
|
+
list(options) {
|
|
301
|
+
return this.http.requestData("GET", "/sales", options);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
// src/client.ts
|
|
305
|
+
var TebexClient = class {
|
|
306
|
+
information;
|
|
307
|
+
communityGoals;
|
|
308
|
+
payments;
|
|
309
|
+
packages;
|
|
310
|
+
checkout;
|
|
311
|
+
giftCards;
|
|
312
|
+
coupons;
|
|
313
|
+
bans;
|
|
314
|
+
sales;
|
|
315
|
+
players;
|
|
316
|
+
queue;
|
|
317
|
+
constructor(options = {}) {
|
|
318
|
+
const http = new Http(options);
|
|
319
|
+
this.information = new InformationResource(http);
|
|
320
|
+
this.communityGoals = new CommunityGoalsResource(http);
|
|
321
|
+
this.payments = new PaymentsResource(http);
|
|
322
|
+
this.packages = new PackagesResource(http);
|
|
323
|
+
this.checkout = new CheckoutResource(http);
|
|
324
|
+
this.giftCards = new GiftCardsResource(http);
|
|
325
|
+
this.coupons = new CouponsResource(http);
|
|
326
|
+
this.bans = new BansResource(http);
|
|
327
|
+
this.sales = new SalesResource(http);
|
|
328
|
+
this.players = new PlayersResource(http);
|
|
329
|
+
this.queue = new QueueResource(http);
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
export { TebexClient, TebexError };
|
|
333
|
+
|
|
334
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/errors.ts","../src/http.ts","../src/resources/bans.ts","../src/resources/checkout.ts","../src/resources/community-goals.ts","../src/resources/coupons.ts","../src/resources/gift-cards.ts","../src/resources/information.ts","../src/resources/packages.ts","../src/resources/payments.ts","../src/resources/players.ts","../src/resources/queue.ts","../src/resources/sales.ts","../src/client.ts"],"sourcesContent":["export class TebexError extends Error {\n override readonly name = \"TebexError\";\n\n readonly status: number;\n readonly code: number | undefined;\n readonly method: string;\n readonly path: string;\n readonly body: unknown;\n\n constructor(init: {\n message: string;\n status: number;\n code: number | undefined;\n method: string;\n path: string;\n body: unknown;\n }) {\n super(init.message);\n this.status = init.status;\n this.code = init.code;\n this.method = init.method;\n this.path = init.path;\n this.body = init.body;\n }\n}\n","import { TebexError } from \"./errors\";\n\nexport interface TebexClientOptions {\n secret?: string;\n baseUrl?: string;\n timeout?: number;\n fetch?: typeof fetch;\n}\n\nexport interface RequestOptions {\n signal?: AbortSignal;\n}\n\ninterface Init extends RequestOptions {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n}\n\ntype Method = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\nexport class Http {\n readonly #secret: string;\n readonly #baseUrl: string;\n readonly #timeout: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TebexClientOptions) {\n const secret =\n options.secret ?? (typeof process === \"undefined\" ? undefined : process.env.TEBEX_SECRET);\n if (!secret) {\n throw new TypeError(\n \"Missing Tebex secret. Pass `secret` or set the TEBEX_SECRET environment variable.\",\n );\n }\n if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n console.warn(\n \"[tebex-plugin-api] Your secret is exposed in the browser. Use this server-side only.\",\n );\n }\n\n this.#secret = secret;\n this.#baseUrl = (options.baseUrl ?? \"https://plugin.tebex.io\").replace(/\\/+$/, \"\");\n this.#timeout = options.timeout ?? 10_000;\n this.#fetch = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n async request<T>(method: Method, path: string, init: Init = {}): Promise<T> {\n const url = new URL(this.#baseUrl + path);\n for (const [key, value] of Object.entries(init.query ?? {})) {\n if (value !== undefined) url.searchParams.set(key, String(value));\n }\n\n const signals = [init.signal, this.#timeout > 0 && AbortSignal.timeout(this.#timeout)].filter(\n (signal) => !!signal,\n );\n const hasBody = init.body !== undefined;\n\n const response = await this.#fetch(url, {\n method,\n headers: {\n Accept: \"application/json\",\n \"X-Tebex-Secret\": this.#secret,\n ...(hasBody && { \"Content-Type\": \"application/json\" }),\n },\n body: hasBody ? JSON.stringify(init.body) : null,\n signal: signals.length ? AbortSignal.any(signals) : null,\n });\n\n // Some endpoints reply 201/204 with no body.\n const text = await response.text();\n const data = text ? parseJson(text) : undefined;\n\n if (!response.ok) {\n const error =\n typeof data === \"object\" && data !== null ? (data as Record<string, unknown>) : {};\n throw new TebexError({\n message:\n typeof error.error_message === \"string\"\n ? error.error_message\n : response.statusText || `HTTP ${response.status}`,\n status: response.status,\n code: typeof error.error_code === \"number\" ? error.error_code : undefined,\n method,\n path,\n body: data,\n });\n }\n\n return data as T;\n }\n\n async requestData<T>(method: Method, path: string, init?: Init): Promise<T> {\n return (await this.request<{ data: T }>(method, path, init)).data;\n }\n}\n\nfunction parseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nexport const segment = (value: string | number): string => encodeURIComponent(String(value));\n","import type { Http, RequestOptions } from \"../http\";\n\nexport interface Ban {\n id: number;\n time: string;\n ip: string;\n payment_email: string;\n reason: string;\n user: { ign: string; uuid: string };\n}\n\nexport interface CreateBanParams {\n user: string;\n reason?: string;\n ip?: string;\n}\n\nexport class BansResource {\n constructor(private readonly http: Http) {}\n\n list(options?: RequestOptions): Promise<Ban[]> {\n return this.http.requestData(\"GET\", \"/bans\", options);\n }\n\n create(params: CreateBanParams, options?: RequestOptions): Promise<Ban> {\n return this.http.requestData(\"POST\", \"/bans\", { ...options, body: params });\n }\n}\n","import type { Http, RequestOptions } from \"../http\";\n\nexport interface CreateCheckoutParams {\n package_id: number | string;\n username: string;\n}\n\nexport interface Checkout {\n url: string;\n expires: string;\n}\n\nexport class CheckoutResource {\n constructor(private readonly http: Http) {}\n\n create(params: CreateCheckoutParams, options?: RequestOptions): Promise<Checkout> {\n return this.http.request(\"POST\", \"/checkout\", { ...options, body: params });\n }\n}\n","import { type Http, type RequestOptions, segment } from \"../http\";\n\nexport interface CommunityGoal {\n id: number;\n created_at: string;\n updated_at: string;\n account: number;\n name: string;\n description: string;\n image: string;\n target: string;\n current: string;\n repeatable: number;\n last_achieved: string | null;\n times_achieved: number;\n status: \"active\" | (string & {});\n sale: number;\n}\n\nexport class CommunityGoalsResource {\n constructor(private readonly http: Http) {}\n\n list(options?: RequestOptions): Promise<CommunityGoal[]> {\n return this.http.request(\"GET\", \"/community_goals\", options);\n }\n\n get(id: number | string, options?: RequestOptions): Promise<CommunityGoal> {\n return this.http.request(\"GET\", `/community_goals/${segment(id)}`, options);\n }\n}\n","import { type Http, type RequestOptions, segment } from \"../http\";\nimport type { Page } from \"../types\";\n\ntype BoolString = boolean | \"true\" | \"false\";\n\nexport interface Coupon {\n id: number;\n code: string;\n effective: {\n type: \"cart\" | \"package\" | \"category\";\n packages: number[];\n categories: number[];\n };\n discount: {\n type: \"value\" | \"percentage\";\n percentage: number;\n value: number;\n };\n expire: {\n redeem_unlimited: BoolString;\n expire_never: BoolString;\n limit: number;\n date: string;\n };\n basket_type: \"single\" | \"subscription\" | \"both\";\n start_date: string;\n user_limit: number;\n minimum: number;\n discount_application_method?: number;\n username: string;\n note: string;\n}\n\ntype Discount =\n | { discount_type: \"percentage\"; discount_percentage: number }\n | { discount_type: \"value\"; discount_amount: number };\n\ntype Target =\n | { effective_on: \"cart\" }\n | { effective_on: \"package\"; packages: number[] }\n | { effective_on: \"category\"; categories: number[] };\n\nexport type CreateCouponParams = Discount &\n Target & {\n code: string;\n redeem_unlimited: boolean;\n expire_limit?: number;\n expire_never: boolean;\n expire_date?: string;\n start_date: string;\n basket_type: \"single\" | \"subscription\" | \"both\";\n minimum?: number;\n discount_application_method?: 0 | 1 | 2;\n username?: string;\n note?: string;\n };\n\nexport class CouponsResource {\n constructor(private readonly http: Http) {}\n\n async list(page?: number, options?: RequestOptions): Promise<Page<Coupon>> {\n const response = await this.http.request<{\n data: Coupon[];\n pagination: {\n totalResults: number;\n currentPage: number;\n lastPage: number;\n next: string | null;\n };\n }>(\"GET\", \"/coupons\", { ...options, query: { page } });\n\n return {\n items: response.data,\n page: response.pagination.currentPage,\n lastPage: response.pagination.lastPage,\n total: response.pagination.totalResults,\n hasNext: response.pagination.next !== null,\n };\n }\n\n get(id: number | string, options?: RequestOptions): Promise<Coupon> {\n return this.http.requestData(\"GET\", `/coupons/${segment(id)}`, options);\n }\n\n create(params: CreateCouponParams, options?: RequestOptions): Promise<Coupon> {\n return this.http.requestData(\"POST\", \"/coupons\", { ...options, body: params });\n }\n\n delete(id: number | string, options?: RequestOptions): Promise<void> {\n return this.http.request(\"DELETE\", `/coupons/${segment(id)}`, options);\n }\n}\n","import { type Http, type RequestOptions, segment } from \"../http\";\n\nexport interface GiftCard {\n id: number;\n code: string;\n balance: {\n starting: string;\n remaining: string;\n currency: string;\n };\n note: string;\n void: boolean;\n}\n\nexport interface CreateGiftCardParams {\n amount: number;\n note?: string;\n expires_at?: string;\n}\n\nexport class GiftCardsResource {\n constructor(private readonly http: Http) {}\n\n list(options?: RequestOptions): Promise<GiftCard[]> {\n return this.http.requestData(\"GET\", \"/gift-cards\", options);\n }\n\n get(id: number | string, options?: RequestOptions): Promise<GiftCard> {\n return this.http.requestData(\"GET\", `/gift-cards/${segment(id)}`, options);\n }\n\n lookup(code: string, options?: RequestOptions): Promise<GiftCard> {\n return this.http.requestData(\"GET\", `/gift-cards/lookup/${segment(code)}`, options);\n }\n\n create(params: CreateGiftCardParams, options?: RequestOptions): Promise<GiftCard> {\n return this.http.requestData(\"POST\", \"/gift-cards\", { ...options, body: params });\n }\n\n topUp(id: number | string, amount: number, options?: RequestOptions): Promise<GiftCard> {\n return this.http.requestData(\"PUT\", `/gift-cards/${segment(id)}`, {\n ...options,\n body: { amount: String(amount) },\n });\n }\n\n void(id: number | string, options?: RequestOptions): Promise<GiftCard> {\n return this.http.requestData(\"DELETE\", `/gift-cards/${segment(id)}`, options);\n }\n}\n","import type { Http, RequestOptions } from \"../http\";\nimport type { Currency } from \"../types\";\n\nexport interface ServerInformation {\n account: {\n id: number;\n domain: string;\n name: string;\n currency: Currency;\n online_mode: boolean;\n game_type: string;\n log_events: boolean;\n };\n server: { id: number; name: string };\n}\n\nexport class InformationResource {\n constructor(private readonly http: Http) {}\n\n get(options?: RequestOptions): Promise<ServerInformation> {\n return this.http.request(\"GET\", \"/information\", options);\n }\n}\n","import { type Http, type RequestOptions, segment } from \"../http\";\n\nexport interface UpdatePackageParams {\n disabled?: boolean;\n name?: string;\n price?: number;\n}\n\nexport class PackagesResource {\n constructor(private readonly http: Http) {}\n\n update(\n id: number | string,\n params: UpdatePackageParams,\n options?: RequestOptions,\n ): Promise<void> {\n return this.http.request(\"PUT\", `/package/${segment(id)}`, { ...options, body: params });\n }\n}\n","import { type Http, type RequestOptions, segment } from \"../http\";\nimport type { Currency, PackageRef, Page, Player } from \"../types\";\n\nexport type PaymentStatus = \"Complete\" | \"Refund\" | \"Chargeback\" | (string & {});\n\nexport interface Payment {\n id: number;\n amount: string;\n date: string;\n currency: Currency;\n status: PaymentStatus;\n player: Player;\n packages: PackageRef[];\n gateway?: { id: number; name: string };\n email?: string;\n notes?: { created_at: string; note: string }[];\n creator_code?: string | null;\n}\n\nexport interface PaymentField {\n name: string;\n type: \"numeric\" | \"dropdown\" | \"username\" | (string & {});\n description?: string;\n value?: string;\n options?: false | { label: string; value: string | number }[];\n}\n\nexport interface CreatePaymentParams {\n ign: string;\n price: number;\n packages: {\n id: number;\n options?: Record<string, string | number>;\n }[];\n note?: string;\n}\n\nexport interface UpdatePaymentParams {\n username?: string;\n status?: \"complete\" | \"chargeback\" | \"refund\";\n}\n\nexport class PaymentsResource {\n constructor(private readonly http: Http) {}\n\n list(query: { limit?: number } = {}, options?: RequestOptions): Promise<Payment[]> {\n return this.http.request(\"GET\", \"/payments\", { ...options, query });\n }\n\n async listPaged(page = 1, options?: RequestOptions): Promise<Page<Payment>> {\n const response = await this.http.request<{\n data: Payment[];\n total: number;\n current_page: number;\n last_page: number;\n next_page_url: string | null;\n }>(\"GET\", \"/payments\", { ...options, query: { paged: 1, page } });\n\n return {\n items: response.data,\n page: response.current_page,\n lastPage: response.last_page,\n total: response.total,\n hasNext: response.next_page_url !== null,\n };\n }\n\n get(transaction: string, options?: RequestOptions): Promise<Payment> {\n return this.http.request(\"GET\", `/payments/${segment(transaction)}`, options);\n }\n\n requiredFields(packageId: number | string, options?: RequestOptions): Promise<PaymentField[]> {\n return this.http.request(\"GET\", `/payments/fields/${segment(packageId)}`, options);\n }\n\n create(params: CreatePaymentParams, options?: RequestOptions): Promise<void> {\n return this.http.request(\"POST\", \"/payments\", { ...options, body: params });\n }\n\n update(\n transaction: string,\n params: UpdatePaymentParams,\n options?: RequestOptions,\n ): Promise<void> {\n return this.http.request(\"PUT\", `/payments/${segment(transaction)}`, {\n ...options,\n body: params,\n });\n }\n\n addNote(transaction: string, note: string, options?: RequestOptions): Promise<void> {\n return this.http.request(\"POST\", `/payments/${segment(transaction)}/note`, {\n ...options,\n body: { note },\n });\n }\n}\n","import { type Http, type RequestOptions, segment } from \"../http\";\nimport type { PackageRef } from \"../types\";\n\nexport interface PlayerLookup {\n player: {\n id: string;\n username: string;\n meta: string;\n plugin_username_id: number;\n };\n banCount: number;\n chargebackRate: number;\n payments: {\n txn_id: string;\n time: number;\n price: number;\n currency: string;\n status: number;\n }[];\n purchaseTotals: Record<string, number>;\n}\n\nexport interface ActivePackage {\n txn_id: string;\n date: string;\n quantity: number;\n package: PackageRef;\n}\n\nexport class PlayersResource {\n constructor(private readonly http: Http) {}\n\n lookup(user: string, options?: RequestOptions): Promise<PlayerLookup> {\n return this.http.request(\"GET\", `/user/${segment(user)}`, options);\n }\n\n activePackages(\n playerId: number | string,\n query: { package?: number } = {},\n options?: RequestOptions,\n ): Promise<ActivePackage[]> {\n return this.http.request(\"GET\", `/player/${segment(playerId)}/packages`, {\n ...options,\n query,\n });\n }\n}\n","import { type Http, type RequestOptions, segment } from \"../http\";\nimport type { Player } from \"../types\";\n\nexport interface DueQueue {\n meta: {\n execute_offline: boolean;\n next_check: number;\n more: boolean;\n };\n players: Player[];\n}\n\nexport interface OfflineCommand {\n id: number;\n command: string;\n payment: number;\n package: number;\n conditions: { delay: number };\n player: Player;\n}\n\nexport interface OfflineCommands {\n meta: { limited: boolean };\n commands: OfflineCommand[];\n}\n\nexport interface OnlineCommand {\n id: number;\n command: string;\n payment: number;\n package: number;\n conditions: { delay: number; slots: number };\n}\n\nexport interface OnlineCommands {\n commands: OnlineCommand[];\n}\n\nexport class QueueResource {\n constructor(private readonly http: Http) {}\n\n get(options?: RequestOptions): Promise<DueQueue> {\n return this.http.request(\"GET\", \"/queue\", options);\n }\n\n offlineCommands(options?: RequestOptions): Promise<OfflineCommands> {\n return this.http.request(\"GET\", \"/queue/offline-commands\", options);\n }\n\n onlineCommands(playerId: string | number, options?: RequestOptions): Promise<OnlineCommands> {\n return this.http.request(\"GET\", `/queue/online-commands/${segment(playerId)}`, options);\n }\n\n delete(ids: number[], options?: RequestOptions): Promise<void> {\n return this.http.request(\"DELETE\", \"/queue\", { ...options, body: { ids } });\n }\n}\n","import type { Http, RequestOptions } from \"../http\";\n\nexport interface Sale {\n id: number;\n name: string;\n effective: {\n type: \"package\" | \"category\" | (string & {});\n packages: number[];\n categories: number[];\n };\n discount: {\n type: \"percentage\" | \"value\";\n percentage: number;\n value: number;\n };\n start: number;\n expire: number;\n order: number;\n}\n\nexport class SalesResource {\n constructor(private readonly http: Http) {}\n\n list(options?: RequestOptions): Promise<Sale[]> {\n return this.http.requestData(\"GET\", \"/sales\", options);\n }\n}\n","import { Http, type TebexClientOptions } from \"./http\";\nimport {\n BansResource,\n CheckoutResource,\n CommunityGoalsResource,\n CouponsResource,\n GiftCardsResource,\n InformationResource,\n PackagesResource,\n PaymentsResource,\n PlayersResource,\n QueueResource,\n SalesResource,\n} from \"./resources\";\n\nexport class TebexClient {\n readonly information: InformationResource;\n readonly communityGoals: CommunityGoalsResource;\n readonly payments: PaymentsResource;\n readonly packages: PackagesResource;\n readonly checkout: CheckoutResource;\n readonly giftCards: GiftCardsResource;\n readonly coupons: CouponsResource;\n readonly bans: BansResource;\n readonly sales: SalesResource;\n readonly players: PlayersResource;\n readonly queue: QueueResource;\n\n constructor(options: TebexClientOptions = {}) {\n const http = new Http(options);\n\n this.information = new InformationResource(http);\n this.communityGoals = new CommunityGoalsResource(http);\n this.payments = new PaymentsResource(http);\n this.packages = new PackagesResource(http);\n this.checkout = new CheckoutResource(http);\n this.giftCards = new GiftCardsResource(http);\n this.coupons = new CouponsResource(http);\n this.bans = new BansResource(http);\n this.sales = new SalesResource(http);\n this.players = new PlayersResource(http);\n this.queue = new QueueResource(http);\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tebex-plugin-api",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Unofficial, fully typed TypeScript SDK for the Tebex Plugin (Game Server) API.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"game-server-api",
|
|
7
|
+
"plugin-api",
|
|
8
|
+
"sdk",
|
|
9
|
+
"tebex",
|
|
10
|
+
"typescript"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/heyxmirko/tebex-plugin-api#readme",
|
|
13
|
+
"bugs": "https://github.com/heyxmirko/tebex-plugin-api/issues",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": "heyxmirko",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/heyxmirko/tebex-plugin-api.git"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"main": "./dist/index.mjs",
|
|
26
|
+
"types": "./dist/index.d.mts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.mts",
|
|
30
|
+
"import": "./dist/index.mjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "vp pack",
|
|
35
|
+
"test": "vp test",
|
|
36
|
+
"check": "vp check",
|
|
37
|
+
"prepublishOnly": "vp check && vp test && vp pack"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^22.0.0",
|
|
41
|
+
"typescript": "^5.9.0",
|
|
42
|
+
"vite-plus": "^1.6.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=22"
|
|
46
|
+
}
|
|
47
|
+
}
|