@theholocron/holocron-plugin-discord 5.0.0-alpha.183 → 5.0.0-alpha.185
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +19 -0
- package/dist/index.mjs +48 -8
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -47,6 +47,25 @@ declare class DiscordNotifications implements Notifications {
|
|
|
47
47
|
target: string;
|
|
48
48
|
} | null>;
|
|
49
49
|
private guild;
|
|
50
|
+
/**
|
|
51
|
+
* The server's channel list, fetched once per instance. Every ensure* call used
|
|
52
|
+
* to refetch it -- about 40 identical GETs in one setup run -- and Discord
|
|
53
|
+
* rate-limited the route. Our own creates and edits update the copy, so it
|
|
54
|
+
* stays accurate for the run; a new run builds a new instance.
|
|
55
|
+
*
|
|
56
|
+
* It is the in-flight promise that is shared, not the array: callers that start
|
|
57
|
+
* while the first fetch is pending all get the same snapshot, so a later
|
|
58
|
+
* response can never overwrite what an earlier caller added.
|
|
59
|
+
*/
|
|
60
|
+
private channelLoad?;
|
|
61
|
+
private channelList;
|
|
62
|
+
/**
|
|
63
|
+
* Create a channel and add it to the shared list. If the create fails, Discord
|
|
64
|
+
* may still have applied it (a timeout looks the same as a refusal), so forget the
|
|
65
|
+
* list: the next ensure refetches the server's real state instead of creating a
|
|
66
|
+
* duplicate.
|
|
67
|
+
*/
|
|
68
|
+
private createChannel;
|
|
50
69
|
private static same;
|
|
51
70
|
ensureCategory(name: string): Promise<EnsuredResource>;
|
|
52
71
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -58,18 +58,50 @@ var DiscordNotifications = class DiscordNotifications {
|
|
|
58
58
|
if (!this.opts.guildId) throw new Error("no Discord server id — set `guildId` in the discord provider options in holocron.config.ts");
|
|
59
59
|
return this.opts.guildId;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* The server's channel list, fetched once per instance. Every ensure* call used
|
|
63
|
+
* to refetch it -- about 40 identical GETs in one setup run -- and Discord
|
|
64
|
+
* rate-limited the route. Our own creates and edits update the copy, so it
|
|
65
|
+
* stays accurate for the run; a new run builds a new instance.
|
|
66
|
+
*
|
|
67
|
+
* It is the in-flight promise that is shared, not the array: callers that start
|
|
68
|
+
* while the first fetch is pending all get the same snapshot, so a later
|
|
69
|
+
* response can never overwrite what an earlier caller added.
|
|
70
|
+
*/
|
|
71
|
+
channelLoad;
|
|
72
|
+
channelList() {
|
|
73
|
+
return this.channelLoad ??= this.bot().guilds.channels(this.guild()).catch((err) => {
|
|
74
|
+
this.channelLoad = void 0;
|
|
75
|
+
throw err;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create a channel and add it to the shared list. If the create fails, Discord
|
|
80
|
+
* may still have applied it (a timeout looks the same as a refusal), so forget the
|
|
81
|
+
* list: the next ensure refetches the server's real state instead of creating a
|
|
82
|
+
* duplicate.
|
|
83
|
+
*/
|
|
84
|
+
async createChannel(body) {
|
|
85
|
+
try {
|
|
86
|
+
const made = await this.bot().guilds.createChannel(this.guild(), body);
|
|
87
|
+
(await this.channelList()).push(made);
|
|
88
|
+
return made;
|
|
89
|
+
} catch (err) {
|
|
90
|
+
this.channelLoad = void 0;
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
61
94
|
static same(a, b) {
|
|
62
95
|
return a.toLowerCase() === b.toLowerCase();
|
|
63
96
|
}
|
|
64
97
|
async ensureCategory(name) {
|
|
65
|
-
const
|
|
66
|
-
const existing = (await bot.guilds.channels(this.guild())).find((c) => c.type === ChannelType.Category && DiscordNotifications.same(c.name, name));
|
|
98
|
+
const existing = (await this.channelList()).find((c) => c.type === ChannelType.Category && DiscordNotifications.same(c.name, name));
|
|
67
99
|
if (existing) return {
|
|
68
100
|
id: existing.id,
|
|
69
101
|
created: false
|
|
70
102
|
};
|
|
71
103
|
return {
|
|
72
|
-
id: (await
|
|
104
|
+
id: (await this.createChannel({
|
|
73
105
|
name,
|
|
74
106
|
type: ChannelType.Category
|
|
75
107
|
})).id,
|
|
@@ -90,20 +122,28 @@ var DiscordNotifications = class DiscordNotifications {
|
|
|
90
122
|
async ensureChannel(input) {
|
|
91
123
|
const bot = this.bot();
|
|
92
124
|
const parent = input.category ? (await this.ensureCategory(input.category)).id : void 0;
|
|
93
|
-
const existing = DiscordNotifications.findChannel(await
|
|
125
|
+
const existing = DiscordNotifications.findChannel(await this.channelList(), input.name, parent);
|
|
94
126
|
if (existing) {
|
|
95
127
|
const patch = {
|
|
96
128
|
...parent && existing.parent_id !== parent ? { parent_id: parent } : {},
|
|
97
129
|
...input.topic !== void 0 && (existing.topic ?? "") !== input.topic ? { topic: input.topic } : {}
|
|
98
130
|
};
|
|
99
|
-
if (Object.keys(patch).length > 0)
|
|
131
|
+
if (Object.keys(patch).length > 0) {
|
|
132
|
+
try {
|
|
133
|
+
await bot.channels.modify(existing.id, patch);
|
|
134
|
+
} catch (err) {
|
|
135
|
+
this.channelLoad = void 0;
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
Object.assign(existing, patch);
|
|
139
|
+
}
|
|
100
140
|
return {
|
|
101
141
|
id: existing.id,
|
|
102
142
|
created: false
|
|
103
143
|
};
|
|
104
144
|
}
|
|
105
145
|
return {
|
|
106
|
-
id: (await
|
|
146
|
+
id: (await this.createChannel({
|
|
107
147
|
name: input.name,
|
|
108
148
|
type: ChannelType.Text,
|
|
109
149
|
...input.topic ? { topic: input.topic } : {},
|
|
@@ -114,8 +154,8 @@ var DiscordNotifications = class DiscordNotifications {
|
|
|
114
154
|
}
|
|
115
155
|
async ensureWebhook(input) {
|
|
116
156
|
const bot = this.bot();
|
|
117
|
-
const parent = input.category ? (await
|
|
118
|
-
const channel = DiscordNotifications.findChannel(await
|
|
157
|
+
const parent = input.category ? (await this.channelList()).find((c) => c.type === ChannelType.Category && DiscordNotifications.same(c.name, input.category))?.id : void 0;
|
|
158
|
+
const channel = DiscordNotifications.findChannel(await this.channelList(), input.channel, parent);
|
|
119
159
|
if (!channel) throw new Error(`no channel named \`${input.channel}\` — create it first`);
|
|
120
160
|
const existing = (await bot.channels.webhooks(channel.id)).find((w) => DiscordNotifications.same(w.name ?? "", input.name));
|
|
121
161
|
if (existing) return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-discord",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.185",
|
|
4
4
|
"description": "Holocron plugin for Discord. Implements the notifications capability via Discord incoming webhooks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"discord",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"tsx": "4.23.15",
|
|
49
49
|
"typescript": "^5.9.3",
|
|
50
50
|
"vitest": "^4.1.11",
|
|
51
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
51
|
+
"@theholocron/cli": "5.0.0-alpha.185"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@theholocron/discord-client": "^1.43.1",
|
|
55
55
|
"@theholocron/misc-utils": "^1.16.0",
|
|
56
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
56
|
+
"@theholocron/cli": "5.0.0-alpha.185"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">=22"
|