@nerimity/nerimity.js 1.18.0 → 1.20.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/build/AsyncFunctionQueue.d.ts +43 -0
- package/build/AsyncFunctionQueue.d.ts.map +1 -0
- package/build/AsyncFunctionQueue.js +105 -0
- package/build/AsyncFunctionQueue.js.map +1 -0
- package/build/classes/Channel.d.ts +2 -0
- package/build/classes/Channel.d.ts.map +1 -1
- package/build/classes/Channel.js +16 -12
- package/build/classes/Channel.js.map +1 -1
- package/build/classes/Client.js +10 -2
- package/build/classes/Client.js.map +1 -1
- package/build/classes/Message.d.ts +1 -0
- package/build/classes/Message.d.ts.map +1 -1
- package/build/classes/Message.js +1 -0
- package/build/classes/Message.js.map +1 -1
- package/build/classes/Server.d.ts +2 -0
- package/build/classes/Server.d.ts.map +1 -1
- package/build/classes/Server.js +1 -0
- package/build/classes/Server.js.map +1 -1
- package/build/classes/Webhooks.d.ts.map +1 -1
- package/build/classes/Webhooks.js +6 -1
- package/build/classes/Webhooks.js.map +1 -1
- package/build/services/MessageService.d.ts +1 -0
- package/build/services/MessageService.d.ts.map +1 -1
- package/build/services/MessageService.js +18 -24
- package/build/services/MessageService.js.map +1 -1
- package/build/services/PostsService.d.ts.map +1 -1
- package/build/services/PostsService.js +0 -8
- package/build/services/PostsService.js.map +1 -1
- package/build/services/ServerService.d.ts.map +1 -1
- package/build/services/ServerService.js +0 -6
- package/build/services/ServerService.js.map +1 -1
- package/package.json +38 -38
- package/src/AsyncFunctionQueue.ts +115 -0
- package/src/classes/Channel.ts +17 -12
- package/src/classes/Client.ts +12 -2
- package/src/classes/Message.ts +2 -0
- package/src/classes/Server.ts +2 -0
- package/src/classes/Webhooks.ts +8 -1
- package/src/services/MessageService.ts +19 -24
- package/src/services/PostsService.ts +0 -8
- package/src/services/ServerService.ts +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostsService.d.ts","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"PostsService.d.ts","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,sBAO5C;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,oBAYhD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,oBAQhD;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,oBAOpD"}
|
|
@@ -12,8 +12,6 @@ async function getPosts(client) {
|
|
|
12
12
|
url: serviceEndpoints_1.ServiceEndpoints.GetPosts(),
|
|
13
13
|
method: "GET",
|
|
14
14
|
useToken: true,
|
|
15
|
-
}).catch((err) => {
|
|
16
|
-
throw new Error(`Failed to get posts. ${err.message}`);
|
|
17
15
|
});
|
|
18
16
|
}
|
|
19
17
|
async function postPost(opts) {
|
|
@@ -27,8 +25,6 @@ async function postPost(opts) {
|
|
|
27
25
|
poll: opts.poll,
|
|
28
26
|
},
|
|
29
27
|
useToken: true,
|
|
30
|
-
}).catch((err) => {
|
|
31
|
-
throw new Error(`Failed to send post. ${err.message}`);
|
|
32
28
|
});
|
|
33
29
|
}
|
|
34
30
|
async function editPost(opts) {
|
|
@@ -38,8 +34,6 @@ async function editPost(opts) {
|
|
|
38
34
|
method: "PATCH",
|
|
39
35
|
body: { content: opts.content },
|
|
40
36
|
useToken: true,
|
|
41
|
-
}).catch((err) => {
|
|
42
|
-
throw new Error(`Failed to edit post. ${err.message}`);
|
|
43
37
|
});
|
|
44
38
|
}
|
|
45
39
|
async function deletePost(opts) {
|
|
@@ -48,8 +42,6 @@ async function deletePost(opts) {
|
|
|
48
42
|
url: serviceEndpoints_1.ServiceEndpoints.DeletePost(opts.postId),
|
|
49
43
|
method: "DELETE",
|
|
50
44
|
useToken: true,
|
|
51
|
-
}).catch((err) => {
|
|
52
|
-
throw new Error(`Failed to delete post. ${err.message}`);
|
|
53
45
|
});
|
|
54
46
|
}
|
|
55
47
|
//# sourceMappingURL=PostsService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostsService.js","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":";;AA0BA,
|
|
1
|
+
{"version":3,"file":"PostsService.js","sourceRoot":"","sources":["../../src/services/PostsService.ts"],"names":[],"mappings":";;AA0BA,4BAOC;AAED,4BAYC;AAED,4BAQC;AAED,gCAOC;AAhED,qDAA2C;AAC3C,yDAAsD;AAuB/C,KAAK,UAAU,QAAQ,CAAC,MAAc;IAC3C,OAAO,MAAM,IAAA,wBAAO,EAAY;QAC9B,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,OAAO,MAAM,IAAA,wBAAO,EAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QACD,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,OAAO,MAAM,IAAA,wBAAO,EAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3C,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;QAC/B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,OAAO,MAAM,IAAA,wBAAO,EAAC;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,mCAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7C,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerService.d.ts","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI3C,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ServerService.d.ts","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI3C,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,gBAShB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,gBAQf;AACD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,gBAQf"}
|
|
@@ -12,8 +12,6 @@ async function banServerMember(client, serverId, userId, reason) {
|
|
|
12
12
|
method: "POST",
|
|
13
13
|
useToken: true,
|
|
14
14
|
body: { reason },
|
|
15
|
-
}).catch((err) => {
|
|
16
|
-
throw new Error(`Failed to ban server member. ${err.message}`);
|
|
17
15
|
});
|
|
18
16
|
}
|
|
19
17
|
async function unbanServerMember(client, serverId, userId) {
|
|
@@ -22,8 +20,6 @@ async function unbanServerMember(client, serverId, userId) {
|
|
|
22
20
|
url: serviceEndpoints_1.ServiceEndpoints.serverMemberBan(serverId, userId),
|
|
23
21
|
method: "DELETE",
|
|
24
22
|
useToken: true,
|
|
25
|
-
}).catch((err) => {
|
|
26
|
-
throw new Error(`Failed to unban server member. ${err.message}`);
|
|
27
23
|
});
|
|
28
24
|
}
|
|
29
25
|
async function kickServerMember(client, serverId, userId) {
|
|
@@ -32,8 +28,6 @@ async function kickServerMember(client, serverId, userId) {
|
|
|
32
28
|
url: serviceEndpoints_1.ServiceEndpoints.serverMemberKick(serverId, userId),
|
|
33
29
|
method: "DELETE",
|
|
34
30
|
useToken: true,
|
|
35
|
-
}).catch((err) => {
|
|
36
|
-
throw new Error(`Failed to kick server member. ${err.message}`);
|
|
37
31
|
});
|
|
38
32
|
}
|
|
39
33
|
//# sourceMappingURL=ServerService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerService.js","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":";;AAIA,
|
|
1
|
+
{"version":3,"file":"ServerService.js","sourceRoot":"","sources":["../../src/services/ServerService.ts"],"names":[],"mappings":";;AAIA,0CAaC;AAED,8CAWC;AACD,4CAWC;AAzCD,qDAA2C;AAC3C,yDAAsD;AAE/C,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,QAAgB,EAChB,MAAc,EACd,MAAe;IAEf,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC;QACvD,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,EAAE,MAAM,EAAE;KACjB,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,QAAgB,EAChB,MAAc;IAEd,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC;QACvD,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AACM,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,QAAgB,EAChB,MAAc;IAEd,OAAO,MAAM,IAAA,wBAAO,EAAM;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mCAAgB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACxD,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@nerimity/nerimity.js",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "",
|
|
5
|
-
"main": "build/index.js",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
},
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@nerimity/nerimity.js",
|
|
3
|
+
"version": "1.20.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc",
|
|
8
|
+
"prepublishOnly": "tsc",
|
|
9
|
+
"dev": "tsc && node tests/test.js"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "SupertigerDev",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@eslint/js": "^9.39.1",
|
|
16
|
+
"@types/node-fetch": "^2.6.13",
|
|
17
|
+
"@types/ws": "^8.18.1",
|
|
18
|
+
"eslint": "^9.39.1",
|
|
19
|
+
"globals": "^16.5.0",
|
|
20
|
+
"nodemon": "^3.1.11",
|
|
21
|
+
"ts-node": "^10.9.2",
|
|
22
|
+
"typescript": "^5.9.3",
|
|
23
|
+
"typescript-eslint": "^8.48.1"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"eventemitter3": "^5.0.1",
|
|
27
|
+
"socket.io-client": "^4.8.1",
|
|
28
|
+
"ws": "^8.18.3"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/Nerimity/nerimity.js.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/Nerimity/nerimity.js/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/Nerimity/nerimity.js#readme"
|
|
38
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for an item in the queue.
|
|
3
|
+
* @template T The type of the result that the async function resolves to.
|
|
4
|
+
*/
|
|
5
|
+
interface QueueItem<T> {
|
|
6
|
+
asyncFunc: () => Promise<T>;
|
|
7
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
|
8
|
+
reject: (reason?: unknown) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A simple and fast async function queue for web environments, with TypeScript types.
|
|
13
|
+
* It ensures that asynchronous functions are executed one after another in the order they were added.
|
|
14
|
+
*/
|
|
15
|
+
export class AsyncFunctionQueue {
|
|
16
|
+
/**
|
|
17
|
+
* The array that holds the queue items.
|
|
18
|
+
* Using `unknown` is a type-safe alternative to `any`.
|
|
19
|
+
* Type safety for individual items is handled by the generic `add` method.
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
private queue: QueueItem<unknown>[] = [];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A flag to indicate whether the queue is currently processing an item.
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
private isProcessing: boolean = false;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Adds an async function to the queue and returns a promise that resolves with the function's return value
|
|
32
|
+
* or rejects with its error.
|
|
33
|
+
* @template T The type of the result that the async function resolves to.
|
|
34
|
+
* @param {() => Promise<T>} asyncFunc - An async function to be added to the queue. It must be a function that returns a Promise.
|
|
35
|
+
* @returns {Promise<T>} A promise that resolves or rejects when the added function is executed.
|
|
36
|
+
*/
|
|
37
|
+
public add<T>(asyncFunc: () => Promise<T>): Promise<T> {
|
|
38
|
+
return new Promise<T>((resolve, reject) => {
|
|
39
|
+
// Push the function along with its resolve/reject handlers to the queue.
|
|
40
|
+
// We cast here to satisfy TypeScript's strict checks on function parameter contravariance.
|
|
41
|
+
// This is safe because we ensure that the `resolve` function for a given `asyncFunc`
|
|
42
|
+
// is always called with the result of that specific function.
|
|
43
|
+
this.queue.push({
|
|
44
|
+
asyncFunc,
|
|
45
|
+
resolve,
|
|
46
|
+
reject,
|
|
47
|
+
} as QueueItem<unknown>);
|
|
48
|
+
|
|
49
|
+
// If not already processing, start processing the queue.
|
|
50
|
+
if (!this.isProcessing) {
|
|
51
|
+
this._processNext();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Processes the next item in the queue.
|
|
58
|
+
* This is a private method and should not be called directly.
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
private async _processNext(): Promise<void> {
|
|
62
|
+
// If there's nothing in the queue, stop processing.
|
|
63
|
+
if (this.queue.length === 0) {
|
|
64
|
+
this.isProcessing = false;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Set the flag to indicate that processing has started.
|
|
69
|
+
this.isProcessing = true;
|
|
70
|
+
|
|
71
|
+
// Get the next item from the front of the queue.
|
|
72
|
+
const item = this.queue.shift();
|
|
73
|
+
|
|
74
|
+
if (!item) {
|
|
75
|
+
// This case should not be hit due to the length check, but it's good practice for type safety.
|
|
76
|
+
this.isProcessing = false;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
// Execute the async function.
|
|
82
|
+
const result = await item.asyncFunc();
|
|
83
|
+
// Resolve the promise associated with this function.
|
|
84
|
+
item.resolve(result);
|
|
85
|
+
} catch (error: unknown) {
|
|
86
|
+
// Reject the promise if the function throws an error.
|
|
87
|
+
item.reject(error);
|
|
88
|
+
} finally {
|
|
89
|
+
// After the function is done (either resolved or rejected),
|
|
90
|
+
// recursively call _processNext to handle the next item in the queue.
|
|
91
|
+
// Using requestAnimationFrame or setTimeout can prevent potential stack overflow with a very long queue of synchronous tasks.
|
|
92
|
+
if (typeof requestAnimationFrame !== "undefined") {
|
|
93
|
+
requestAnimationFrame(() => this._processNext());
|
|
94
|
+
} else {
|
|
95
|
+
setTimeout(() => this._processNext(), 0);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Gets the current size of the queue.
|
|
102
|
+
* @returns {number} The number of items currently in the queue.
|
|
103
|
+
*/
|
|
104
|
+
public get size(): number {
|
|
105
|
+
return this.queue.length;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Checks if the queue is currently processing an item.
|
|
110
|
+
* @returns {boolean} True if processing, false otherwise.
|
|
111
|
+
*/
|
|
112
|
+
public get isBusy(): boolean {
|
|
113
|
+
return this.isProcessing;
|
|
114
|
+
}
|
|
115
|
+
}
|
package/src/classes/Channel.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AsyncFunctionQueue } from "../AsyncFunctionQueue";
|
|
1
2
|
import { ChannelType, RawChannel } from "../RawData";
|
|
2
3
|
import {
|
|
3
4
|
deleteMessage as requestMessageDelete,
|
|
@@ -11,6 +12,8 @@ export class Channel {
|
|
|
11
12
|
client: Client;
|
|
12
13
|
id: string;
|
|
13
14
|
|
|
15
|
+
messageSendQueue = new AsyncFunctionQueue();
|
|
16
|
+
|
|
14
17
|
type: ChannelType;
|
|
15
18
|
createdAt?: number;
|
|
16
19
|
lastMessagedAt?: number;
|
|
@@ -26,19 +29,21 @@ export class Channel {
|
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
async send(content: string, opts?: MessageOpts) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
return this.messageSendQueue.add(async () => {
|
|
33
|
+
const RawMessage = await postMessage({
|
|
34
|
+
client: this.client,
|
|
35
|
+
channelId: this.id,
|
|
36
|
+
content: content,
|
|
37
|
+
silent: opts?.silent,
|
|
38
|
+
nerimityCdnFileId: opts?.nerimityCdnFileId,
|
|
39
|
+
htmlEmbed: opts?.htmlEmbed,
|
|
40
|
+
buttons: opts?.buttons,
|
|
41
|
+
replyToMessageIds: opts?.replyToMessageIds,
|
|
42
|
+
mentionReplies: opts?.mentionReplies,
|
|
43
|
+
});
|
|
44
|
+
const message = new Message(this.client, RawMessage);
|
|
45
|
+
return message;
|
|
39
46
|
});
|
|
40
|
-
const message = new Message(this.client, RawMessage);
|
|
41
|
-
return message;
|
|
42
47
|
}
|
|
43
48
|
toString() {
|
|
44
49
|
return `[#:${this.id}]`;
|
package/src/classes/Client.ts
CHANGED
|
@@ -184,7 +184,11 @@ class EventHandlers {
|
|
|
184
184
|
|
|
185
185
|
for (let i = 0; i < payload.channels.length; i++) {
|
|
186
186
|
const rawChannel = payload.channels[i];
|
|
187
|
-
this.client.channels.setCache(rawChannel);
|
|
187
|
+
const channel = this.client.channels.setCache(rawChannel);
|
|
188
|
+
if ("serverId" in rawChannel && rawChannel.serverId) {
|
|
189
|
+
const server = this.client.servers.cache.get(rawChannel.serverId);
|
|
190
|
+
server?.channels.set(channel.id, channel);
|
|
191
|
+
}
|
|
188
192
|
}
|
|
189
193
|
for (let i = 0; i < payload.serverMembers.length; i++) {
|
|
190
194
|
const member = payload.serverMembers[i];
|
|
@@ -254,6 +258,8 @@ class EventHandlers {
|
|
|
254
258
|
}
|
|
255
259
|
onServerChannelCreated(payload: { serverId: string; channel: RawChannel }) {
|
|
256
260
|
const channel = this.client.channels.setCache(payload.channel);
|
|
261
|
+
const server = this.client.servers.cache.get(payload.serverId);
|
|
262
|
+
server?.channels.set(channel.id, channel);
|
|
257
263
|
this.client.emit(
|
|
258
264
|
ClientEvents.ServerChannelCreated,
|
|
259
265
|
channel as ServerChannel
|
|
@@ -275,9 +281,13 @@ class EventHandlers {
|
|
|
275
281
|
}
|
|
276
282
|
}
|
|
277
283
|
onServerChannelDeleted(payload: { serverId: string; channelId: string }) {
|
|
278
|
-
const channel = this.client.channels.cache.
|
|
284
|
+
const channel = this.client.channels.cache.get(payload.channelId);
|
|
279
285
|
if (channel) {
|
|
280
286
|
this.client.channels.cache.delete(payload.channelId);
|
|
287
|
+
|
|
288
|
+
const server = this.client.servers.cache.get(payload.serverId);
|
|
289
|
+
server?.channels.delete(payload.channelId);
|
|
290
|
+
|
|
281
291
|
this.client.emit(ClientEvents.ServerChannelDeleted, {
|
|
282
292
|
channelId: payload.channelId,
|
|
283
293
|
serverId: payload.serverId,
|
package/src/classes/Message.ts
CHANGED
|
@@ -59,6 +59,7 @@ export interface MessageOpts {
|
|
|
59
59
|
}
|
|
60
60
|
interface EditMessageOpts {
|
|
61
61
|
htmlEmbed?: string;
|
|
62
|
+
buttons?: RawMessageButton[];
|
|
62
63
|
}
|
|
63
64
|
export class Message {
|
|
64
65
|
client: Client;
|
|
@@ -136,6 +137,7 @@ export class Message {
|
|
|
136
137
|
messageId: this.id,
|
|
137
138
|
content: content,
|
|
138
139
|
htmlEmbed: opts?.htmlEmbed,
|
|
140
|
+
buttons: opts?.buttons,
|
|
139
141
|
});
|
|
140
142
|
const message = new Message(this.client, RawMessage);
|
|
141
143
|
return message;
|
package/src/classes/Server.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
kickServerMember,
|
|
5
5
|
unbanServerMember,
|
|
6
6
|
} from "../services/ServerService";
|
|
7
|
+
import { AllChannel } from "../types";
|
|
7
8
|
import { Client } from "./Client";
|
|
8
9
|
import { Collection } from "./Collection";
|
|
9
10
|
import { ServerMembers } from "./ServerMember";
|
|
@@ -30,6 +31,7 @@ export class Server {
|
|
|
30
31
|
avatar?: string;
|
|
31
32
|
defaultRoleId: string;
|
|
32
33
|
createdById: string;
|
|
34
|
+
channels: Collection<string, AllChannel> = new Collection();
|
|
33
35
|
|
|
34
36
|
members: ServerMembers;
|
|
35
37
|
roles: ServerRoles;
|
package/src/classes/Webhooks.ts
CHANGED
|
@@ -116,6 +116,9 @@ export class WebhookBuilder {
|
|
|
116
116
|
* @throws If the request fails, is unauthorized, or returns invalid JSON.
|
|
117
117
|
*/
|
|
118
118
|
public async send(content: string): Promise<any> {
|
|
119
|
+
const error = new Error();
|
|
120
|
+
Error.captureStackTrace(error, this.send);
|
|
121
|
+
|
|
119
122
|
const url = `https://nerimity.com/api/webhooks/${this.channelId}/${this.token}`;
|
|
120
123
|
|
|
121
124
|
try {
|
|
@@ -138,7 +141,11 @@ export class WebhookBuilder {
|
|
|
138
141
|
|
|
139
142
|
return json;
|
|
140
143
|
} catch (err: any) {
|
|
141
|
-
|
|
144
|
+
const message = err.message || err;
|
|
145
|
+
error.message = `Failed to send webhook: ${message}`;
|
|
146
|
+
(error as any).raw = message;
|
|
147
|
+
|
|
148
|
+
throw error;
|
|
142
149
|
}
|
|
143
150
|
}
|
|
144
151
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Client } from "../classes/Client";
|
|
2
2
|
import { RawMessage, RawMessageButton } from "../RawData";
|
|
3
3
|
import { ServiceEndpoints } from "./serviceEndpoints";
|
|
4
|
-
import fetch from "node-fetch";
|
|
5
4
|
|
|
6
5
|
interface FetchMessageOpts {
|
|
7
6
|
client: Client;
|
|
@@ -16,12 +15,6 @@ export async function fetchMessage(opts: FetchMessageOpts) {
|
|
|
16
15
|
method: "GET",
|
|
17
16
|
|
|
18
17
|
useToken: true,
|
|
19
|
-
}).catch((err) => {
|
|
20
|
-
const error = new Error(
|
|
21
|
-
`Failed to get message. ${JSON.stringify(err.message)}`
|
|
22
|
-
);
|
|
23
|
-
(error as unknown as { raw: string }).raw = err.message;
|
|
24
|
-
throw error;
|
|
25
18
|
});
|
|
26
19
|
}
|
|
27
20
|
|
|
@@ -52,12 +45,6 @@ export async function postMessage(opts: PostMessageOpts) {
|
|
|
52
45
|
replyToMessageIds: opts.replyToMessageIds,
|
|
53
46
|
},
|
|
54
47
|
useToken: true,
|
|
55
|
-
}).catch((err) => {
|
|
56
|
-
const error = new Error(
|
|
57
|
-
`Failed to send message. ${JSON.stringify(err.message)}`
|
|
58
|
-
);
|
|
59
|
-
(error as unknown as { raw: string }).raw = err.message;
|
|
60
|
-
throw error;
|
|
61
48
|
});
|
|
62
49
|
}
|
|
63
50
|
|
|
@@ -67,6 +54,7 @@ interface EditMessageOpts {
|
|
|
67
54
|
messageId: string;
|
|
68
55
|
content: string;
|
|
69
56
|
htmlEmbed?: string;
|
|
57
|
+
buttons?: RawMessageButton[];
|
|
70
58
|
}
|
|
71
59
|
|
|
72
60
|
export function editMessage(opts: EditMessageOpts) {
|
|
@@ -74,10 +62,12 @@ export function editMessage(opts: EditMessageOpts) {
|
|
|
74
62
|
client: opts.client,
|
|
75
63
|
url: ServiceEndpoints.EditMessage(opts.channelId, opts.messageId),
|
|
76
64
|
method: "PATCH",
|
|
77
|
-
body: {
|
|
65
|
+
body: {
|
|
66
|
+
content: opts.content,
|
|
67
|
+
htmlEmbed: opts.htmlEmbed,
|
|
68
|
+
buttons: opts.buttons,
|
|
69
|
+
},
|
|
78
70
|
useToken: true,
|
|
79
|
-
}).catch((err) => {
|
|
80
|
-
throw err.message;
|
|
81
71
|
});
|
|
82
72
|
}
|
|
83
73
|
|
|
@@ -92,8 +82,6 @@ export function deleteMessage(opts: DeleteMessageOpts) {
|
|
|
92
82
|
url: ServiceEndpoints.EditMessage(opts.channelId, opts.messageId),
|
|
93
83
|
method: "DELETE",
|
|
94
84
|
useToken: true,
|
|
95
|
-
}).catch((err) => {
|
|
96
|
-
throw err.message;
|
|
97
85
|
});
|
|
98
86
|
}
|
|
99
87
|
|
|
@@ -168,8 +156,6 @@ export function buttonClickCallback(opts: ButtonClickCallbackOpts) {
|
|
|
168
156
|
userId: opts.userId,
|
|
169
157
|
},
|
|
170
158
|
useToken: true,
|
|
171
|
-
}).catch((err) => {
|
|
172
|
-
throw err.message;
|
|
173
159
|
});
|
|
174
160
|
}
|
|
175
161
|
|
|
@@ -184,6 +170,9 @@ interface RequestOpts {
|
|
|
184
170
|
}
|
|
185
171
|
|
|
186
172
|
export async function request<T>(opts: RequestOpts): Promise<T> {
|
|
173
|
+
const stackCapture: any = {};
|
|
174
|
+
Error.captureStackTrace(stackCapture, request);
|
|
175
|
+
|
|
187
176
|
const url = new URL(opts.url);
|
|
188
177
|
url.search = new URLSearchParams(opts.params || {}).toString();
|
|
189
178
|
|
|
@@ -195,7 +184,7 @@ export async function request<T>(opts: RequestOpts): Promise<T> {
|
|
|
195
184
|
Authorization: opts.useToken ? opts.client.token! : "",
|
|
196
185
|
},
|
|
197
186
|
}).catch((err) => {
|
|
198
|
-
throw
|
|
187
|
+
throw new Error("Could not connect to server. " + err.message);
|
|
199
188
|
});
|
|
200
189
|
|
|
201
190
|
const text = await response.text();
|
|
@@ -204,10 +193,16 @@ export async function request<T>(opts: RequestOpts): Promise<T> {
|
|
|
204
193
|
try {
|
|
205
194
|
const json = JSON.parse(text);
|
|
206
195
|
if (!response.ok) {
|
|
207
|
-
|
|
196
|
+
throw new Error(JSON.stringify(json));
|
|
208
197
|
}
|
|
209
198
|
return json;
|
|
210
|
-
} catch {
|
|
211
|
-
|
|
199
|
+
} catch (err) {
|
|
200
|
+
if (err instanceof Error) {
|
|
201
|
+
// Remove the first line of the captured stack ("Error")
|
|
202
|
+
// and append the rest to the real error
|
|
203
|
+
const originalStack = stackCapture.stack?.split("\n").slice(1).join("\n");
|
|
204
|
+
err.stack += "\n -- caused by --\n" + originalStack;
|
|
205
|
+
}
|
|
206
|
+
throw err;
|
|
212
207
|
}
|
|
213
208
|
}
|
|
@@ -30,8 +30,6 @@ export async function getPosts(client: Client) {
|
|
|
30
30
|
url: ServiceEndpoints.GetPosts(),
|
|
31
31
|
method: "GET",
|
|
32
32
|
useToken: true,
|
|
33
|
-
}).catch((err) => {
|
|
34
|
-
throw new Error(`Failed to get posts. ${err.message}`);
|
|
35
33
|
});
|
|
36
34
|
}
|
|
37
35
|
|
|
@@ -46,8 +44,6 @@ export async function postPost(opts: PostPostOpts) {
|
|
|
46
44
|
poll: opts.poll,
|
|
47
45
|
},
|
|
48
46
|
useToken: true,
|
|
49
|
-
}).catch((err) => {
|
|
50
|
-
throw new Error(`Failed to send post. ${err.message}`);
|
|
51
47
|
});
|
|
52
48
|
}
|
|
53
49
|
|
|
@@ -58,8 +54,6 @@ export async function editPost(opts: EditPostOpts) {
|
|
|
58
54
|
method: "PATCH",
|
|
59
55
|
body: { content: opts.content },
|
|
60
56
|
useToken: true,
|
|
61
|
-
}).catch((err) => {
|
|
62
|
-
throw new Error(`Failed to edit post. ${err.message}`);
|
|
63
57
|
});
|
|
64
58
|
}
|
|
65
59
|
|
|
@@ -69,7 +63,5 @@ export async function deletePost(opts: DeletePostOpts) {
|
|
|
69
63
|
url: ServiceEndpoints.DeletePost(opts.postId),
|
|
70
64
|
method: "DELETE",
|
|
71
65
|
useToken: true,
|
|
72
|
-
}).catch((err) => {
|
|
73
|
-
throw new Error(`Failed to delete post. ${err.message}`);
|
|
74
66
|
});
|
|
75
67
|
}
|
|
@@ -14,8 +14,6 @@ export async function banServerMember(
|
|
|
14
14
|
method: "POST",
|
|
15
15
|
useToken: true,
|
|
16
16
|
body: { reason },
|
|
17
|
-
}).catch((err) => {
|
|
18
|
-
throw new Error(`Failed to ban server member. ${err.message}`);
|
|
19
17
|
});
|
|
20
18
|
}
|
|
21
19
|
|
|
@@ -29,8 +27,6 @@ export async function unbanServerMember(
|
|
|
29
27
|
url: ServiceEndpoints.serverMemberBan(serverId, userId),
|
|
30
28
|
method: "DELETE",
|
|
31
29
|
useToken: true,
|
|
32
|
-
}).catch((err) => {
|
|
33
|
-
throw new Error(`Failed to unban server member. ${err.message}`);
|
|
34
30
|
});
|
|
35
31
|
}
|
|
36
32
|
export async function kickServerMember(
|
|
@@ -43,7 +39,5 @@ export async function kickServerMember(
|
|
|
43
39
|
url: ServiceEndpoints.serverMemberKick(serverId, userId),
|
|
44
40
|
method: "DELETE",
|
|
45
41
|
useToken: true,
|
|
46
|
-
}).catch((err) => {
|
|
47
|
-
throw new Error(`Failed to kick server member. ${err.message}`);
|
|
48
42
|
});
|
|
49
43
|
}
|