unb-api 1.4.0 → 2.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/README.md +4 -1
- package/eslintrc.js +7 -0
- package/index.d.ts +2 -1
- package/package.json +4 -4
- package/src/lib/Client.js +1 -0
- package/src/lib/RequestHandler.js +45 -19
- package/src/lib/structures/items/StoreItem.js +1 -0
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
`npm install unb-api`
|
|
12
12
|
|
|
13
|
+
Requires Node.js 18 or newer (uses the built-in `fetch`). For older Node.js versions, use `unb-api@1`.
|
|
14
|
+
|
|
13
15
|
## Documentation
|
|
14
16
|
|
|
15
17
|
Full API documentation is located at [https://unbelievaboat.com/api/docs](https://unbelievaboat.com/api/docs)
|
|
@@ -89,7 +91,7 @@ Returns: `Promise<{ page: number, totalPages: number, items: InventoryItem[] }>`
|
|
|
89
91
|
`getInventoryItem(guildId: string, userId: string, itemId: string)`
|
|
90
92
|
Returns: `Promise<InventoryItem>`
|
|
91
93
|
|
|
92
|
-
`addInventoryItem(guildId: string, userId: string, itemId: string, quantity?: string | number, options?: { inventoryUserId?: string })`
|
|
94
|
+
`addInventoryItem(guildId: string, userId: string, itemId: string, quantity?: string | number, options?: { inventoryUserId?: string, ignoreMaxQuantity?: boolean })`
|
|
93
95
|
Returns: `Promise<InventoryItem>`
|
|
94
96
|
|
|
95
97
|
`removeInventoryItem(guildId: string, userId: string, itemId: string, quantity?: string | number)`
|
|
@@ -138,6 +140,7 @@ Returns: `Promise<any>`
|
|
|
138
140
|
| Number | `price` | Price of the item. |
|
|
139
141
|
| Number | `stockRemaining` | Amount of stock remaining for the item. |
|
|
140
142
|
| Boolean | `unlimitedStock` | Whether the item has unlimited stock. |
|
|
143
|
+
| Number | `maxQuantity?` | Max a user can own, or buy at once if not an inventory item. |
|
|
141
144
|
| Boolean | `isInventory` | Indicates if the item will be added to a user’s inventory when purchased. |
|
|
142
145
|
| Date | `expiresAt?` | Expiration date of the item. |
|
|
143
146
|
| Boolean | `isUsable` | Whether the item can be used by the user. |
|
package/eslintrc.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ declare module 'unb-api' {
|
|
|
37
37
|
|
|
38
38
|
public getInventoryItem(guildId: string, userId: string, itemId: string): Promise<InventoryItem>
|
|
39
39
|
|
|
40
|
-
public addInventoryItem(guildId: string, userId: string, itemId: string, quantity?: string | number, options?: { inventoryUserId?: string }): Promise<InventoryItem>
|
|
40
|
+
public addInventoryItem(guildId: string, userId: string, itemId: string, quantity?: string | number, options?: { inventoryUserId?: string, ignoreMaxQuantity?: boolean }): Promise<InventoryItem>
|
|
41
41
|
|
|
42
42
|
public removeInventoryItem(guildId: string, userId: string, itemId: string, quantity?: string | number): Promise<any>
|
|
43
43
|
|
|
@@ -111,6 +111,7 @@ declare module 'unb-api' {
|
|
|
111
111
|
public price: number;
|
|
112
112
|
public stockRemaining: number;
|
|
113
113
|
public unlimitedStock: boolean;
|
|
114
|
+
public maxQuantity: number | null;
|
|
114
115
|
public isInventory: boolean;
|
|
115
116
|
public expiresAt?: Date;
|
|
116
117
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unb-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "API wrapper for UnbelievaBoat Discord Bot API",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
],
|
|
17
17
|
"author": "unbelievable",
|
|
18
18
|
"license": "MIT",
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
19
22
|
"devDependencies": {
|
|
20
23
|
"@types/node": "^10.0.7",
|
|
21
24
|
"eslint": "^6.7.2",
|
|
22
25
|
"typescript": "^2.6.2"
|
|
23
|
-
},
|
|
24
|
-
"dependencies": {
|
|
25
|
-
"axios": "1.6.0"
|
|
26
26
|
}
|
|
27
27
|
}
|
package/src/lib/Client.js
CHANGED
|
@@ -336,6 +336,7 @@ class Client {
|
|
|
336
336
|
* @param {number|string} [quantity=1] - Quantity to add
|
|
337
337
|
* @param {object} [options]
|
|
338
338
|
* @param {string} [options.inventoryUserId] - User ID of the inventory to add the item from (can be used if the item no longer exists in the store or the item settings differ)
|
|
339
|
+
* @param {boolean} [options.ignoreMaxQuantity=false] - Add the item even if the user would own more than the item's max quantity
|
|
339
340
|
* @returns {Promise<InventoryItem>}
|
|
340
341
|
*
|
|
341
342
|
* @see {@link https://unbelievaboat-api.readme.io/reference/add-inventory-item|Add Inventory Item}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const axios = require('axios');
|
|
2
1
|
const Bucket = require('./util/Bucket');
|
|
3
2
|
const { APIError, HTTPError } = require('./errors');
|
|
4
3
|
const MajorParams = ['guilds'];
|
|
@@ -7,13 +6,6 @@ class RequestHandler {
|
|
|
7
6
|
constructor(client) {
|
|
8
7
|
this._client = client;
|
|
9
8
|
this.ratelimits = {};
|
|
10
|
-
this.axiosInstance = axios.create({
|
|
11
|
-
baseURL: this._client.baseURL,
|
|
12
|
-
headers: {
|
|
13
|
-
'Authorization': this._client.token,
|
|
14
|
-
'Content-Type': 'application/json'
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
9
|
}
|
|
18
10
|
|
|
19
11
|
async request(method, endpoint, data = {}, params = {}, _attempts = 0) {
|
|
@@ -32,7 +24,7 @@ class RequestHandler {
|
|
|
32
24
|
};
|
|
33
25
|
|
|
34
26
|
try {
|
|
35
|
-
const { data: responseData, status, headers } = await this.
|
|
27
|
+
const { data: responseData, status, statusText, headers } = await this.fetch(options);
|
|
36
28
|
|
|
37
29
|
// Increase the number of attempts
|
|
38
30
|
++_attempts;
|
|
@@ -44,21 +36,17 @@ class RequestHandler {
|
|
|
44
36
|
resolve(responseData);
|
|
45
37
|
} else if (status === 429) {
|
|
46
38
|
if (_attempts >= this._client.maxRetries) {
|
|
47
|
-
this.rejectWithError(options, responseData, status, reject);
|
|
39
|
+
this.rejectWithError(options, responseData, status, statusText, reject);
|
|
48
40
|
} else {
|
|
49
41
|
this.retryRequest(method, endpoint, data, params, _attempts, headers, resolve, reject);
|
|
50
42
|
}
|
|
51
43
|
} else {
|
|
52
|
-
this.rejectWithError(options, responseData, status, reject);
|
|
44
|
+
this.rejectWithError(options, responseData, status, statusText, reject);
|
|
53
45
|
}
|
|
54
46
|
|
|
55
47
|
callback();
|
|
56
48
|
} catch (error) {
|
|
57
|
-
|
|
58
|
-
this.rejectWithError(options, error.response.data, error.response.status, reject);
|
|
59
|
-
} else {
|
|
60
|
-
reject(error);
|
|
61
|
-
}
|
|
49
|
+
reject(error);
|
|
62
50
|
callback();
|
|
63
51
|
}
|
|
64
52
|
};
|
|
@@ -67,11 +55,49 @@ class RequestHandler {
|
|
|
67
55
|
});
|
|
68
56
|
}
|
|
69
57
|
|
|
70
|
-
|
|
58
|
+
async fetch(options) {
|
|
59
|
+
const url = new URL(`${this._client.baseURL.replace(/\/+$/, '')}${options.url}`);
|
|
60
|
+
for (const [key, value] of Object.entries(options.params || {})) {
|
|
61
|
+
if (value === undefined || value === null) continue;
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
for (const v of value) url.searchParams.append(`${key}[]`, v);
|
|
64
|
+
} else {
|
|
65
|
+
url.searchParams.append(key, value);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const response = await fetch(url, {
|
|
70
|
+
method: options.method,
|
|
71
|
+
headers: {
|
|
72
|
+
'Authorization': this._client.token,
|
|
73
|
+
'Content-Type': 'application/json'
|
|
74
|
+
},
|
|
75
|
+
body: ['GET', 'HEAD'].includes(options.method) ? undefined : JSON.stringify(options.data)
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const text = await response.text();
|
|
79
|
+
let data = text;
|
|
80
|
+
if (text) {
|
|
81
|
+
try {
|
|
82
|
+
data = JSON.parse(text);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
// Not JSON (e.g. an HTML error page from a proxy), keep the raw text
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
data,
|
|
90
|
+
status: response.status,
|
|
91
|
+
statusText: response.statusText,
|
|
92
|
+
headers: Object.fromEntries(response.headers)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
rejectWithError(options, data, status, statusText, reject) {
|
|
71
97
|
if (data && data.message) {
|
|
72
|
-
reject(new APIError(options, { data, status }));
|
|
98
|
+
reject(new APIError(options, { data, status, statusText }));
|
|
73
99
|
} else {
|
|
74
|
-
reject(new HTTPError(options, { data, status }));
|
|
100
|
+
reject(new HTTPError(options, { data, status, statusText }));
|
|
75
101
|
}
|
|
76
102
|
}
|
|
77
103
|
|
|
@@ -8,6 +8,7 @@ class StoreItem extends BaseItem {
|
|
|
8
8
|
this.isInventory = data.is_inventory;
|
|
9
9
|
this.stockRemaining = data.stock_remaining;
|
|
10
10
|
this.unlimitedStock = data.unlimited_stock;
|
|
11
|
+
this.maxQuantity = data.max_quantity ?? null;
|
|
11
12
|
if (data.expires_at) {
|
|
12
13
|
this.expiresAt = new Date(data.expires_at);
|
|
13
14
|
}
|