51 |
52 |
55 |
56 |
57 |
58 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/docs/staged/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | /*global document */
2 | (() => {
3 | const source = document.getElementsByClassName('prettyprint source linenums');
4 | let i = 0;
5 | let lineNumber = 0;
6 | let lineId;
7 | let lines;
8 | let totalLines;
9 | let anchorHash;
10 |
11 | if (source && source[0]) {
12 | anchorHash = document.location.hash.substring(1);
13 | lines = source[0].getElementsByTagName('li');
14 | totalLines = lines.length;
15 |
16 | for (; i < totalLines; i++) {
17 | lineNumber++;
18 | lineId = `line${lineNumber}`;
19 | lines[i].id = lineId;
20 | if (lineId === anchorHash) {
21 | lines[i].className += ' selected';
22 | }
23 | }
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/docs/staged/scripts/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/docs/staged/styles/prettify-jsdoc.css:
--------------------------------------------------------------------------------
1 | /* JSDoc prettify.js theme */
2 |
3 | /* plain text */
4 | .pln {
5 | color: #000000;
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | /* string content */
11 | .str {
12 | color: #006400;
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
17 | /* a keyword */
18 | .kwd {
19 | color: #000000;
20 | font-weight: bold;
21 | font-style: normal;
22 | }
23 |
24 | /* a comment */
25 | .com {
26 | font-weight: normal;
27 | font-style: italic;
28 | }
29 |
30 | /* a type name */
31 | .typ {
32 | color: #000000;
33 | font-weight: normal;
34 | font-style: normal;
35 | }
36 |
37 | /* a literal value */
38 | .lit {
39 | color: #006400;
40 | font-weight: normal;
41 | font-style: normal;
42 | }
43 |
44 | /* punctuation */
45 | .pun {
46 | color: #000000;
47 | font-weight: bold;
48 | font-style: normal;
49 | }
50 |
51 | /* lisp open bracket */
52 | .opn {
53 | color: #000000;
54 | font-weight: bold;
55 | font-style: normal;
56 | }
57 |
58 | /* lisp close bracket */
59 | .clo {
60 | color: #000000;
61 | font-weight: bold;
62 | font-style: normal;
63 | }
64 |
65 | /* a markup tag name */
66 | .tag {
67 | color: #006400;
68 | font-weight: normal;
69 | font-style: normal;
70 | }
71 |
72 | /* a markup attribute name */
73 | .atn {
74 | color: #006400;
75 | font-weight: normal;
76 | font-style: normal;
77 | }
78 |
79 | /* a markup attribute value */
80 | .atv {
81 | color: #006400;
82 | font-weight: normal;
83 | font-style: normal;
84 | }
85 |
86 | /* a declaration */
87 | .dec {
88 | color: #000000;
89 | font-weight: bold;
90 | font-style: normal;
91 | }
92 |
93 | /* a variable name */
94 | .var {
95 | color: #000000;
96 | font-weight: normal;
97 | font-style: normal;
98 | }
99 |
100 | /* a function name */
101 | .fun {
102 | color: #000000;
103 | font-weight: bold;
104 | font-style: normal;
105 | }
106 |
107 | /* Specify class=linenums on a pre to get line numbering */
108 | ol.linenums {
109 | margin-top: 0;
110 | margin-bottom: 0;
111 | }
112 |
--------------------------------------------------------------------------------
/docs/staged/styles/prettify-tomorrow.css:
--------------------------------------------------------------------------------
1 | /* Tomorrow Theme */
2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */
3 | /* Pretty printing styles. Used with prettify.js. */
4 | /* SPAN elements with the classes below are added by prettyprint. */
5 | /* plain text */
6 | .pln {
7 | color: #4d4d4c; }
8 |
9 | @media screen {
10 | /* string content */
11 | .str {
12 | color: #718c00; }
13 |
14 | /* a keyword */
15 | .kwd {
16 | color: #8959a8; }
17 |
18 | /* a comment */
19 | .com {
20 | color: #8e908c; }
21 |
22 | /* a type name */
23 | .typ {
24 | color: #4271ae; }
25 |
26 | /* a literal value */
27 | .lit {
28 | color: #f5871f; }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #4d4d4c; }
33 |
34 | /* lisp open bracket */
35 | .opn {
36 | color: #4d4d4c; }
37 |
38 | /* lisp close bracket */
39 | .clo {
40 | color: #4d4d4c; }
41 |
42 | /* a markup tag name */
43 | .tag {
44 | color: #c82829; }
45 |
46 | /* a markup attribute name */
47 | .atn {
48 | color: #f5871f; }
49 |
50 | /* a markup attribute value */
51 | .atv {
52 | color: #3e999f; }
53 |
54 | /* a declaration */
55 | .dec {
56 | color: #f5871f; }
57 |
58 | /* a variable name */
59 | .var {
60 | color: #c82829; }
61 |
62 | /* a function name */
63 | .fun {
64 | color: #4271ae; } }
65 | /* Use higher contrast and text-weight for printable form. */
66 | @media print, projection {
67 | .str {
68 | color: #060; }
69 |
70 | .kwd {
71 | color: #006;
72 | font-weight: bold; }
73 |
74 | .com {
75 | color: #600;
76 | font-style: italic; }
77 |
78 | .typ {
79 | color: #404;
80 | font-weight: bold; }
81 |
82 | .lit {
83 | color: #044; }
84 |
85 | .pun, .opn, .clo {
86 | color: #440; }
87 |
88 | .tag {
89 | color: #006;
90 | font-weight: bold; }
91 |
92 | .atn {
93 | color: #404; }
94 |
95 | .atv {
96 | color: #060; } }
97 | /* Style */
98 | /*
99 | pre.prettyprint {
100 | background: white;
101 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
102 | font-size: 12px;
103 | line-height: 1.5;
104 | border: 1px solid #ccc;
105 | padding: 10px; }
106 | */
107 |
108 | /* Specify class=linenums on a pre to get line numbering */
109 | ol.linenums {
110 | margin-top: 0;
111 | margin-bottom: 0; }
112 |
113 | /* IE indents via margin-left */
114 | li.L0,
115 | li.L1,
116 | li.L2,
117 | li.L3,
118 | li.L4,
119 | li.L5,
120 | li.L6,
121 | li.L7,
122 | li.L8,
123 | li.L9 {
124 | /* */ }
125 |
126 | /* Alternate shading for lines */
127 | li.L1,
128 | li.L3,
129 | li.L5,
130 | li.L7,
131 | li.L9 {
132 | /* */ }
133 |
--------------------------------------------------------------------------------
/examples/conversation-verification.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 | const readline = require("readline");
6 |
7 | const rl = readline.createInterface({
8 | input: process.stdin,
9 | output: process.stdout
10 | });
11 |
12 | let token = new Token(TokenType.PRIVATE, "Find @ https://builtbybit.com/account/api");
13 | let wrapper = new Wrapper();
14 |
15 |
16 | async function main() {
17 | await wrapper.init(token);
18 |
19 | let title = "Verification";
20 | let message = "This message verifies that I am speaking with you.";
21 |
22 | rl.question("What is the ID of the user you'd like to start a conversation with?", (userId) => {
23 | let conversation = wrapper.conversations().start(title, message, new Array(userId));
24 | console.info("Conversation " + conversation + " created for verification");
25 | });
26 |
27 | }
28 |
29 | main().catch(error => console.error("ERROR: " + error));
--------------------------------------------------------------------------------
/examples/delete-all-versions.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 |
6 | let token = new Token(TokenType.PRIVATE, "Find @ https://builtbybit.com/account/api");
7 | let wrapper = new Wrapper();
8 |
9 | let resourceId = 0;
10 |
11 | async function main() {
12 | await wrapper.init(token);
13 |
14 | let versions = await wrapper.resources().versions().listAll(resourceId);
15 |
16 | // The current version cannot be deleted so we remove it from the returned list of versions.
17 | versions.shift();
18 |
19 | for (const index in versions) {
20 | let versionId = versions[index]["version_id"];
21 |
22 | await wrapper.resources().versions().delete(resourceId, versionId);
23 | console.log("Successfully deleted version with id: " + versionId);
24 | }
25 | }
26 |
27 | main().catch(error => console.error("ERROR: " + error));
28 |
--------------------------------------------------------------------------------
/examples/discord-identity-bot/index.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType, Error } = require("@builtbybit/api-wrapper");
5 | const { Client, Intents } = require('discord.js');
6 |
7 | const bbbToken = new Token(TokenType.PRIVATE, "Find @ https://builtbybit.com/account/api");
8 | const botToken = "Find @ https://discord.com/developers/applications";
9 |
10 | const GUILD_ID = "0";
11 | const ROLE_ID = "0";
12 | const CHANNEL_ID = "0";
13 |
14 | let guild = undefined;
15 | let channel = undefined;
16 | let role = undefined;
17 |
18 | const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
19 | const wrapper = new Wrapper();
20 |
21 | async function main() {
22 | await client.login(botToken);
23 | await wrapper.init(bbbToken);
24 |
25 | guild = await client.guilds.fetch(GUILD_ID);
26 | channel = await client.channels.fetch(CHANNEL_ID);
27 | role = await guild.roles.fetch(ROLE_ID);
28 |
29 | client.on("guildMemberAdd", join);
30 | }
31 |
32 | async function join(user) {
33 | if (user.guild.id !== guild.id) return;
34 |
35 | let member;
36 | try {
37 | member = await wrapper.members().fetchByDiscord(Number(user.user.id));
38 | } catch (error) {
39 | if (error instanceof Error && error.code() === "MemberNotFound") {
40 | await channel.send(`[BuiltByBit] No member found for ${user}.`);
41 | }
42 |
43 | throw error;
44 | }
45 |
46 | let member_url = `https://wbuiltbybit.com/members/${member.member_id}/`;
47 | await channel.send(`[BuiltByBit] A member was found for ${user}: '${member.username}' (${member_url}).`);
48 |
49 | await user.roles.add(role);
50 | }
51 |
52 | main().catch(error => console.error("ERROR: " + error));
--------------------------------------------------------------------------------
/examples/discord-identity-bot/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "discord-identity-bot",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "discord.js": "^13.6.0",
13 | "@builtbybit/api-wrapper": "^1.1.4"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/examples/download-verification.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2025 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 | const readline = require("readline");
6 | const { table } = require("table");
7 |
8 | const rl = readline.createInterface({
9 | input: process.stdin,
10 | output: process.stdout
11 | });
12 |
13 | const config = {
14 | header: {
15 | alignment: "center",
16 | content: "BuiltByBit Download Verification"
17 | }
18 | };
19 |
20 | let token = new Token(TokenType.PRIVATE, "Find @ https://builtbybit.com/account/api");
21 | let wrapper = new Wrapper();
22 |
23 | async function main() {
24 | await wrapper.init(token);
25 |
26 | let ownedResources = await wrapper.resources().listOwnedAll().catch(e => { console.error(e); });
27 | let resourceIds = [["Resource Title", "Resource ID"]];
28 | for (const resource of ownedResources) {
29 | resourceIds.push([resource.title, resource.resource_id]);
30 | }
31 | const ownedConfig = {
32 | header: {
33 | alignment: "center",
34 | content: "BuiltByBit Download Verification\nOwned Resources"
35 | }
36 | };
37 | console.log(table(resourceIds, ownedConfig));
38 |
39 | rl.question("Lookup by (u)sername or by (r)esource id? ", async (answer) =>{
40 | let downloadDetails;
41 | let user;
42 | let downloads = [];
43 | switch (answer.toLowerCase()) {
44 | case "u":
45 | try {
46 | rl.question("What is the username of the user you'd like to lookup? ", async (username) => {
47 | user = await wrapper.members().fetchByUsername(username).catch(e => { console.error(e); });
48 | console.log("Fetching...");
49 | downloads.push(["Resource Title", "Resource ID", "Download Date"]);
50 | for (const resource of ownedResources) {
51 | // eslint-disable-next-line max-len
52 | downloadDetails = await wrapper.resources().downloads().listByMemberAll(resource.resource_id, user.member_id).catch(e => { console.error(e); });
53 | for (const download of downloadDetails) {
54 | // eslint-disable-next-line max-len
55 | downloads.push([resource.title, resource.resource_id, new Date(download.download_date * 1000).toLocaleString()]);
56 | }
57 | }
58 | console.log(table(downloads, config));
59 | rl.close();
60 | });
61 | } catch (e) {
62 | console.error(e);
63 | rl.close();
64 | }
65 | break;
66 | case "r":
67 | try {
68 | rl.question("What is the resource id of the resource you'd like to lookup? ", async (resourceId) => {
69 | // eslint-disable-next-line max-len
70 | downloadDetails = await wrapper.resources().downloads().listAll(resourceId).catch(e => { console.error(e); });
71 | downloads.push(["Username", "Member ID", "Download Date"]);
72 | console.log("Fetching...");
73 | for (const download of downloadDetails) {
74 | user = await wrapper.members().fetch(download.downloader_id).catch(e => { console.error(e); });
75 | // eslint-disable-next-line max-len
76 | downloads.push([user.username, user.member_id, new Date(download.download_date * 1000).toLocaleString()]);
77 | }
78 | console.log(table(downloads, config));
79 | rl.close();
80 | });
81 | } catch (e) {
82 | console.error(e);
83 | rl.close();
84 | }
85 | break;
86 | default:
87 | console.error("Invalid input. Please try again.");
88 | rl.close();
89 | break;
90 | }
91 | });
92 | }
93 |
94 | main().catch(error => console.error("ERROR: " + error));
--------------------------------------------------------------------------------
/examples/export-purchases-csv.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 | const fs = require("fs");
6 |
7 | let token = new Token(TokenType.PRIVATE, "Find @ https://builtbybit.com/account/api");
8 | let wrapper = new Wrapper();
9 |
10 | async function main() {
11 | await wrapper.init(token);
12 |
13 | let ownedResources = await wrapper.resources().listOwnedAll();
14 | let fileData = "Resource ID,Purchase ID,Member ID,Renewal,Price,Currency,Date\n";
15 |
16 | for (const rIndex in ownedResources) {
17 | let resourceId = ownedResources[rIndex]["resource_id"];
18 | let purchases = await wrapper.resources().purchases().listAll(resourceId);
19 |
20 | for (const pIndex in purchases) {
21 | let purchaseId = purchases[pIndex]["purchase_id"];
22 | let memberId = purchases[pIndex]["purchaser_id"];
23 | let renewal = purchases[pIndex]["renewal"];
24 | let price = purchases[pIndex]["price"];
25 | let currency = purchases[pIndex]["currency"];
26 | let date = purchases[pIndex]["purchase_date"];
27 |
28 | fileData += `${resourceId},${purchaseId},${memberId},${renewal},${price},${currency},${date}\n`;
29 | }
30 |
31 | console.log(`Fetched all purchases for ${resourceId}.`);
32 | }
33 |
34 | await fs.promises.writeFile("./purchases.csv", fileData);
35 | console.log("Done!");
36 | }
37 |
38 | main().catch(error => console.error("ERROR: " + error));
39 |
--------------------------------------------------------------------------------
/examples/license-check.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 |
6 | let token = new Token(TokenType.SHARED, "Find @ https://builtbybit.com/account/api");
7 | let wrapper = new Wrapper();
8 |
9 | // Injected placeholders.
10 | let resourceId = Number("%%__RESOURCE__%%");
11 | let memberId = Number("%%__USER__%%");
12 | let nonce = Number("%%__NONCE__%%");
13 | let timestamp = Number("%%__TIMESTAMP__%%");
14 |
15 | async function main() {
16 | await wrapper.init(token);
17 |
18 | let license = await wrapper.resources().licenses().fetchMember(resourceId, memberId, nonce, timestamp);
19 | let currentTimestamp = Math.floor(new Date().getTime() / 1000);
20 |
21 | if (license.permanent && !license.active) {
22 | throw "A license has been found but it isn't currently active.";
23 | }
24 |
25 | if (!license.permanent && (license["start_date"] > currentTimestamp || license["end_date"] < currentTimestamp)) {
26 | throw "A license has been found but it has since expired.";
27 | }
28 |
29 | console.log("Active license found, returning from function without throwing an error.");
30 | }
31 |
32 | main().catch(error => console.error("ERROR: " + error));
33 |
--------------------------------------------------------------------------------
/examples/lookup-user.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 | const readline = require("readline");
6 |
7 | const rl = readline.createInterface({
8 | input: process.stdin,
9 | output: process.stdout
10 | });
11 |
12 | let token = new Token(TokenType.PRIVATE, "Find @ https://builtbybit.com/account/api");
13 | let wrapper = new Wrapper();
14 |
15 | async function main() {
16 | await wrapper.init(token);
17 |
18 | rl.question("Lookup by (u)sername or by (i)d? ", (answer) => {
19 | let userObj;
20 | switch (answer.toLowerCase()) {
21 | case "u":
22 | try {
23 | rl.question("What is the username of the user you'd like to lookup? ", async (username) => {
24 | userObj = await wrapper.members().fetchByUsername(username).catch(e => { console.error(e); });
25 | let memberId = userObj.member_id;
26 | let joinDate = userObj.join_date;
27 | let lastActivityDate = userObj.last_activity_date;
28 | let banned = userObj.banned;
29 | let suspended = userObj.suspended;
30 | let restricted = userObj.restricted;
31 | let disabled = userObj.disabled;
32 | let postCount = userObj.post_count;
33 | // eslint-disable-next-line max-len
34 | let message = `${username}'s Statistics:\nMember Id: ${memberId}\nJoin Date: ${new Date(joinDate * 1000)}\nLast Activity: ${new Date(lastActivityDate * 1000)}\nBanned: ${banned}\nSuspended: ${suspended}\nRestricted: ${restricted}\nDisabled: ${disabled}\nPost Count: ${postCount}`;
35 | console.log(message);
36 | rl.close();
37 | });
38 | } catch (error) {
39 | console.log("Error: " + error);
40 | }
41 | break;
42 | case "i":
43 | try {
44 | rl.question("What is the ID of the user you'd like to lookup? ", async (userId) => {
45 | let userObj = await wrapper.members().fetch(userId).catch(e => { console.log(e); });
46 | let username = userObj.username;
47 | let joinDate = userObj.join_date;
48 | let lastActivityDate = userObj.last_activity_date;
49 | let banned = userObj.banned;
50 | let suspended = userObj.suspended;
51 | let restricted = userObj.restricted;
52 | let disabled = userObj.disabled;
53 | let postCount = userObj.post_count;
54 |
55 | // eslint-disable-next-line max-len
56 | let message = `${userId}'s Statistics:\nUsername: ${username}\nJoin Date: ${new Date(joinDate * 1000)}\nLast Activity: ${new Date(lastActivityDate * 1000)}\nBanned: ${banned}\nSuspended: ${suspended}\nRestricted: ${restricted}\nDisabled: ${disabled}\nPost Count: ${postCount}`;
57 |
58 | console.log(message);
59 | rl.close();
60 | });
61 | } catch (error) {
62 | console.log("ERROR: " + error);
63 | }
64 | break;
65 | default:
66 | console.log("Invalid Answer");
67 | }
68 | });
69 | }
70 |
71 | main().catch(error => console.error("ERROR: " + error));
--------------------------------------------------------------------------------
/examples/pm-on-purchase.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 |
6 | let token = new Token(TokenType.PRIVATE, "Find @ https://builtbybit.com/account/api");
7 | let wrapper = new Wrapper();
8 |
9 | // We're only listening for a specific resource in this example, but this could be expanded to cover multiple.
10 | let resourceId = 0;
11 |
12 | // We're only keeping a store of the last purchase ID in memory for this example, but it's likely you'd want to
13 | // read/write this to a secondary data store (ie. a file or database).
14 | let lastPurchaseId = 0;
15 |
16 | let pmTitle = "Your recent purchase!";
17 | let pmMessage = `Hi there,
18 |
19 | Thank you for your recent purchase of my resource.
20 |
21 | If you need any assistance, don't hesitate to contact me.
22 |
23 | Thanks,
24 | - Author`;
25 |
26 | async function main() {
27 | await wrapper.init(token);
28 |
29 | // Poll once every hour.
30 | task();
31 | setInterval(task, 60 * 60 * 1000);
32 | }
33 |
34 | async function task() {
35 | let purchases = await wrapper.resources().purchases().listUntil(resourceId, (purchase) => {
36 | return purchase["purchase_id"] > lastPurchaseId;
37 | });
38 |
39 | if (purchases.length > 0) {
40 | lastPurchaseId = purchases[0]["purchase_id"];
41 |
42 | for (const index in purchases) {
43 | await onPurchase(purchases[index]);
44 | }
45 | }
46 | }
47 |
48 | async function onPurchase(purchase) {
49 | await wrapper.conversations().create(pmTitle, pmMessage, purchase["purchaser_id"]);
50 | console.log(`A PM has been sent to user ${purchase["purchaser_id"]}.`);
51 | }
52 |
53 | main().catch(error => console.error("ERROR: " + error));
54 |
--------------------------------------------------------------------------------
/examples/version-check.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { Wrapper, Token, TokenType } = require("@builtbybit/api-wrapper");
5 |
6 | let token = new Token(TokenType.SHARED, "Find @ https://builtbybit.com/account/api");
7 | let wrapper = new Wrapper();
8 |
9 | // Injected placeholders.
10 | let resourceId = "%%__RESOURCE__%%";
11 | let versionId = "%%__VERSION__%%";
12 |
13 | async function main() {
14 | await wrapper.init(token);
15 |
16 | let latest = await wrapper.resources().versions().latest(resourceId);
17 |
18 | if (Number(versionId) === latest["version_id"]) {
19 | console.log("Up to date.");
20 | } else {
21 | console.log(`A new version exists. https://builtbybit.com/resources/${resourceId}/`);
22 | }
23 | }
24 |
25 | main().catch(error => console.error("ERROR: " + error));
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@builtbybit/api-wrapper",
3 | "version": "1.1.10",
4 | "description": "An official asynchronous Node.js wrapper for BuiltByBit's Ultimate API.",
5 | "keywords": [
6 | "builtbybit",
7 | "api wrapper",
8 | "asynchronous"
9 | ],
10 | "main": "./src/index.js",
11 | "types": "./types/index.d.ts",
12 | "scripts": {
13 | "doc-live": "jsdoc -r ./src/ -d ./docs/live/",
14 | "doc-staged": "jsdoc -r ./src/ -d ./docs/staged/",
15 | "lint": "npx eslint --fix ./src/",
16 | "type": "npx tsc",
17 | "test": "node ./tests/test.js && npx eslint ./src/"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/BuiltByBit/js-api-wrapper.git"
22 | },
23 | "author": "BuiltByBit (Mick Capital Pty. Ltd.)",
24 | "license": "MIT",
25 | "bugs": {
26 | "url": "https://github.com/BuiltByBit/js-api-wrapper/issues"
27 | },
28 | "homepage": "https://builtbybit.com/wiki/ultimate-api/",
29 | "dependencies": {
30 | "axios": "^0.21.1"
31 | },
32 | "devDependencies": {
33 | "eslint": "^8.6.0",
34 | "jsdoc": "^4.0.2",
35 | "typescript": "^4.5.5"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/APIError.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | /** A type which represents a parsed error from the API, or an internal wrapper error. */
5 | class APIError extends Error {
6 | #code;
7 | #message;
8 |
9 | constructor(json) {
10 | super(`${json.code} - ${json.message}`);
11 |
12 | this.#code = json.code;
13 | this.#message = json.message;
14 | }
15 |
16 | /** Returns the machine-readable code of the error.
17 | *
18 | * @type {string} The machine-readable error code.
19 | */
20 | get code() {
21 | return this.#code;
22 | }
23 |
24 | /** Returns the human-readable message of the error.
25 | *
26 | * @type {string} The human-readable error message.
27 | */
28 | get message() {
29 | return this.#message;
30 | }
31 |
32 | /** Constructs a new Error which originated within the wrapper.
33 | *
34 | * @param {string} message The internal error message.
35 | * @returns {APIError} The newly-constructed error.
36 | */
37 | static internal(message) {
38 | return new APIError({code: "InternalWrapperError", message});
39 | }
40 | }
41 |
42 | exports.APIError = APIError;
--------------------------------------------------------------------------------
/src/SortOptions.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | /** A type representing the sorting options available for listing-style endpoints. */
5 | class SortOptions {
6 | sort;
7 | order;
8 | page;
9 |
10 | /** Convets this SortOptions instance into a query string.
11 | *
12 | * @returns {string} The query-string representation.
13 | */
14 | toQueryString() {
15 | let asArray = [];
16 |
17 | if (this.sort) {
18 | asArray.push(`sort=${this.sort}`);
19 | }
20 | if (this.order) {
21 | asArray.push(`order=${this.order}`);
22 | }
23 | if (this.page) {
24 | asArray.push(`page=${this.page}`);
25 | }
26 |
27 | return "?" + asArray.join("&");
28 | }
29 |
30 | /** Returns whether or not any sort options have been set.
31 | *
32 | * @returns {boolean} Whether or not any sort options have been set.
33 | */
34 | isSet() {
35 | return this.sort || this.order || this.page;
36 | }
37 | }
38 |
39 | exports.SortOptions = SortOptions;
--------------------------------------------------------------------------------
/src/Throttler.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | class Throttler {
5 | #readLastRetry;
6 | #readLastRequest;
7 |
8 | #writeLastRetry;
9 | #writeLastRequest;
10 |
11 | constructor() {
12 | this.#readLastRetry = 0;
13 | this.#readLastRequest = Date.now();
14 |
15 | this.#writeLastRetry = 0;
16 | this.#writeLastRequest = Date.now();
17 | }
18 |
19 | setRead(retry) {
20 | this.#readLastRetry = retry;
21 | this.#readLastRequest = Date.now();
22 | }
23 |
24 | setWrite(retry) {
25 | this.#writeLastRetry = retry;
26 | this.#writeLastRequest = Date.now();
27 | }
28 |
29 | resetRead() {
30 | this.#readLastRetry = 0;
31 | this.#readLastRequest = Date.now();
32 | }
33 |
34 | resetWrite() {
35 | this.#writeLastRetry = 0;
36 | this.#writeLastRequest = Date.now();
37 | }
38 |
39 | async stallIfRequired(write) {
40 | let stall = true;
41 |
42 | while (stall) {
43 | let time = Date.now();
44 |
45 | // As rate limits for WRITE operations are applied independently of those applied to READ operations, we
46 | // first determine if we're in a WRITE operation, and if we are, attempt to stall if required.
47 | // `stall_for_helper` will return true if a stall was required (and it completed the stall), or false if
48 | // no stall was required.
49 | if (write && (await this.#stallForHelper(this.#writeLastRetry, this.#writeLastRequest, time))) {
50 | continue;
51 | } else if (write) {
52 | stall = false;
53 | continue;
54 | }
55 |
56 | // If we haven't started a new iteration of this loop yet, we must be in a READ operation.
57 | if (await this.#stallForHelper(this.#readLastRetry, this.#readLastRequest, time)) {
58 | continue;
59 | } else {
60 | stall = false;
61 | }
62 | }
63 | }
64 |
65 | // A helper function for `stall_if_required` which computes over a generic set of rate limiting parameters.
66 | async #stallForHelper(lastRetry, lastRequest, time) {
67 | // If we've previously hit a rate limit, no other request has been completed with a non-429 response since, and
68 | // we're still within the Retry-After delay period, we should stall this request. The exact amount of time we
69 | // stall for derives from the amount of time that has passed since the last request, minus the Retry-After
70 | // value.
71 | if (lastRetry > 0 && time - lastRequest < lastRetry) {
72 | let stallFor = lastRetry - (time - lastRequest);
73 | await new Promise((resolve) => setTimeout(resolve, stallFor));
74 |
75 | return true;
76 | } else {
77 | return false;
78 | }
79 | }
80 | }
81 |
82 | exports.Throttler = Throttler;
--------------------------------------------------------------------------------
/src/Token.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { TokenType } = require("./TokenType");
5 |
6 | /** A type representing an API authentication token. */
7 | class Token {
8 | #type;
9 | #value;
10 |
11 | /** Constructs a new token from its constituents.
12 | *
13 | * @param {TokenType} type The type of this token.
14 | * @param {string} value The value of this token.
15 | */
16 | constructor(type, value) {
17 | this.#type = type;
18 | this.#value = value;
19 | }
20 |
21 | /** Constructs an object containing the header representation of this token.
22 | *
23 | * @returns An object with a single attribute, 'Authorization'.
24 | */
25 | asHeader() {
26 | return {Authorization: `${this.#type.headerName()} ${this.#value}`};
27 | }
28 | }
29 |
30 | exports.Token = Token;
--------------------------------------------------------------------------------
/src/TokenType.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | /** A type representing the different token types. */
5 | class TokenType {
6 | static PRIVATE = new TokenType("Private");
7 | static SHARED = new TokenType("Shared");
8 |
9 | #headerName;
10 |
11 | constructor(headerName) {
12 | this.#headerName = headerName;
13 | }
14 |
15 | headerName() {
16 | return this.#headerName;
17 | }
18 | }
19 |
20 | exports.TokenType = TokenType;
--------------------------------------------------------------------------------
/src/Wrapper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const axios = require("axios");
5 |
6 | const { Token } = require("./Token");
7 | const { Http } = require("./Http.js");
8 | const { APIError } = require("./APIError.js");
9 | const { Throttler } = require("./Throttler.js");
10 |
11 | const { AlertsHelper } = require("./helpers/AlertsHelper.js");
12 | const { ConversationsHelper } = require("./helpers/ConversationsHelper.js");
13 | const { ThreadsHelper } = require("./helpers/ThreadsHelper.js");
14 | const { MembersHelper } = require("./helpers/members/MembersHelper.js");
15 | const { ResourcesHelper } = require("./helpers/resources/ResourcesHelper.js");
16 |
17 | /** The primary wrapping type for interactions with BuiltByBit's API. */
18 | class Wrapper {
19 | /** The base API URL and version which will be prepended to non-absolute paths by axios. */
20 | static #BASE_URL = "https://api.builtbybit.com/v1";
21 |
22 | #http;
23 |
24 | /** Initialise this wrapper with a provided API token.
25 | *
26 | *
27 | *
28 | * By default, initialisation of this wrapper will execute a health check which we expect to always succeed under
29 | * nominal conditions. If the request does fail, we expect subsequent requests to other endpoints to also fail. In
30 | * this situation, we conclude that an initialisation failure has occured. We reject the returned Promise and pass
31 | * back the error to the caller.
32 | *
33 | * @param {Token} token The constructed API token.
34 | * @param {boolean} health Whether or not to execute a health check during initialisation.
35 | */
36 | async init(token, health = true) {
37 | let client = axios.create({baseURL: Wrapper.#BASE_URL, headers: token.asHeader()});
38 | this.#http = new Http(client, new Throttler());
39 |
40 | if (health) await this.health();
41 | }
42 |
43 | /** Schedule an empty request which we expect to always succeed under nominal conditions. */
44 | async health() {
45 | if (await this.#http.get("/health") !== "ok") {
46 | throw APIError.internal("The health response contained unexpected data.");
47 | }
48 | }
49 |
50 | /** Schedule an empty request and measure how long the API took to respond.
51 | *
52 | *
53 | *
54 | * This duration may not be representative of the raw request latency due to the fact that requests may be stalled
55 | * locally within this wrapper to ensure compliance with rate limiting rules. Whilst this is a trade-off, it can
56 | * be argued that the returned duration will be more representative of the true latencies experienced.
57 | *
58 | * @return {number} The response time in milliseconds.
59 | */
60 | async ping() {
61 | let start = Date.now();
62 | await this.health();
63 | return Date.now() - start;
64 | }
65 |
66 | /** Access alert-related helper functions.
67 | *
68 | * @return {AlertsHelper} A newly-constructed alert helper instance.
69 | */
70 | alerts() {
71 | return new AlertsHelper(this);
72 | }
73 |
74 | /** Access conversation-related helper functions.
75 | *
76 | * @return {ConversationsHelper} A newly-constructed conversation helper instance.
77 | */
78 | conversations() {
79 | return new ConversationsHelper(this);
80 | }
81 |
82 | /** Access thread-related helper functions.
83 | *
84 | * @return {ThreadsHelper} A newly-constructed thread helper instance.
85 | */
86 | threads() {
87 | return new ThreadsHelper(this);
88 | }
89 |
90 | /** Access member-related helper functions.
91 | *
92 | * @return {MembersHelper} A newly-constructed member helper instance.
93 | */
94 | members() {
95 | return new MembersHelper(this);
96 | }
97 |
98 | /** Access resource-related helper functions.
99 | *
100 | * @return {ResourcesHelper} A newly-constructed resource helper instance.
101 | */
102 | resources() {
103 | return new ResourcesHelper(this);
104 | }
105 |
106 | /** Access the inner Http instance which can be used to make raw requests.
107 | *
108 | * @returns {Http} The current Http instance in use by this wrapper.
109 | */
110 | http() {
111 | return this.#http;
112 | }
113 | }
114 |
115 | exports.Wrapper = Wrapper;
--------------------------------------------------------------------------------
/src/helpers/AlertsHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../SortOptions");
5 |
6 | /**
7 | * @typedef {object} Alert
8 | * @property {number} caused_member_id
9 | * @property {string} content_type
10 | * @property {number} content_id
11 | * @property {string} alert_type
12 | * @property {number} alert_date
13 | */
14 |
15 | /** A helper type for alert-related API endpoints. */
16 | class AlertsHelper {
17 | #wrapper;
18 |
19 | constructor(wrapper) {
20 | this.#wrapper = wrapper;
21 | }
22 |
23 | /** List a single page of unread alerts.
24 | *
25 | * @param {SortOptions | undefined} sort An optional set of sort options.
26 | * @return {Array} An array of raw data objects.
27 | */
28 | async list(sort) {
29 | return await this.#wrapper.http().get("/alerts", sort);
30 | }
31 |
32 | /** List all pages of unread alerts.
33 | *
34 | * @param {SortOptions | undefined} sort An optional set of sort options.
35 | * @return {Array} An array of raw data objects.
36 | */
37 | async listAll(sort) {
38 | return await this.#wrapper.http().listUntil("/alerts", () => true, sort);
39 | }
40 |
41 | /** List multiple pages of unread alerts until a condition is no longer met.
42 | *
43 | * @param {function(Alert):boolean} shouldContinue A function which determines if further pages are requested.
44 | * @param {SortOptions | undefined} sort An optional set of sort options.
45 | *
46 | * @return {Array} An array of raw data objects.
47 | */
48 | async listUntil(shouldContinue, sort) {
49 | return await this.#wrapper.http().listUntil("/alerts", shouldContinue, sort);
50 | }
51 |
52 | /** Mark unread alerts as read. */
53 | async markAsRead() {
54 | return await this.#wrapper.http().patch("/alerts", { read: true });
55 | }
56 | }
57 |
58 | exports.AlertsHelper = AlertsHelper;
--------------------------------------------------------------------------------
/src/helpers/ConversationsHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../SortOptions");
5 |
6 | /**
7 | * @typedef {object} Conversation
8 | * @property {number} conversation_id
9 | * @property {string} title
10 | * @property {number} creation_date
11 | * @property {number} creator_id
12 | * @property {number} last_message_date
13 | * @property {number} last_read_date
14 | * @property {boolean} open
15 | * @property {number} reply_count
16 | * @property {Array} recipient_ids
17 | */
18 |
19 | /**
20 | * @typedef {object} Reply
21 | * @property {number} message_id
22 | * @property {number} message_date
23 | * @property {number} author_id
24 | * @property {string} message
25 | */
26 |
27 | /** A helper type for conversation-related API endpoints. */
28 | class ConversationsHelper {
29 | #wrapper;
30 |
31 | constructor(wrapper) {
32 | this.#wrapper = wrapper;
33 | }
34 |
35 | /** List a page of unread conversations.
36 | *
37 | * @param {SortOptions | undefined} sort An optional set of sort options.
38 | * @return {Array} An array of raw data objects.
39 | */
40 | async list(sort) {
41 | return await this.#wrapper.http().get("/conversations", sort);
42 | }
43 |
44 | /** List all pages of unread conversations.
45 | *
46 | * @param {SortOptions | undefined} sort An optional set of sort options.
47 | * @return {Array} An array of raw data objects.
48 | */
49 | async listAll(sort) {
50 | return await this.#wrapper.http().listUntil("/conversations", () => true, sort);
51 | }
52 |
53 | /** List multiple pages of unread conversations until a condition is no longer met.
54 | *
55 | * @param {function(Conversation):boolean} shouldContinue A function which determines if further pages are
56 | * requested.
57 | * @param {SortOptions | undefined} sort An optional set of sort options.
58 | *
59 | * @return {Array} An array of raw data objects.
60 | */
61 | async listUntil(shouldContinue, sort) {
62 | return await this.#wrapper.http().listUntil("/conversations", shouldContinue, sort);
63 | }
64 |
65 | /** Start a new conversation.
66 | *
67 | * @param {string} title The title of the conversation.
68 | * @param {string} message The content of the first message in the conversation.
69 | * @param {Array} recipientIds An array of recipient identifiers.
70 | *
71 | * @return {number} The newly-created conversation identifier.
72 | */
73 | async start(title, message, recipientIds) {
74 | let body = {title, message, "recipient_ids": recipientIds};
75 | return await this.#wrapper.http().post("/conversations", body);
76 | }
77 |
78 | /** List a page of replies to an unread conversation.
79 | *
80 | * @param {number} conversationId The identifier of the unread conversation.
81 | * @param {SortOptions | undefined} sort An optional set of sort options.
82 | *
83 | * @return {Array} An array of raw data objects.
84 | */
85 | async listReplies(conversationId, sort) {
86 | return await this.#wrapper.http().get(`/conversations/${conversationId}/replies`, sort);
87 | }
88 |
89 | /** List all pages of replies to an unread conversation.
90 | *
91 | * @param {number} conversationId The identifier of the unread conversation.
92 | * @param {SortOptions | undefined} sort An optional set of sort options.
93 | *
94 | * @return {Array} An array of raw data objects.
95 | */
96 | async listRepliesAll(conversationId, sort) {
97 | return await this.#wrapper.http().listUntil(`/conversations/${conversationId}/replies`, () => true, sort);
98 | }
99 |
100 | /** List multiple pages of replies to an unread conversation until a condition is no longer met.
101 | *
102 | * @param {number} conversationId The identifier of the unread conversation.
103 | * @param {function(Reply):boolean} shouldContinue A function which determines if further pages are requested.
104 | * @param {SortOptions | undefined} sort An optional set of sort options.
105 | *
106 | * @return {Array} An array of raw data objects.
107 | */
108 | async listRepliesUntil(conversationId, shouldContinue, sort) {
109 | return await this.#wrapper.http().listUntil(`/conversations/${conversationId}/replies`, shouldContinue, sort);
110 | }
111 |
112 | /** Reply to an unread conversation
113 | *
114 | * @param {number} conversationId The identifier of the unread conversation.
115 | * @param {string} message The content of the new reply.
116 | *
117 | * @return {number} The identifier of the newly-created conversation message.
118 | */
119 | async reply(conversationId, message) {
120 | return await this.#wrapper.http().post(`/conversations/${conversationId}/replies`, {message});
121 | }
122 | }
123 |
124 | exports.ConversationsHelper = ConversationsHelper;
125 |
--------------------------------------------------------------------------------
/src/helpers/ThreadsHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../SortOptions");
5 |
6 | /**
7 | * @typedef {object} BasicThread
8 | * @property {number} thread_id
9 | * @property {string} title
10 | * @property {number} reply_count
11 | * @property {number} view_count
12 | * @property {number} creation_date
13 | * @property {number} last_message_date
14 | */
15 |
16 | /**
17 | * @typedef {object} Thread
18 | * @property {number} thread_id
19 | * @property {string} forum_name
20 | * @property {string} title
21 | * @property {number} reply_count
22 | * @property {number} view_count
23 | * @property {number} post_date
24 | * @property {string} thread_type
25 | * @property {boolean} thread_open
26 | * @property {number} last_post_date
27 | */
28 |
29 | /**
30 | * @typedef {object} Reply
31 | * @property {number} reply_id
32 | * @property {number} author_id
33 | * @property {number} post_date
34 | * @property {string} message
35 | */
36 |
37 | /** A helper type for thread-related API endpoints. */
38 | class ThreadsHelper {
39 | #wrapper;
40 |
41 | constructor(wrapper) {
42 | this.#wrapper = wrapper;
43 | }
44 |
45 | /** List a page of threads you own or collaborate on.
46 | *
47 | * @param {SortOptions | undefined} sort An optional set of sort options.
48 | * @return {Array} An array of raw data objects.
49 | */
50 | async list(sort) {
51 | return await this.#wrapper.http().get("/threads", sort);
52 | }
53 |
54 | /** List all pages of threads you own or collaborate on.
55 | *
56 | * @param {SortOptions | undefined} sort An optional set of sort options.
57 | * @return {Array} An array of raw data objects.
58 | */
59 | async listAll(sort) {
60 | return await this.#wrapper.http().listUntil("/threads", () => true, sort);
61 | }
62 |
63 | /** List multiple pages of threads you own or collaborate on until a condition is no longer met.
64 | *
65 | * @param {function(BasicThread):boolean} shouldContinue A function which determines if further pages are requested.
66 | * @param {SortOptions | undefined} sort An optional set of sort options.
67 | *
68 | * @return {Array} An array of raw data objects.
69 | */
70 | async listUntil(shouldContinue, sort) {
71 | return await this.#wrapper.http().listUntil("/threads", shouldContinue, sort);
72 | }
73 |
74 | /** Fetch information about a thread you own or collaborate on.
75 | *
76 | * @param {number} threadId The identifier of the thread.
77 | * @return {Thread} A raw data object.
78 | */
79 | async fetch(threadId) {
80 | return await this.#wrapper.http().get(`/threads/${threadId}`);
81 | }
82 |
83 | /** List a page of replies for a thread you own or collaborate on.
84 | *
85 | * @param {number} threadId The identifier of the thread.
86 | * @param {SortOptions | undefined} sort An optional set of sort options.
87 | *
88 | * @return {Array} An array of raw data objects.
89 | */
90 | async listReplies(threadId, sort) {
91 | return await this.#wrapper.http().get(`/threads/${threadId}/replies`, sort);
92 | }
93 |
94 | /** List all pages of replies for a thread you own or collaborate on.
95 | *
96 | * @param {number} threadId The identifier of the thread.
97 | * @param {SortOptions | undefined} sort An optional set of sort options.
98 | *
99 | * @return {Array} An array of raw data objects.
100 | */
101 | async listRepliesAll(threadId, sort) {
102 | return await this.#wrapper.http().listUntil(`/threads/${threadId}/replies`, () => true, sort);
103 | }
104 |
105 | /** List multiple pages of replies for a thread you own or collaborate on until a condition is no longer met.
106 | *
107 | * @param {number} threadId The identifier of the thread.
108 | * @param {function(Reply):boolean} shouldContinue A function which determines if further pages are requested.
109 | * @param {SortOptions | undefined} sort An optional set of sort options.
110 | *
111 | * @return {Array} An array of raw data objects.
112 | */
113 | async listRepliesUntil(threadId, shouldContinue, sort) {
114 | return await this.#wrapper.http().listUntil(`/threads/${threadId}/replies`, shouldContinue, sort);
115 | }
116 |
117 | /** Reply to a thread you own or collaborate on.
118 | *
119 | * @param {number} threadId The identifier of the thread.
120 | * @param {string} message The content of the new reply.
121 | *
122 | * @return {number} The identifier of the newly-created post.
123 | */
124 | async reply(threadId, message) {
125 | return await this.#wrapper.http().post(`/threads/${threadId}/replies`, { message });
126 | }
127 | }
128 |
129 | exports.ThreadsHelper = ThreadsHelper;
--------------------------------------------------------------------------------
/src/helpers/members/MembersHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { ProfilePostsHelper } = require("./ProfilePostsHelper.js");
5 |
6 | /**
7 | * @typedef {object} Member
8 | * @property {number} member_id
9 | * @property {string} username
10 | * @property {number} join_date
11 | * @property {number} [last_activity_date]
12 | * @property {boolean} banned
13 | * @property {boolean} suspended
14 | * @property {boolean} restricted
15 | * @property {boolean} disabled
16 | * @property {boolean} premium
17 | * @property {boolean} supreme
18 | * @property {boolean} ultimate
19 | * @property {number} [discord_id]
20 | * @property {string} avatar_url
21 | * @property {number} post_count
22 | * @property {number} resource_count
23 | * @property {number} purchase_count
24 | * @property {number} feedback_positive
25 | * @property {number} feedback_neutral
26 | * @property {number} feedback_negative
27 | */
28 |
29 | /**
30 | * @typedef {object} Ban
31 | * @property {number} member_id
32 | * @property {number} banned_by_id
33 | * @property {number} ban_date
34 | * @property {string} reason
35 | */
36 |
37 | /** A helper type for member-related API endpoints. */
38 | class MembersHelper {
39 | #wrapper;
40 |
41 | constructor(wrapper) {
42 | this.#wrapper = wrapper;
43 | }
44 |
45 | /** Fetch information about yourself.
46 | *
47 | * @return {Member} A raw data object.
48 | */
49 | async self() {
50 | return await this.#wrapper.http().get("/members/self");
51 | }
52 |
53 | /** Modify information about yourself.
54 | *
55 | * @param {string} aboutMe The 'about me' field content, or undefined.
56 | * @param {string} customTitle The 'custom title' field content, or undefined.
57 | * @param {string} signature The 'signature' field content, or undefined.
58 | */
59 | async modifySelf(aboutMe, customTitle, signature) {
60 | let body = {"about_me": aboutMe, "custom_title": customTitle, signature};
61 | return await this.#wrapper.http().patch("/members/self", body);
62 | }
63 |
64 | /** Fetch information about a member.
65 | *
66 | * @param {number} memberId The identifier of the member.
67 | * @return {Member} A raw data object.
68 | */
69 | async fetch(memberId) {
70 | return await this.#wrapper.http().get(`/members/${memberId}`);
71 | }
72 |
73 | /** Fetch information about a member by username.
74 | *
75 | * @param {string} username The username of the member.
76 | * @return {Member} A raw data object.
77 | */
78 | async fetchByUsername(username) {
79 | return await this.#wrapper.http().get(`/members/usernames/${username}`);
80 | }
81 |
82 | /** Fetch information about a member by Discord identifier.
83 | *
84 | * @param {string} discordId The identifier of the Discord account.
85 | * @return {Member} A raw data object.
86 | */
87 | async fetchByDiscord(discordId) {
88 | return await this.#wrapper.http().get(`/members/discords/${discordId}`);
89 | }
90 |
91 | /** Fetch a list of recently issued bans.
92 | *
93 | * @return {Array} An array of raw data objects.
94 | */
95 | async bans() {
96 | return await this.#wrapper.http().get("/members/bans");
97 | }
98 |
99 | /** Access profile post-related helper functions.
100 | *
101 | * @return {ProfilePostsHelper} A newly-constructed profile post helper instance.
102 | */
103 | profilePosts() {
104 | return new ProfilePostsHelper(this.#wrapper);
105 | }
106 | }
107 |
108 | exports.MembersHelper = MembersHelper;
--------------------------------------------------------------------------------
/src/helpers/members/ProfilePostsHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../../SortOptions");
5 |
6 | /**
7 | * @typedef {object} ProfilePost
8 | * @property {number} profile_post_id
9 | * @property {number} author_id
10 | * @property {number} post_date
11 | * @property {string} message
12 | * @property {number} comment_count
13 | */
14 |
15 | /** A helper type for profile post-related API endpoints. */
16 | class ProfilePostsHelper {
17 | #wrapper;
18 |
19 | constructor(wrapper) {
20 | this.#wrapper = wrapper;
21 | }
22 |
23 | /** List a page of profile posts on your profile.
24 | *
25 | * @param {SortOptions | undefined} sort An optional set of sort options.
26 | * @return {Array} An array of raw data objects.
27 | */
28 | async list(sort) {
29 | return await this.#wrapper.http().get("/members/self/profile-posts", sort);
30 | }
31 |
32 | /** List all pages of profile posts on your profile.
33 | *
34 | * @param {SortOptions | undefined} sort An optional set of sort options.
35 | * @return {Array} An array of raw data objects.
36 | */
37 | async listAll(sort) {
38 | return await this.#wrapper.http().listUntil("/members/self/profile-posts", () => true, sort);
39 | }
40 |
41 | /** List multiple pages of profile posts on your profile until a condition is no longer met.
42 | *
43 | * @param {function(ProfilePost):boolean} shouldContinue A function which determines if further pages are requested.
44 | * @param {SortOptions | undefined} sort An optional set of sort options.
45 | * @return {Array} An array of raw data objects.
46 | */
47 | async listUntil(shouldContinue, sort) {
48 | return await this.#wrapper.http().listUntil("/members/self/profile-posts", shouldContinue, sort);
49 | }
50 |
51 | /** Fetch information about a profile post on your profile.
52 | *
53 | * @param {number} profilePostId The identifier of the profile post to fetch.
54 | * @return {ProfilePost} A raw data object.
55 | */
56 | async fetch(profilePostId) {
57 | return await this.#wrapper.http().get(`/members/self/profile-posts/${profilePostId}`);
58 | }
59 |
60 | /** Create a new profile post on your profile.
61 | *
62 | * @param {string} message The content of the message to modify to.
63 | * @return {number} The identifer of the newly-created profile post.
64 | */
65 | async create(message) {
66 | return await this.#wrapper.http().post("/members/self/profile-posts", { message });
67 | }
68 |
69 | /** Modify a profile post on your profile that you've authored.
70 | *
71 | * @param {number} profilePostId The identifier of the profile post to modify.
72 | * @param {string} message The content of the message to modify to.
73 | */
74 | async modify(profilePostId, message) {
75 | return await this.#wrapper.http().patch(`/members/self/profile-posts/${profilePostId}`, { message });
76 | }
77 |
78 | /** Delete a profile post on your profile that you've authored.
79 | *
80 | * @param {number} profilePostId The identifier of the profile post to delete.
81 | */
82 | async delete(profilePostId) {
83 | return await this.#wrapper.http().delete(`/members/self/profile-posts/${profilePostId}`);
84 | }
85 | }
86 |
87 | exports.ProfilePostsHelper = ProfilePostsHelper;
--------------------------------------------------------------------------------
/src/helpers/resources/LicensesHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../../SortOptions");
5 |
6 | /**
7 | * @typedef {object} License
8 | * @property {number} license_id
9 | * @property {number} purchaser_id
10 | * @property {boolean} validated
11 | * @property {boolean} permanent
12 | * @property {boolean} active
13 | * @property {number} start_date
14 | * @property {number} end_date
15 | * @property {number} previous_end_date
16 | */
17 |
18 | /** A helper type for resource license-related API endpoints. */
19 | class LicensesHelper {
20 | #wrapper;
21 |
22 | constructor(wrapper) {
23 | this.#wrapper = wrapper;
24 | }
25 |
26 | /** List a page of licenses for a given resource.
27 | *
28 | * @param {number} resourceId The identifier of the resource.
29 | * @param {SortOptions | undefined} sort An optional set of sort options.
30 | *
31 | * @return {Array} An array of raw data objects.
32 | */
33 | async list(resourceId, sort) {
34 | return await this.#wrapper.http().get(`/resources/${resourceId}/licenses`, sort);
35 | }
36 |
37 | /** List all pages of licenses for a given resource.
38 | *
39 | * @param {number} resourceId The identifier of the resource.
40 | * @param {SortOptions | undefined} sort An optional set of sort options.
41 | *
42 | * @return {Array} An array of raw data objects.
43 | */
44 | async listAll(resourceId, sort) {
45 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/licenses`, () => true, sort);
46 | }
47 |
48 | /** List multiple pages of licenses for a given resource until a condition is no longer met.
49 | *
50 | * @param {number} resourceId The identifier of the resource.
51 | * @param {function(License):boolean} shouldContinue A function which determines if further pages are requested.
52 | * @param {SortOptions | undefined} sort An optional set of sort options.
53 | *
54 | * @return {Array} An array of raw data objects.
55 | */
56 | async listUntil(resourceId, shouldContinue, sort) {
57 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/licenses`, shouldContinue, sort);
58 | }
59 |
60 | /** Fetch a license for a given resource.
61 | *
62 | * @param {number} resourceId The identifier of the resource.
63 | * @param {number} licenseId The identifier of the license.
64 | *
65 | * @return {License} A raw data object.
66 | */
67 | async fetch(resourceId, licenseId) {
68 | return await this.#wrapper.http().get(`/resources/${resourceId}/licenses/${licenseId}`);
69 | }
70 |
71 | /** Fetch a member's license for a given resource.
72 | *
73 | * @param {number} resourceId The identifier of the resource.
74 | * @param {number} memberId The identifier of the member.
75 | * @param {number | undefined} nonce The download's NONCE value, or undefined if using a Private token.
76 | * @param {number | undefined} timestamp The download's UNIX timestamp, or undefined if using a Private token.
77 | *
78 | * @return {License} A raw data object.
79 | */
80 | async fetchMember(resourceId, memberId, nonce, timestamp) {
81 | let endpoint = `/resources/${resourceId}/licenses/members/${memberId}`;
82 | if (nonce && timestamp) endpoint += `?nonce=${nonce}×tamp=${timestamp}`;
83 |
84 | return await this.#wrapper.http().get(endpoint);
85 | }
86 |
87 | /** Modify a permanent license (and convert to permanent if currently temporary).
88 | *
89 | * @param {number} resourceId The identifier of the resource.
90 | * @param {number} licenseId The identifier of the license.
91 | * @param {boolean} active Whether or not the license should be active.
92 | */
93 | async modifyPermanent(resourceId, licenseId, active) {
94 | let body = {permanent: true, active};
95 | return await this.#wrapper.http().patch(`/resources/${resourceId}/licenses/${licenseId}`, body);
96 | }
97 |
98 | /** Modify a temporary license (and convert to temporary if currently permanent).
99 | *
100 | * @param {number} resourceId The identifier of the resource.
101 | * @param {number} licenseId The identifier of the license.
102 | * @param {number} startDate The UNIX timestamp of when the license should start.
103 | * @param {number} endDate The UNIX timestamp of when the license should end.
104 | */
105 | async modifyTemporary(resourceId, licenseId, startDate, endDate) {
106 | let body = {permanent: false, "start_date": startDate, "end_date": endDate};
107 | return await this.#wrapper.http().patch(`/resources/${resourceId}/licenses/${licenseId}`, body);
108 | }
109 | }
110 |
111 | exports.LicensesHelper = LicensesHelper;
--------------------------------------------------------------------------------
/src/helpers/resources/PurchasesHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../../SortOptions");
5 |
6 | /**
7 | * @typedef {object} Purchase
8 | * @property {number} purchase_id
9 | * @property {number} purchaser_id
10 | * @property {number} license_id
11 | * @property {boolean} renewal
12 | * @property {string} status
13 | * @property {number} price
14 | * @property {string} currency
15 | * @property {number} purchase_date
16 | * @property {number} validation_date
17 | */
18 |
19 | /** A helper type for resource purchase-related API endpoints. */
20 | class PurchasesHelper {
21 | #wrapper;
22 |
23 | constructor(wrapper) {
24 | this.#wrapper = wrapper;
25 | }
26 |
27 | /** List a page of purchases for a given resource.
28 | *
29 | * @param {number} resourceId The identifier of the resource.
30 | * @param {SortOptions | undefined} sort An optional set of sort options.
31 | *
32 | * @return {Array} An array of raw data objects.
33 | */
34 | async list(resourceId, sort) {
35 | return await this.#wrapper.http().get(`/resources/${resourceId}/purchases`, sort);
36 | }
37 |
38 | /** List all pages of purchases for a given resource.
39 | *
40 | * @param {number} resourceId The identifier of the resource.
41 | * @param {SortOptions | undefined} sort An optional set of sort options.
42 | *
43 | * @return {Array} An array of raw data objects.
44 | */
45 | async listAll(resourceId, sort) {
46 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/purchases`, () => true, sort);
47 | }
48 |
49 | /** List multiple pages of purchases for a given resource until a condition is no longer met.
50 | *
51 | * @param {number} resourceId The identifier of the resource.
52 | * @param {function(Purchase):boolean} shouldContinue A function which determines if further pages are requested.
53 | * @param {SortOptions | undefined} sort An optional set of sort options.
54 | *
55 | * @return {Array} An array of raw data objects.
56 | */
57 | async listUntil(resourceId, shouldContinue, sort) {
58 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/purchases`, shouldContinue, sort);
59 | }
60 |
61 | /** Fetch a purchase for a given resource.
62 | *
63 | * @param {number} resourceId The identifier of the resource.
64 | * @param {number} purchaseId The identifier of the purchase.
65 | *
66 | * @return {Purchase} A raw data object.
67 | */
68 | async fetch(resourceId, purchaseId) {
69 | return await this.#wrapper.http().get(`/resources/${resourceId}/purchases/${purchaseId}`);
70 | }
71 | }
72 |
73 | exports.PurchasesHelper = PurchasesHelper;
--------------------------------------------------------------------------------
/src/helpers/resources/ReviewsHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../../SortOptions");
5 |
6 | /**
7 | * @typedef {object} Review
8 | * @property {number} review_id
9 | * @property {number} reviewer_id
10 | * @property {number} review_date
11 | * @property {number} rating
12 | * @property {string} message
13 | * @property {string} response
14 | */
15 |
16 | /** A helper type for resource review-related API endpoints. */
17 | class ReviewsHelper {
18 | #wrapper;
19 |
20 | constructor(wrapper) {
21 | this.#wrapper = wrapper;
22 | }
23 |
24 | /** List a page of reviews for a given resource.
25 | *
26 | * @param {number} resourceId The identifier of the resource.
27 | * @param {SortOptions | undefined} sort An optional set of sort options.
28 | *
29 | * @return {Array} An array of raw data objects.
30 | */
31 | async list(resourceId, sort) {
32 | return await this.#wrapper.http().get(`/resources/${resourceId}/reviews`, sort);
33 | }
34 |
35 | /** List all pages of reviews for a given resource.
36 | *
37 | * @param {number} resourceId The identifier of the resource.
38 | * @param {SortOptions | undefined} sort An optional set of sort options.
39 | *
40 | * @return {Array} An array of raw data objects.
41 | */
42 | async listAll(resourceId, sort) {
43 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/reviews`, () => true, sort);
44 | }
45 |
46 | /** List multiple pages of reviews for a given resource until a condition is no longer met.
47 | *
48 | * @param {number} resourceId The identifier of the resource.
49 | * @param {function(Review):boolean} shouldContinue A function which determines if further pages are requested.
50 | * @param {SortOptions | undefined} sort An optional set of sort options.
51 | *
52 | * @return {Array} An array of raw data objects.
53 | */
54 | async listUntil(resourceId, shouldContinue, sort) {
55 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/reviews`, shouldContinue, sort);
56 | }
57 |
58 | /** Fetch a resource review by a member for a given resource.
59 | *
60 | * @param {number} resourceId The identifier of the resource.
61 | * @param {number} memberId The identifier of the member.
62 | *
63 | * @return {Review} A raw data object.
64 | */
65 | async fetch(resourceId, memberId) {
66 | return await this.#wrapper.http().get(`/resources/${resourceId}/reviews/members/${memberId}`);
67 | }
68 |
69 | /** Respond to a review for a given resource.
70 | *
71 | * @param {number} resourceId The identifier of the resource.
72 | * @param {number} reviewId The identifier of the review.
73 | * @param {string} response The content of the author response.
74 | */
75 | async respond(resourceId, reviewId, response) {
76 | return await this.#wrapper.http().patch(`/resources/${resourceId}/reviews/${reviewId}`, {response});
77 | }
78 | }
79 |
80 | exports.ReviewsHelper = ReviewsHelper;
--------------------------------------------------------------------------------
/src/helpers/resources/UpdatesHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../../SortOptions");
5 |
6 | /**
7 | * @typedef {object} Update
8 | * @property {number} update_id
9 | * @property {string} title
10 | * @property {string} message
11 | * @property {number} update_date
12 | */
13 |
14 | /** A helper type for resource update-related API endpoints. */
15 | class UpdatesHelper {
16 | #wrapper;
17 |
18 | constructor(wrapper) {
19 | this.#wrapper = wrapper;
20 | }
21 |
22 | /** List a page of updates for a given resource.
23 | *
24 | * @param {number} resourceId The identifier of the resource.
25 | * @param {SortOptions | undefined} sort An optional set of sort options.
26 | *
27 | * @return {Array} An array of raw data objects.
28 | */
29 | async list(resourceId, sort) {
30 | return await this.#wrapper.http().get(`/resources/${resourceId}/updates`, sort);
31 | }
32 |
33 | /** List all pages of updates for a given resource.
34 | *
35 | * @param {number} resourceId The identifier of the resource.
36 | * @param {SortOptions | undefined} sort An optional set of sort options.
37 | *
38 | * @return {Array} An array of raw data objects.
39 | */
40 | async listAll(resourceId, sort) {
41 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/updates`, () => true, sort);
42 | }
43 |
44 | /** List multiple pages of updates for a given resource until a condition is no longer met.
45 | *
46 | * @param {number} resourceId The identifier of the resource.
47 | * @param {function(Update):boolean} shouldContinue A function which determines if further pages are requested.
48 | * @param {SortOptions | undefined} sort An optional set of sort options.
49 | *
50 | * @return {Array} An array of raw data objects.
51 | */
52 | async listUntil(resourceId, shouldContinue, sort) {
53 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/updates`, shouldContinue, sort);
54 | }
55 |
56 | /** Fetch the latest update for a given resource.
57 | *
58 | * @param {number} resourceId The identifier of the resource.
59 | *
60 | * @return {Update} A raw data object.
61 | */
62 | async latest(resourceId) {
63 | return await this.#wrapper.http().get(`/resources/${resourceId}/updates/latest`);
64 | }
65 |
66 | /** Fetch an update for a given resource.
67 | *
68 | * @param {number} resourceId The identifier of the resource.
69 | * @param {number} updateId The identifier of the update.
70 | *
71 | * @return {Update} A raw data object.
72 | */
73 | async fetch(resourceId, updateId) {
74 | return await this.#wrapper.http().get(`/resources/${resourceId}/updates/${updateId}`);
75 | }
76 |
77 | /** Delete an update for a given resource.
78 | *
79 | * @param {number} resourceId The identifier of the resource.
80 | * @param {number} updateId The identifier of the update.
81 | */
82 | async delete(resourceId, updateId) {
83 | return await this.#wrapper.http().delete(`/resources/${resourceId}/updates/${updateId}`);
84 | }
85 | }
86 |
87 | exports.UpdatesHelper = UpdatesHelper;
--------------------------------------------------------------------------------
/src/helpers/resources/VersionsHelper.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const { SortOptions } = require("../../SortOptions");
5 |
6 | /**
7 | * @typedef {object} Version
8 | * @property {number} version_id
9 | * @property {number} update_id
10 | * @property {string} name
11 | * @property {number} release_date
12 | * @property {number} download_count
13 | */
14 |
15 | /** A helper type for resource version-related API endpoints. */
16 | class VersionsHelper {
17 | #wrapper;
18 |
19 | constructor(wrapper) {
20 | this.#wrapper = wrapper;
21 | }
22 |
23 | /** List a page of versions for a given resource.
24 | *
25 | * @param {number} resourceId The identifier of the resource.
26 | * @param {SortOptions | undefined} sort An optional set of sort options.
27 | *
28 | * @return {Array} An array of raw data objects.
29 | */
30 | async list(resourceId, sort) {
31 | return await this.#wrapper.http().get(`/resources/${resourceId}/versions`, sort);
32 | }
33 |
34 | /** List all pages of versions for a given resource.
35 | *
36 | * @param {number} resourceId The identifier of the resource.
37 | * @param {SortOptions | undefined} sort An optional set of sort options.
38 | *
39 | * @return {Array} An array of raw data objects.
40 | */
41 | async listAll(resourceId, sort) {
42 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/versions`, () => true, sort);
43 | }
44 |
45 | /** List multiple pages of versions for a given resource until a condition is no longer met.
46 | *
47 | * @param {number} resourceId The identifier of the resource.
48 | * @param {function(Version):boolean} shouldContinue A function which determines if further pages are requested.
49 | * @param {SortOptions | undefined} sort An optional set of sort options.
50 | *
51 | * @return {Array} An array of raw data objects.
52 | */
53 | async listUntil(resourceId, shouldContinue, sort) {
54 | return await this.#wrapper.http().listUntil(`/resources/${resourceId}/versions`, shouldContinue, sort);
55 | }
56 |
57 | /** Fetch the latest version for a given resource.
58 | *
59 | * @param {number} resourceId The identifier of the resource.
60 | *
61 | * @return {Version} A raw data object.
62 | */
63 | async latest(resourceId) {
64 | return await this.#wrapper.http().get(`/resources/${resourceId}/versions/latest`);
65 | }
66 |
67 | /** Fetch a version for a given resource.
68 | *
69 | * @param {number} resourceId The identifier of the resource.
70 | * @param {number} versionId The identifier of the version.
71 | *
72 | * @return {Version} A raw data object.
73 | */
74 | async fetch(resourceId, versionId) {
75 | return await this.#wrapper.http().get(`/resources/${resourceId}/versions/${versionId}`);
76 | }
77 |
78 | /** Delete a version for a given resource.
79 | *
80 | * @param {number} resourceId The identifier of the resource.
81 | * @param {number} versionId The identifier of the version.
82 | */
83 | async delete(resourceId, versionId) {
84 | return await this.#wrapper.http().delete(`/resources/${resourceId}/versions/${versionId}`);
85 | }
86 | }
87 |
88 | exports.VersionsHelper = VersionsHelper;
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | exports.Token = require("./Token.js").Token;
5 | exports.TokenType = require("./TokenType.js").TokenType;
6 | exports.SortOptions = require("./SortOptions.js").SortOptions;
7 | exports.Http = require("./Http.js").Http;
8 | exports.APIError = require("./APIError.js").APIError;
9 | exports.Wrapper = require("./Wrapper.js").Wrapper;
10 |
11 | exports.AlertsHelper = require("./helpers/AlertsHelper.js").AlertsHelper;
12 | exports.ConversationsHelper = require("./helpers/ConversationsHelper.js").ConversationsHelper;
13 | exports.ThreadsHelper = require("./helpers/ThreadsHelper.js").ThreadsHelper;
14 |
15 | exports.MembersHelper = require("./helpers/members/MembersHelper.js").MembersHelper;
16 | exports.ProfilePostsHelper = require("./helpers/members/ProfilePostsHelper.js").ProfilePostsHelper;
17 |
18 | exports.ResourcesHelper = require("./helpers/resources/ResourcesHelper.js").ResourcesHelper;
19 | exports.DownloadsHelper = require("./helpers/resources/DownloadsHelper.js").DownloadsHelper;
20 | exports.LicensesHelper = require("./helpers/resources/LicensesHelper.js").LicensesHelper;
21 | exports.PurchasesHelper = require("./helpers/resources/PurchasesHelper.js").PurchasesHelper;
22 | exports.ReviewsHelper = require("./helpers/resources/ReviewsHelper.js").ReviewsHelper;
23 | exports.UpdatesHelper = require("./helpers/resources/UpdatesHelper.js").UpdatesHelper;
24 | exports.VersionsHelper = require("./helpers/resources/VersionsHelper.js").VersionsHelper;
--------------------------------------------------------------------------------
/tests/base.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 |
--------------------------------------------------------------------------------
/tests/sort_options.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | const assert = require("assert");
5 | const { SortOptions } = require("../src/SortOptions.js");
6 |
7 | function single_sort() {
8 | let options = new SortOptions();
9 | options.sort = "purchases";
10 | assert.strictEqual(options.toQueryString(), "?sort=purchases");
11 | }
12 |
13 | function single_order() {
14 | let options = new SortOptions();
15 | options.order = "asc";
16 | assert.strictEqual(options.toQueryString(), "?order=asc");
17 | }
18 |
19 | function single_page() {
20 | let options = new SortOptions();
21 | options.page = 5;
22 | assert.strictEqual(options.toQueryString(), "?page=5");
23 | }
24 |
25 | single_sort();
26 | single_order();
27 | single_page();
--------------------------------------------------------------------------------
/tests/test.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-2022 BuiltByBit (Mick Capital Pty. Ltd.)
2 | // MIT License (https://github.com/BuiltByBit/js-api-wrapper/blob/main/LICENSE)
3 |
4 | require("./base.js");
5 | require("./sort_options.js");
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src/**/*"],
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "declaration": true,
6 | "emitDeclarationOnly": true,
7 | "outDir": "types",
8 | "declarationMap": true
9 | }
10 | }
--------------------------------------------------------------------------------
/types/APIError.d.ts:
--------------------------------------------------------------------------------
1 | /** A type which represents a parsed error from the API, or an internal wrapper error. */
2 | export class APIError extends Error {
3 | /** Constructs a new Error which originated within the wrapper.
4 | *
5 | * @param {string} message The internal error message.
6 | * @returns {APIError} The newly-constructed error.
7 | */
8 | static internal(message: string): APIError;
9 | constructor(json: any);
10 | /** Returns the machine-readable code of the error.
11 | *
12 | * @type {string} The machine-readable error code.
13 | */
14 | get code(): string;
15 | /** Returns the human-readable message of the error.
16 | *
17 | * @type {string} The human-readable error message.
18 | */
19 | get message(): string;
20 | #private;
21 | }
22 | //# sourceMappingURL=APIError.d.ts.map
--------------------------------------------------------------------------------
/types/APIError.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"APIError.d.ts","sourceRoot":"","sources":["../src/APIError.js"],"names":[],"mappings":"AAGA,yFAAyF;AACzF;IA2BI;;;;OAIG;IACH,yBAHW,MAAM,GACJ,QAAQ,CAIpB;IA9BD,uBAKC;IAED;;;OAGG;IACH,mBAEC;IAED;;;OAGG;IACH,sBAEC;;CAUJ"}
--------------------------------------------------------------------------------
/types/Error.d.ts:
--------------------------------------------------------------------------------
1 | /** A type which represents a parsed error from the API, or an internal wrapper error. */
2 | export class Error {
3 | /** Constructs a new Error which originated within the wrapper.
4 | *
5 | * @param {string} message The internal error message.
6 | * @returns {Error} The newly-constructed error.
7 | */
8 | static internal(message: string): Error;
9 | constructor(json: any);
10 | /** Returns a string representation of this error including both the machine and human-readable parts.
11 | *
12 | * @returns {string} A string representation of this error.
13 | */
14 | toString(): string;
15 | /** Returns the machine-readable code of the error.
16 | *
17 | * @returns {string} The machine-readable error code.
18 | */
19 | code(): string;
20 | /** Returns the human-readable message of the error.
21 | *
22 | * @returns {string} The human-readable error message.
23 | */
24 | message(): string;
25 | #private;
26 | }
27 | //# sourceMappingURL=Error.d.ts.map
--------------------------------------------------------------------------------
/types/Error.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"Error.d.ts","sourceRoot":"","sources":["../src/Error.js"],"names":[],"mappings":"AAGA,yFAAyF;AACzF;IAiCI;;;;OAIG;IACH,yBAHW,MAAM,GACJ,KAAK,CAIjB;IApCD,uBAGC;IAED;;;OAGG;IACH,YAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,QAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,WAFa,MAAM,CAIlB;;CAUJ"}
--------------------------------------------------------------------------------
/types/Http.d.ts:
--------------------------------------------------------------------------------
1 | /** A type that handles raw HTTP requests to the API. */
2 | export class Http {
3 | /** The maximum number of objects returned by a list endpoint for a single request. */
4 | static "__#2@#PER_PAGE": number;
5 | /** The content type used for WRITE operations with bodies (ie. POST/PATCH). */
6 | static "__#2@#WRITE_HEADERS": {
7 | headers: {
8 | "Content-Type": string;
9 | };
10 | };
11 | constructor(client: any, throtter: any);
12 | /** Schedules a GET request for a specific endpoint.
13 | *
14 | * @param {string} endpoint The path of the endpoint (incl. any path parameters).
15 | * @param {SortOptions | undefined} sort The optional set of sort options.
16 | *
17 | * @return {*} The response data on success.
18 | */
19 | get(endpoint: string, sort?: SortOptions | undefined): any;
20 | /** Schedules a POST request for a specific endpoint.
21 | *
22 | * @param {string} endpoint The path of the endpoint (incl. any path parameters).
23 | * @param {object} body The request body options.
24 | *
25 | * @return {number} The response data on success (ie. a content identifier).
26 | */
27 | post(endpoint: string, body: object): number;
28 | /** Schedules a PATCH request for a specific endpoint.
29 | *
30 | * @param {string} endpoint The path of the endpoint (incl. any path parameters).
31 | * @param {object} body The request body options.
32 | */
33 | patch(endpoint: string, body: object): any;
34 | /** Schedules a DELETE request for a specific endpoint.
35 | *
36 | * @param {string} endpoint The path of the endpoint (incl. any path parameters).
37 | */
38 | delete(endpoint: string): any;
39 | /** A raw function returning a compiled list of objects from all available pages or until we decide to stop.
40 | *
41 | *
42 | *
43 | * 'shouldContinue' expects a function with a single parameter and should return a boolean representing if we
44 | * should continue to add the current (and future) objects to the final list (and thus, if we should continue
45 | * to make requests). This function is called for every single object as a parameter within each request's
46 | * returned list.
47 | *
48 | *
49 | *
50 | * This function continuously makes requests to a specific endpoint with a set of sort options, and increments the
51 | * sort option page count after each request.
52 | *
53 | * @param {string} endpoint The path of the endpoint (incl. any path parameters).
54 | * @param {function(object):boolean} shouldContinue A function which determines if further pages are requested.
55 | * @param {SortOptions | undefined} sort An optional set of sort options.
56 | *
57 | * @return {Array