@confluxjs/conflux 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/dist/cli.cjs +286 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +284 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.cjs +0 -0
- package/dist/commands.d.cts +4 -0
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +1 -0
- package/dist/config.cjs +3 -0
- package/dist/config.d.cts +3 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +3 -0
- package/dist/conflux-Bx2wI68U.d.ts +18 -0
- package/dist/conflux-Bx2wI68U.d.ts.map +1 -0
- package/dist/conflux-Cff37YF-.d.cts +18 -0
- package/dist/conflux-Cff37YF-.d.cts.map +1 -0
- package/dist/define-config-Bb-dVG_k.js +33 -0
- package/dist/define-config-Bb-dVG_k.js.map +1 -0
- package/dist/define-config-BcOV1lur.d.cts +7 -0
- package/dist/define-config-BcOV1lur.d.cts.map +1 -0
- package/dist/define-config-BsNwuPZR.d.ts +7 -0
- package/dist/define-config-BsNwuPZR.d.ts.map +1 -0
- package/dist/define-config-DW4WVjfh.cjs +80 -0
- package/dist/define-config-DW4WVjfh.cjs.map +1 -0
- package/dist/dev-runner.cjs +14 -0
- package/dist/dev-runner.cjs.map +1 -0
- package/dist/dev-runner.d.cts +1 -0
- package/dist/dev-runner.d.ts +1 -0
- package/dist/dev-runner.js +15 -0
- package/dist/dev-runner.js.map +1 -0
- package/dist/events.cjs +3 -0
- package/dist/events.d.cts +4 -0
- package/dist/events.d.ts +4 -0
- package/dist/events.js +3 -0
- package/dist/index.cjs +479 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +469 -0
- package/dist/index.js.map +1 -0
- package/dist/parse-args-73A1_Lee.cjs +42 -0
- package/dist/parse-args-73A1_Lee.cjs.map +1 -0
- package/dist/parse-args-fMvnTEQ2.js +30 -0
- package/dist/parse-args-fMvnTEQ2.js.map +1 -0
- package/dist/pipeline-B7aJQrzJ.cjs +33 -0
- package/dist/pipeline-B7aJQrzJ.cjs.map +1 -0
- package/dist/pipeline-BkDu0cvJ.js +15 -0
- package/dist/pipeline-BkDu0cvJ.js.map +1 -0
- package/dist/run-conflux-B_44EsUH.cjs +586 -0
- package/dist/run-conflux-B_44EsUH.cjs.map +1 -0
- package/dist/run-conflux-DMth5S90.js +518 -0
- package/dist/run-conflux-DMth5S90.js.map +1 -0
- package/dist/runtime.cjs +4 -0
- package/dist/runtime.d.cts +3 -0
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.js +3 -0
- package/dist/start.cjs +12 -0
- package/dist/start.cjs.map +1 -0
- package/dist/start.d.cts +1 -0
- package/dist/start.d.ts +1 -0
- package/dist/start.js +13 -0
- package/dist/start.js.map +1 -0
- package/dist/state-CCmrZeeU.d.cts +8 -0
- package/dist/state-CCmrZeeU.d.cts.map +1 -0
- package/dist/state-CN_liMII.d.ts +8 -0
- package/dist/state-CN_liMII.d.ts.map +1 -0
- package/dist/state-DJDc7S6k.js +13 -0
- package/dist/state-DJDc7S6k.js.map +1 -0
- package/dist/state-EbW_m9jV.cjs +25 -0
- package/dist/state-EbW_m9jV.cjs.map +1 -0
- package/dist/types-BF-O7UjY.d.cts +20 -0
- package/dist/types-BF-O7UjY.d.cts.map +1 -0
- package/dist/types-BNkZrOSn.d.ts +25 -0
- package/dist/types-BNkZrOSn.d.ts.map +1 -0
- package/dist/types-C642X_95.d.cts +25 -0
- package/dist/types-C642X_95.d.cts.map +1 -0
- package/dist/types-CDgj0pfF.d.cts +46 -0
- package/dist/types-CDgj0pfF.d.cts.map +1 -0
- package/dist/types-CYtE8ckK.d.ts +46 -0
- package/dist/types-CYtE8ckK.d.ts.map +1 -0
- package/dist/types-cu2r7p_e.d.ts +20 -0
- package/dist/types-cu2r7p_e.d.ts.map +1 -0
- package/package.json +107 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { n as CONFIG_FILENAMES, r as resolveConfluxConfig, t as defineConfig } from "./define-config-Bb-dVG_k.js";
|
|
2
|
+
import { n as resetEventPipeline, r as stopAllEvents, t as isEventPipelineHalted } from "./pipeline-BkDu0cvJ.js";
|
|
3
|
+
import { n as setConfig, t as getConfig } from "./state-DJDc7S6k.js";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { Client, Events, parsePrefixCommand } from "@fluxerjs/core";
|
|
8
|
+
|
|
9
|
+
//#region src/core/conflux.ts
|
|
10
|
+
var Conflux = class {
|
|
11
|
+
options;
|
|
12
|
+
client = null;
|
|
13
|
+
prefixResolver = null;
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
this.options = options;
|
|
16
|
+
}
|
|
17
|
+
setPrefix(resolver) {
|
|
18
|
+
this.prefixResolver = resolver;
|
|
19
|
+
}
|
|
20
|
+
async resolvePrefixes() {
|
|
21
|
+
if (!this.prefixResolver) return ["!"];
|
|
22
|
+
const result = await this.prefixResolver();
|
|
23
|
+
return Array.isArray(result) ? result : [result];
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function createConflux(options) {
|
|
27
|
+
return new Conflux(options ?? {});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/loader/directory-modules.ts
|
|
32
|
+
const MODULE_EXTENSIONS = [
|
|
33
|
+
".ts",
|
|
34
|
+
".js",
|
|
35
|
+
".mts",
|
|
36
|
+
".mjs",
|
|
37
|
+
".cjs"
|
|
38
|
+
];
|
|
39
|
+
function isLoadableModule(name) {
|
|
40
|
+
return MODULE_EXTENSIONS.some((ext) => name.endsWith(ext));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/commands/discover-paths.ts
|
|
45
|
+
function stem(name) {
|
|
46
|
+
const dot = name.lastIndexOf(".");
|
|
47
|
+
return dot === -1 ? name : name.slice(0, dot);
|
|
48
|
+
}
|
|
49
|
+
function classifyPlusFile(filePath, fileName, out) {
|
|
50
|
+
const base = stem(fileName);
|
|
51
|
+
if (base === "+global-middleware") {
|
|
52
|
+
out.globalMiddlewarePaths.push(filePath);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (base === "+middleware") {
|
|
56
|
+
out.directoryMiddlewarePaths.set(dirname(filePath), filePath);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (base.startsWith("+") && base.endsWith(".middleware")) {
|
|
60
|
+
const commandName = base.slice(1, -11);
|
|
61
|
+
if (!commandName) throw new Error(`Invalid command middleware file name: ${filePath}`);
|
|
62
|
+
const key = `${dirname(filePath)}\0${commandName}`;
|
|
63
|
+
out.commandMiddlewarePaths.set(key, filePath);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Unrecognized middleware file: ${filePath}`);
|
|
67
|
+
}
|
|
68
|
+
function walkDirectory(dir, out) {
|
|
69
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
70
|
+
for (const entry of entries) {
|
|
71
|
+
const entryPath = join(dir, entry.name);
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
walkDirectory(entryPath, out);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!entry.isFile() || !isLoadableModule(entry.name)) continue;
|
|
77
|
+
if (entry.name.startsWith("+")) {
|
|
78
|
+
classifyPlusFile(entryPath, entry.name, out);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
out.commandPaths.push(entryPath);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function discoverCommandPaths(commandsDir) {
|
|
85
|
+
const out = {
|
|
86
|
+
commandPaths: [],
|
|
87
|
+
globalMiddlewarePaths: [],
|
|
88
|
+
directoryMiddlewarePaths: /* @__PURE__ */ new Map(),
|
|
89
|
+
commandMiddlewarePaths: /* @__PURE__ */ new Map()
|
|
90
|
+
};
|
|
91
|
+
if (!existsSync(commandsDir)) return out;
|
|
92
|
+
walkDirectory(commandsDir, out);
|
|
93
|
+
out.commandPaths.sort((a, b) => a.localeCompare(b));
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/commands/validate-registry.ts
|
|
99
|
+
function validateDiscoveredMiddleware(discovered, commandsDir) {
|
|
100
|
+
if (discovered.globalMiddlewarePaths.length > 1) throw new Error(`Only one +global-middleware module is allowed under ${commandsDir}. Found: ${discovered.globalMiddlewarePaths.join(", ")}`);
|
|
101
|
+
}
|
|
102
|
+
function validateCommandTriggers(commands) {
|
|
103
|
+
const triggerOwners = /* @__PURE__ */ new Map();
|
|
104
|
+
for (const command of commands) {
|
|
105
|
+
const triggers = [command.data.name, ...command.data.aliases ?? []];
|
|
106
|
+
for (const trigger of triggers) {
|
|
107
|
+
if (!trigger) throw new Error(`Command at ${command.filePath} has an empty trigger name or alias`);
|
|
108
|
+
const key = trigger.toLowerCase();
|
|
109
|
+
const existing = triggerOwners.get(key);
|
|
110
|
+
if (existing) throw new Error(`Duplicate command trigger "${trigger}" in ${command.filePath} (already used by ${existing})`);
|
|
111
|
+
triggerOwners.set(key, command.filePath);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/commands/load-registry.ts
|
|
118
|
+
function isCommandData(value) {
|
|
119
|
+
if (!value || typeof value !== "object") return false;
|
|
120
|
+
const data = value;
|
|
121
|
+
return typeof data.name === "string" && data.name.length > 0;
|
|
122
|
+
}
|
|
123
|
+
function isMessageCommand(value) {
|
|
124
|
+
return typeof value === "function";
|
|
125
|
+
}
|
|
126
|
+
function readMiddleware(module) {
|
|
127
|
+
const candidate = module.middleware ?? module.default;
|
|
128
|
+
if (!candidate || typeof candidate !== "object") throw new Error("Middleware module must default-export or export `middleware`");
|
|
129
|
+
const middleware = candidate;
|
|
130
|
+
if (typeof middleware.beforeExecute !== "function" || typeof middleware.afterExecute !== "function") throw new Error("Middleware must define beforeExecute and afterExecute functions");
|
|
131
|
+
return middleware;
|
|
132
|
+
}
|
|
133
|
+
async function loadMiddlewareFile(filePath) {
|
|
134
|
+
const module = await import(pathToFileURL(filePath).href);
|
|
135
|
+
try {
|
|
136
|
+
return readMiddleware(module);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
139
|
+
throw new Error(`${message}: ${filePath}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async function loadCommandFile(filePath) {
|
|
143
|
+
const module = await import(pathToFileURL(filePath).href);
|
|
144
|
+
const data = module.data;
|
|
145
|
+
if (!isCommandData(data)) throw new Error(`Command module must export \`data\` with a non-empty name: ${filePath}`);
|
|
146
|
+
const message = module.message;
|
|
147
|
+
if (!isMessageCommand(message)) throw new Error(`Command module must export \`message\` function: ${filePath}`);
|
|
148
|
+
const namedAfter = module.after;
|
|
149
|
+
const after = typeof namedAfter === "function" ? namedAfter : typeof message.after === "function" ? message.after : void 0;
|
|
150
|
+
return {
|
|
151
|
+
filePath,
|
|
152
|
+
directory: dirname(filePath),
|
|
153
|
+
data,
|
|
154
|
+
message,
|
|
155
|
+
after
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async function loadMiddlewareMaps(discovered) {
|
|
159
|
+
const globalMiddleware = discovered.globalMiddlewarePaths.length === 1 ? await loadMiddlewareFile(discovered.globalMiddlewarePaths[0]) : null;
|
|
160
|
+
const directoryMiddleware = /* @__PURE__ */ new Map();
|
|
161
|
+
for (const [dir, filePath] of discovered.directoryMiddlewarePaths) directoryMiddleware.set(dir, await loadMiddlewareFile(filePath));
|
|
162
|
+
const commandMiddleware = /* @__PURE__ */ new Map();
|
|
163
|
+
for (const [key, filePath] of discovered.commandMiddlewarePaths) commandMiddleware.set(key, await loadMiddlewareFile(filePath));
|
|
164
|
+
return {
|
|
165
|
+
globalMiddleware,
|
|
166
|
+
directoryMiddleware,
|
|
167
|
+
commandMiddleware
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
async function loadCommandRegistry(commandsDir) {
|
|
171
|
+
const discovered = discoverCommandPaths(commandsDir);
|
|
172
|
+
validateDiscoveredMiddleware(discovered, commandsDir);
|
|
173
|
+
const commands = [];
|
|
174
|
+
for (const filePath of discovered.commandPaths) commands.push(await loadCommandFile(filePath));
|
|
175
|
+
validateCommandTriggers(commands);
|
|
176
|
+
const middleware = await loadMiddlewareMaps(discovered);
|
|
177
|
+
const byTrigger = /* @__PURE__ */ new Map();
|
|
178
|
+
for (const command of commands) {
|
|
179
|
+
byTrigger.set(command.data.name.toLowerCase(), command);
|
|
180
|
+
for (const alias of command.data.aliases ?? []) byTrigger.set(alias.toLowerCase(), command);
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
commands,
|
|
184
|
+
byTrigger,
|
|
185
|
+
...middleware
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/commands/check-permissions.ts
|
|
191
|
+
function memberHasPermissions(permissions, required) {
|
|
192
|
+
if (required.length === 0) return true;
|
|
193
|
+
if (!permissions) return false;
|
|
194
|
+
return permissions.has(required);
|
|
195
|
+
}
|
|
196
|
+
async function checkCommandPermissions(message, userPermissions, botPermissions) {
|
|
197
|
+
const guild = message.guild;
|
|
198
|
+
if (!guild) {
|
|
199
|
+
if (userPermissions?.length || botPermissions?.length) return false;
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
if (userPermissions?.length) {
|
|
203
|
+
if (!memberHasPermissions((await guild.members.resolve(message.author.id)).permissions, userPermissions)) return false;
|
|
204
|
+
}
|
|
205
|
+
if (botPermissions?.length) {
|
|
206
|
+
if (!memberHasPermissions((guild.members.me ?? await guild.members.fetchMe().catch(() => null))?.permissions, botPermissions)) return false;
|
|
207
|
+
}
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/commands/resolve-middleware.ts
|
|
213
|
+
function directoryChain(commandsDir, commandDir) {
|
|
214
|
+
const dirs = [];
|
|
215
|
+
let current = commandDir;
|
|
216
|
+
while (true) {
|
|
217
|
+
dirs.unshift(current);
|
|
218
|
+
if (current === commandsDir) break;
|
|
219
|
+
current = dirname(current);
|
|
220
|
+
}
|
|
221
|
+
return dirs;
|
|
222
|
+
}
|
|
223
|
+
function resolveMiddlewareChain(registry, command, commandsDir) {
|
|
224
|
+
const chain = [];
|
|
225
|
+
if (registry.globalMiddleware) chain.push(registry.globalMiddleware);
|
|
226
|
+
for (const dir of directoryChain(commandsDir, command.directory)) {
|
|
227
|
+
const middleware = registry.directoryMiddleware.get(dir);
|
|
228
|
+
if (middleware) chain.push(middleware);
|
|
229
|
+
}
|
|
230
|
+
const commandKey = `${command.directory}\0${command.data.name}`;
|
|
231
|
+
const commandMiddleware = registry.commandMiddleware.get(commandKey);
|
|
232
|
+
if (commandMiddleware) chain.push(commandMiddleware);
|
|
233
|
+
return chain;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/commands/dispatch.ts
|
|
238
|
+
function parseWithPrefixes(content, prefixes) {
|
|
239
|
+
for (const prefix of prefixes) {
|
|
240
|
+
const parsed = parsePrefixCommand(content, prefix);
|
|
241
|
+
if (parsed) return parsed;
|
|
242
|
+
}
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
function passesGuildFilter(message, guilds) {
|
|
246
|
+
if (!guilds?.length) return true;
|
|
247
|
+
if (!message.guildId) return true;
|
|
248
|
+
return guilds.includes(message.guildId);
|
|
249
|
+
}
|
|
250
|
+
function createCommandContext(message, client, conflux, commandName, args, data) {
|
|
251
|
+
return {
|
|
252
|
+
message,
|
|
253
|
+
client,
|
|
254
|
+
conflux,
|
|
255
|
+
data,
|
|
256
|
+
commandName,
|
|
257
|
+
args: () => args
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
async function dispatchPrefixCommand(message, client, conflux, registry, commandsDir) {
|
|
261
|
+
if (message.author.bot) return;
|
|
262
|
+
const prefixes = await conflux.resolvePrefixes();
|
|
263
|
+
const parsed = parseWithPrefixes(message.content, prefixes);
|
|
264
|
+
if (!parsed) return;
|
|
265
|
+
const command = registry.byTrigger.get(parsed.command.toLowerCase());
|
|
266
|
+
if (!command) return;
|
|
267
|
+
if (!passesGuildFilter(message, command.data.guilds)) return;
|
|
268
|
+
if (!await checkCommandPermissions(message, command.data.userPermissions, command.data.botPermissions)) return;
|
|
269
|
+
const ctx = createCommandContext(message, client, conflux, parsed.command, parsed.args, command.data);
|
|
270
|
+
const middlewares = resolveMiddlewareChain(registry, command, commandsDir);
|
|
271
|
+
for (const middleware of middlewares) await middleware.beforeExecute(ctx);
|
|
272
|
+
await command.message(ctx);
|
|
273
|
+
if (command.after) await command.after(ctx);
|
|
274
|
+
for (let i = middlewares.length - 1; i >= 0; i -= 1) await middlewares[i].afterExecute(ctx);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/commands/register-commands.ts
|
|
279
|
+
function registerConfluxCommands(client, conflux, registry, commandsDir) {
|
|
280
|
+
client.on("messageCreate", (message) => {
|
|
281
|
+
dispatchPrefixCommand(message, client, conflux, registry, commandsDir);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
//#endregion
|
|
286
|
+
//#region src/config/load-config.ts
|
|
287
|
+
function isResolvedConfig(value) {
|
|
288
|
+
if (!value || typeof value !== "object") return false;
|
|
289
|
+
const record = value;
|
|
290
|
+
return typeof record.root === "string" && typeof record.entry === "string" && typeof record.outDir === "string";
|
|
291
|
+
}
|
|
292
|
+
function findConfigPath(root) {
|
|
293
|
+
for (const name of CONFIG_FILENAMES) {
|
|
294
|
+
const path = join(root, name);
|
|
295
|
+
if (existsSync(path)) return path;
|
|
296
|
+
}
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
async function loadConfluxConfig(root) {
|
|
300
|
+
const configPath = findConfigPath(root);
|
|
301
|
+
if (!configPath) return resolveConfluxConfig({}, root);
|
|
302
|
+
const imported = await import(pathToFileURL(configPath).href);
|
|
303
|
+
const exported = imported.default ?? imported;
|
|
304
|
+
if (typeof exported === "function") {
|
|
305
|
+
const result = await exported();
|
|
306
|
+
if (isResolvedConfig(result)) return result;
|
|
307
|
+
return resolveConfluxConfig(result, root);
|
|
308
|
+
}
|
|
309
|
+
if (isResolvedConfig(exported)) return exported;
|
|
310
|
+
return resolveConfluxConfig(exported, root);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region src/env/project-env.ts
|
|
315
|
+
function parseEnvLine(line) {
|
|
316
|
+
const trimmed = line.trim();
|
|
317
|
+
if (!trimmed || trimmed.startsWith("#")) return null;
|
|
318
|
+
const exportPrefix = trimmed.startsWith("export ") ? trimmed.slice(7).trim() : trimmed;
|
|
319
|
+
const eq = exportPrefix.indexOf("=");
|
|
320
|
+
if (eq === -1) return null;
|
|
321
|
+
const key = exportPrefix.slice(0, eq).trim();
|
|
322
|
+
let value = exportPrefix.slice(eq + 1).trim();
|
|
323
|
+
if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
|
|
324
|
+
return [key, value];
|
|
325
|
+
}
|
|
326
|
+
function loadEnvFile(path) {
|
|
327
|
+
if (!existsSync(path)) return;
|
|
328
|
+
const content = readFileSync(path, "utf8");
|
|
329
|
+
for (const line of content.split(/\r?\n/)) {
|
|
330
|
+
const parsed = parseEnvLine(line);
|
|
331
|
+
if (!parsed) continue;
|
|
332
|
+
const [key, value] = parsed;
|
|
333
|
+
if (process.env[key] === void 0) process.env[key] = value;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function loadProjectEnv(root) {
|
|
337
|
+
loadEnvFile(join(root, ".env"));
|
|
338
|
+
loadEnvFile(join(root, ".env.local"));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/env/resolve-token.ts
|
|
343
|
+
const TOKEN_ENV_CANDIDATES = [
|
|
344
|
+
"FLUXER_BOT_TOKEN",
|
|
345
|
+
"BOT_TOKEN",
|
|
346
|
+
"TOKEN"
|
|
347
|
+
];
|
|
348
|
+
function resolveBotToken(config) {
|
|
349
|
+
if (config.token) return config.token;
|
|
350
|
+
if (config.env) {
|
|
351
|
+
const fromNamed = process.env[config.env];
|
|
352
|
+
if (fromNamed) return fromNamed;
|
|
353
|
+
throw new Error(`Bot token env var "${config.env}" is not set (check .env or your environment)`);
|
|
354
|
+
}
|
|
355
|
+
for (const name of TOKEN_ENV_CANDIDATES) {
|
|
356
|
+
const value = process.env[name];
|
|
357
|
+
if (value) return value;
|
|
358
|
+
}
|
|
359
|
+
throw new Error(`No bot token found. Set one of ${TOKEN_ENV_CANDIDATES.join(", ")} in .env or use token/env in conflux.config`);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
//#endregion
|
|
363
|
+
//#region src/events/register-handlers.ts
|
|
364
|
+
function createHandlerContext(client, conflux) {
|
|
365
|
+
return {
|
|
366
|
+
client,
|
|
367
|
+
conflux,
|
|
368
|
+
stopAllEvents
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
async function runHandlerBatch(handlers, fluxerArgs, ctx) {
|
|
372
|
+
for (const handler of handlers) {
|
|
373
|
+
if (isEventPipelineHalted()) break;
|
|
374
|
+
await handler(...fluxerArgs, ctx);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function registerConfluxEventHandlers(client, conflux, registry) {
|
|
378
|
+
for (const [eventName, handlers] of registry) client.on(eventName, (...fluxerArgs) => {
|
|
379
|
+
if (isEventPipelineHalted()) return;
|
|
380
|
+
runHandlerBatch(handlers, fluxerArgs, createHandlerContext(client, conflux));
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
//#endregion
|
|
385
|
+
//#region src/loader/entry-client.ts
|
|
386
|
+
function isFluxerClient(value) {
|
|
387
|
+
if (value instanceof Client) return true;
|
|
388
|
+
if (!value || typeof value !== "object") return false;
|
|
389
|
+
const candidate = value;
|
|
390
|
+
return typeof candidate.login === "function" && typeof candidate.on === "function" && typeof candidate.once === "function";
|
|
391
|
+
}
|
|
392
|
+
async function loadEntryModule(entryPath) {
|
|
393
|
+
const entryModule = await import(pathToFileURL(entryPath).href);
|
|
394
|
+
const namedExport = entryModule.client;
|
|
395
|
+
let client = null;
|
|
396
|
+
if (isFluxerClient(namedExport)) client = namedExport;
|
|
397
|
+
else if (isFluxerClient(entryModule.default)) client = entryModule.default;
|
|
398
|
+
if (!client) throw new Error(`Conflux entry must export a @fluxerjs/core Client as named export \`client\` or as default export: ${entryPath}`);
|
|
399
|
+
const configure = entryModule.configure;
|
|
400
|
+
if (configure !== void 0 && typeof configure !== "function") throw new Error(`Conflux entry export \`configure\` must be a function: ${entryPath}`);
|
|
401
|
+
return {
|
|
402
|
+
client,
|
|
403
|
+
configure
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region src/loader/event-handlers.ts
|
|
409
|
+
const FLUXER_EVENT_NAMES = new Set(Object.values(Events));
|
|
410
|
+
function isAnyEventHandler(value) {
|
|
411
|
+
return typeof value === "function";
|
|
412
|
+
}
|
|
413
|
+
function listEventNames(eventsDir) {
|
|
414
|
+
if (!existsSync(eventsDir)) return [];
|
|
415
|
+
return readdirSync(eventsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
416
|
+
}
|
|
417
|
+
function sortedHandlerFiles(eventDir) {
|
|
418
|
+
return readdirSync(eventDir, { withFileTypes: true }).filter((entry) => entry.isFile() && isLoadableModule(entry.name)).map((entry) => entry.name).sort((a, b) => a.localeCompare(b)).map((name) => join(eventDir, name));
|
|
419
|
+
}
|
|
420
|
+
function assertKnownEventName(eventName, eventsDir) {
|
|
421
|
+
if (!FLUXER_EVENT_NAMES.has(eventName)) throw new Error(`Unknown event folder "${eventName}" under ${eventsDir}. Name the folder with a Fluxer event string (for example ready, messageCreate). See Events in @fluxerjs/core.`);
|
|
422
|
+
}
|
|
423
|
+
async function loadEventHandlerRegistry(eventsDir) {
|
|
424
|
+
const registry = /* @__PURE__ */ new Map();
|
|
425
|
+
for (const eventName of listEventNames(eventsDir)) {
|
|
426
|
+
assertKnownEventName(eventName, eventsDir);
|
|
427
|
+
const eventDir = join(eventsDir, eventName);
|
|
428
|
+
const handlers = [];
|
|
429
|
+
for (const filePath of sortedHandlerFiles(eventDir)) {
|
|
430
|
+
const handler = (await import(pathToFileURL(filePath).href)).default;
|
|
431
|
+
if (!isAnyEventHandler(handler)) throw new Error(`Event handler must default-export a function: ${filePath}`);
|
|
432
|
+
handlers.push(handler);
|
|
433
|
+
}
|
|
434
|
+
if (handlers.length > 0) registry.set(eventName, handlers);
|
|
435
|
+
}
|
|
436
|
+
return registry;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
//#endregion
|
|
440
|
+
//#region src/runtime/run-conflux.ts
|
|
441
|
+
async function runConflux(options = {}) {
|
|
442
|
+
const root = options.root ?? process.cwd();
|
|
443
|
+
if (options.production) process.env.NODE_ENV = "production";
|
|
444
|
+
loadProjectEnv(root);
|
|
445
|
+
const loaded = await loadConfluxConfig(root);
|
|
446
|
+
const config = {
|
|
447
|
+
...loaded,
|
|
448
|
+
entry: options.entry ?? loaded.entry,
|
|
449
|
+
eventsDir: options.eventsDir ?? loaded.eventsDir,
|
|
450
|
+
commandsDir: options.commandsDir ?? loaded.commandsDir
|
|
451
|
+
};
|
|
452
|
+
const token = resolveBotToken(config);
|
|
453
|
+
setConfig(config);
|
|
454
|
+
resetEventPipeline();
|
|
455
|
+
if (!existsSync(config.entry)) throw new Error(`Conflux entry not found: ${config.entry}`);
|
|
456
|
+
const { client, configure } = await loadEntryModule(config.entry);
|
|
457
|
+
const conflux = new Conflux({ root: config.root });
|
|
458
|
+
conflux.client = client;
|
|
459
|
+
await configure?.(conflux);
|
|
460
|
+
const commandRegistry = await loadCommandRegistry(config.commandsDir);
|
|
461
|
+
registerConfluxEventHandlers(client, conflux, await loadEventHandlerRegistry(config.eventsDir));
|
|
462
|
+
registerConfluxCommands(client, conflux, commandRegistry, config.commandsDir);
|
|
463
|
+
await client.login(token);
|
|
464
|
+
return conflux;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
//#endregion
|
|
468
|
+
export { Conflux, createConflux, defineConfig, getConfig, runConflux, setConfig, stopAllEvents };
|
|
469
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["out: DiscoveredCommandPaths","after: MessageCommandAfter | undefined","commands: LoadedCommand[]","dirs: string[]","chain: CommandMiddleware[]","client: Client | null","registry: EventHandlerRegistry","handlers: AnyEventHandler[]"],"sources":["../src/core/conflux.ts","../src/loader/directory-modules.ts","../src/commands/discover-paths.ts","../src/commands/validate-registry.ts","../src/commands/load-registry.ts","../src/commands/check-permissions.ts","../src/commands/resolve-middleware.ts","../src/commands/dispatch.ts","../src/commands/register-commands.ts","../src/config/load-config.ts","../src/env/project-env.ts","../src/env/resolve-token.ts","../src/events/register-handlers.ts","../src/loader/entry-client.ts","../src/loader/event-handlers.ts","../src/runtime/run-conflux.ts"],"sourcesContent":["import type { Client } from \"@fluxerjs/core\";\n\nimport type { ConfluxOptions } from \"../config/types.js\";\n\nexport type PrefixResolver = () => string | string[] | Promise<string | string[]>;\n\nexport type ConfluxConfigure = (conflux: Conflux) => void | Promise<void>;\n\nexport class Conflux {\n readonly options: ConfluxOptions;\n client: Client | null = null;\n private prefixResolver: PrefixResolver | null = null;\n\n constructor(options: ConfluxOptions = {}) {\n this.options = options;\n }\n\n setPrefix(resolver: PrefixResolver): void {\n this.prefixResolver = resolver;\n }\n\n async resolvePrefixes(): Promise<string[]> {\n if (!this.prefixResolver) {\n return [\"!\"];\n }\n const result = await this.prefixResolver();\n return Array.isArray(result) ? result : [result];\n }\n}\n\nexport function createConflux(options?: ConfluxOptions): Conflux {\n return new Conflux(options ?? {});\n}\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst MODULE_EXTENSIONS = [\".ts\", \".js\", \".mts\", \".mjs\", \".cjs\"] as const;\n\nexport function isLoadableModule(name: string): boolean {\n return MODULE_EXTENSIONS.some((ext) => name.endsWith(ext));\n}\n\nexport function collectDirectoryModulePaths(dir: string): string[] {\n if (!existsSync(dir)) {\n return [];\n }\n const entries = readdirSync(dir, { withFileTypes: true });\n const paths: string[] = [];\n for (const entry of entries) {\n if (!entry.isFile() || !isLoadableModule(entry.name)) {\n continue;\n }\n paths.push(join(dir, entry.name));\n }\n return paths;\n}\n\nexport function collectEventDirectoryModulePaths(dir: string): string[] {\n if (!existsSync(dir)) {\n return [];\n }\n const paths: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isDirectory()) {\n continue;\n }\n const eventDir = join(dir, entry.name);\n const files = readdirSync(eventDir, { withFileTypes: true })\n .filter((file) => file.isFile() && isLoadableModule(file.name))\n .map((file) => file.name)\n .sort((a, b) => a.localeCompare(b));\n for (const file of files) {\n paths.push(join(eventDir, file));\n }\n }\n return paths;\n}\n\nexport async function loadDirectoryModules(dir: string): Promise<void> {\n if (!existsSync(dir)) {\n return;\n }\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !isLoadableModule(entry.name)) {\n continue;\n }\n await import(pathToFileURL(join(dir, entry.name)).href);\n }\n}\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { isLoadableModule } from \"../loader/directory-modules.js\";\n\nexport type DiscoveredCommandPaths = {\n commandPaths: string[];\n globalMiddlewarePaths: string[];\n directoryMiddlewarePaths: Map<string, string>;\n commandMiddlewarePaths: Map<string, string>;\n};\n\nfunction stem(name: string): string {\n const dot = name.lastIndexOf(\".\");\n return dot === -1 ? name : name.slice(0, dot);\n}\n\nfunction classifyPlusFile(filePath: string, fileName: string, out: DiscoveredCommandPaths): void {\n const base = stem(fileName);\n if (base === \"+global-middleware\") {\n out.globalMiddlewarePaths.push(filePath);\n return;\n }\n if (base === \"+middleware\") {\n out.directoryMiddlewarePaths.set(dirname(filePath), filePath);\n return;\n }\n if (base.startsWith(\"+\") && base.endsWith(\".middleware\")) {\n const commandName = base.slice(1, -\".middleware\".length);\n if (!commandName) {\n throw new Error(`Invalid command middleware file name: ${filePath}`);\n }\n const key = `${dirname(filePath)}\\0${commandName}`;\n out.commandMiddlewarePaths.set(key, filePath);\n return;\n }\n throw new Error(`Unrecognized middleware file: ${filePath}`);\n}\n\nfunction walkDirectory(dir: string, out: DiscoveredCommandPaths): void {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const entryPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n walkDirectory(entryPath, out);\n continue;\n }\n if (!entry.isFile() || !isLoadableModule(entry.name)) {\n continue;\n }\n if (entry.name.startsWith(\"+\")) {\n classifyPlusFile(entryPath, entry.name, out);\n continue;\n }\n out.commandPaths.push(entryPath);\n }\n}\n\nexport function discoverCommandPaths(commandsDir: string): DiscoveredCommandPaths {\n const out: DiscoveredCommandPaths = {\n commandPaths: [],\n globalMiddlewarePaths: [],\n directoryMiddlewarePaths: new Map(),\n commandMiddlewarePaths: new Map(),\n };\n if (!existsSync(commandsDir)) {\n return out;\n }\n walkDirectory(commandsDir, out);\n out.commandPaths.sort((a, b) => a.localeCompare(b));\n return out;\n}\n","import type { DiscoveredCommandPaths } from \"./discover-paths.js\";\nimport type { LoadedCommand } from \"./types.js\";\n\nexport function validateDiscoveredMiddleware(\n discovered: DiscoveredCommandPaths,\n commandsDir: string,\n): void {\n if (discovered.globalMiddlewarePaths.length > 1) {\n throw new Error(\n `Only one +global-middleware module is allowed under ${commandsDir}. Found: ${discovered.globalMiddlewarePaths.join(\", \")}`,\n );\n }\n}\n\nexport function validateCommandTriggers(commands: LoadedCommand[]): void {\n const triggerOwners = new Map<string, string>();\n for (const command of commands) {\n const triggers = [command.data.name, ...(command.data.aliases ?? [])];\n for (const trigger of triggers) {\n if (!trigger) {\n throw new Error(`Command at ${command.filePath} has an empty trigger name or alias`);\n }\n const key = trigger.toLowerCase();\n const existing = triggerOwners.get(key);\n if (existing) {\n throw new Error(\n `Duplicate command trigger \"${trigger}\" in ${command.filePath} (already used by ${existing})`,\n );\n }\n triggerOwners.set(key, command.filePath);\n }\n }\n}\n","import { dirname } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { discoverCommandPaths, type DiscoveredCommandPaths } from \"./discover-paths.js\";\nimport type {\n CommandData,\n CommandMiddleware,\n CommandRegistry,\n LoadedCommand,\n MessageCommand,\n MessageCommandAfter,\n} from \"./types.js\";\nimport { validateCommandTriggers, validateDiscoveredMiddleware } from \"./validate-registry.js\";\n\nfunction isCommandData(value: unknown): value is CommandData {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const data = value as CommandData;\n return typeof data.name === \"string\" && data.name.length > 0;\n}\n\nfunction isMessageCommand(value: unknown): value is MessageCommand {\n return typeof value === \"function\";\n}\n\nfunction readMiddleware(module: Record<string, unknown>): CommandMiddleware {\n const candidate = module.middleware ?? module.default;\n if (!candidate || typeof candidate !== \"object\") {\n throw new Error(\"Middleware module must default-export or export `middleware`\");\n }\n const middleware = candidate as CommandMiddleware;\n if (\n typeof middleware.beforeExecute !== \"function\" ||\n typeof middleware.afterExecute !== \"function\"\n ) {\n throw new Error(\"Middleware must define beforeExecute and afterExecute functions\");\n }\n return middleware;\n}\n\nasync function loadMiddlewareFile(filePath: string): Promise<CommandMiddleware> {\n const module = await import(pathToFileURL(filePath).href);\n try {\n return readMiddleware(module as Record<string, unknown>);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`${message}: ${filePath}`);\n }\n}\n\nasync function loadCommandFile(filePath: string): Promise<LoadedCommand> {\n const module = await import(pathToFileURL(filePath).href);\n const data = module.data;\n if (!isCommandData(data)) {\n throw new Error(`Command module must export \\`data\\` with a non-empty name: ${filePath}`);\n }\n const message = module.message;\n if (!isMessageCommand(message)) {\n throw new Error(`Command module must export \\`message\\` function: ${filePath}`);\n }\n const namedAfter = module.after;\n const after: MessageCommandAfter | undefined =\n typeof namedAfter === \"function\"\n ? namedAfter\n : typeof message.after === \"function\"\n ? message.after\n : undefined;\n return {\n filePath,\n directory: dirname(filePath),\n data,\n message,\n after,\n };\n}\n\nasync function loadMiddlewareMaps(discovered: DiscoveredCommandPaths): Promise<{\n globalMiddleware: CommandMiddleware | null;\n directoryMiddleware: Map<string, CommandMiddleware>;\n commandMiddleware: Map<string, CommandMiddleware>;\n}> {\n const globalMiddleware =\n discovered.globalMiddlewarePaths.length === 1\n ? await loadMiddlewareFile(discovered.globalMiddlewarePaths[0]!)\n : null;\n const directoryMiddleware = new Map<string, CommandMiddleware>();\n for (const [dir, filePath] of discovered.directoryMiddlewarePaths) {\n directoryMiddleware.set(dir, await loadMiddlewareFile(filePath));\n }\n const commandMiddleware = new Map<string, CommandMiddleware>();\n for (const [key, filePath] of discovered.commandMiddlewarePaths) {\n commandMiddleware.set(key, await loadMiddlewareFile(filePath));\n }\n return { globalMiddleware, directoryMiddleware, commandMiddleware };\n}\n\nexport async function loadCommandRegistry(commandsDir: string): Promise<CommandRegistry> {\n const discovered = discoverCommandPaths(commandsDir);\n validateDiscoveredMiddleware(discovered, commandsDir);\n const commands: LoadedCommand[] = [];\n for (const filePath of discovered.commandPaths) {\n commands.push(await loadCommandFile(filePath));\n }\n validateCommandTriggers(commands);\n const middleware = await loadMiddlewareMaps(discovered);\n const byTrigger = new Map<string, LoadedCommand>();\n for (const command of commands) {\n byTrigger.set(command.data.name.toLowerCase(), command);\n for (const alias of command.data.aliases ?? []) {\n byTrigger.set(alias.toLowerCase(), command);\n }\n }\n return {\n commands,\n byTrigger,\n ...middleware,\n };\n}\n","import type { PermissionResolvable } from \"@fluxerjs/core\";\nimport type { Message } from \"@fluxerjs/core\";\nimport { PermissionsBitField } from \"@fluxerjs/core\";\n\nfunction memberHasPermissions(\n permissions: PermissionsBitField | null | undefined,\n required: PermissionResolvable[],\n): boolean {\n if (required.length === 0) {\n return true;\n }\n if (!permissions) {\n return false;\n }\n return permissions.has(required as PermissionResolvable);\n}\n\nexport async function checkCommandPermissions(\n message: Message,\n userPermissions: PermissionResolvable[] | undefined,\n botPermissions: PermissionResolvable[] | undefined,\n): Promise<boolean> {\n const guild = message.guild;\n if (!guild) {\n if (userPermissions?.length || botPermissions?.length) {\n return false;\n }\n return true;\n }\n if (userPermissions?.length) {\n const member = await guild.members.resolve(message.author.id);\n if (!memberHasPermissions(member.permissions, userPermissions)) {\n return false;\n }\n }\n if (botPermissions?.length) {\n const me = guild.members.me ?? (await guild.members.fetchMe().catch(() => null));\n if (!memberHasPermissions(me?.permissions, botPermissions)) {\n return false;\n }\n }\n return true;\n}\n","import { dirname } from \"node:path\";\n\nimport type { CommandMiddleware, CommandRegistry, LoadedCommand } from \"./types.js\";\n\nfunction directoryChain(commandsDir: string, commandDir: string): string[] {\n const dirs: string[] = [];\n let current = commandDir;\n while (true) {\n dirs.unshift(current);\n if (current === commandsDir) {\n break;\n }\n current = dirname(current);\n }\n return dirs;\n}\n\nexport function resolveMiddlewareChain(\n registry: CommandRegistry,\n command: LoadedCommand,\n commandsDir: string,\n): CommandMiddleware[] {\n const chain: CommandMiddleware[] = [];\n if (registry.globalMiddleware) {\n chain.push(registry.globalMiddleware);\n }\n for (const dir of directoryChain(commandsDir, command.directory)) {\n const middleware = registry.directoryMiddleware.get(dir);\n if (middleware) {\n chain.push(middleware);\n }\n }\n const commandKey = `${command.directory}\\0${command.data.name}`;\n const commandMiddleware = registry.commandMiddleware.get(commandKey);\n if (commandMiddleware) {\n chain.push(commandMiddleware);\n }\n return chain;\n}\n","import type { Client, Message } from \"@fluxerjs/core\";\nimport { parsePrefixCommand } from \"@fluxerjs/core\";\n\nimport type { Conflux } from \"../core/conflux.js\";\nimport { checkCommandPermissions } from \"./check-permissions.js\";\nimport { resolveMiddlewareChain } from \"./resolve-middleware.js\";\nimport type { CommandContext, CommandRegistry } from \"./types.js\";\n\nfunction parseWithPrefixes(\n content: string,\n prefixes: string[],\n): { command: string; args: string[] } | null {\n for (const prefix of prefixes) {\n const parsed = parsePrefixCommand(content, prefix);\n if (parsed) {\n return parsed;\n }\n }\n return null;\n}\n\nfunction passesGuildFilter(message: Message, guilds: string[] | undefined): boolean {\n if (!guilds?.length) {\n return true;\n }\n if (!message.guildId) {\n return true;\n }\n return guilds.includes(message.guildId);\n}\n\nfunction createCommandContext(\n message: Message,\n client: Client,\n conflux: Conflux,\n commandName: string,\n args: string[],\n data: CommandContext[\"data\"],\n): CommandContext {\n return {\n message,\n client,\n conflux,\n data,\n commandName,\n args: () => args,\n };\n}\n\nexport async function dispatchPrefixCommand(\n message: Message,\n client: Client,\n conflux: Conflux,\n registry: CommandRegistry,\n commandsDir: string,\n): Promise<void> {\n if (message.author.bot) {\n return;\n }\n const prefixes = await conflux.resolvePrefixes();\n const parsed = parseWithPrefixes(message.content, prefixes);\n if (!parsed) {\n return;\n }\n const command = registry.byTrigger.get(parsed.command.toLowerCase());\n if (!command) {\n return;\n }\n if (!passesGuildFilter(message, command.data.guilds)) {\n return;\n }\n const allowed = await checkCommandPermissions(\n message,\n command.data.userPermissions,\n command.data.botPermissions,\n );\n if (!allowed) {\n return;\n }\n const ctx = createCommandContext(\n message,\n client,\n conflux,\n parsed.command,\n parsed.args,\n command.data,\n );\n const middlewares = resolveMiddlewareChain(registry, command, commandsDir);\n for (const middleware of middlewares) {\n await middleware.beforeExecute(ctx);\n }\n await command.message(ctx);\n if (command.after) {\n await command.after(ctx);\n }\n for (let i = middlewares.length - 1; i >= 0; i -= 1) {\n await middlewares[i]!.afterExecute(ctx);\n }\n}\n","import type { Client } from \"@fluxerjs/core\";\n\nimport type { Conflux } from \"../core/conflux.js\";\nimport { dispatchPrefixCommand } from \"./dispatch.js\";\nimport type { CommandRegistry } from \"./types.js\";\n\nexport function registerConfluxCommands(\n client: Client,\n conflux: Conflux,\n registry: CommandRegistry,\n commandsDir: string,\n): void {\n client.on(\"messageCreate\", (message) => {\n void dispatchPrefixCommand(message, client, conflux, registry, commandsDir);\n });\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { CONFIG_FILENAMES, resolveConfluxConfig } from \"./defaults.js\";\nimport type { ConfluxUserConfig, ResolvedConfluxConfig } from \"./types.js\";\n\nfunction isResolvedConfig(value: unknown): value is ResolvedConfluxConfig {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const record = value as Record<string, unknown>;\n return (\n typeof record.root === \"string\" &&\n typeof record.entry === \"string\" &&\n typeof record.outDir === \"string\"\n );\n}\n\nexport function findConfigPath(root: string): string | null {\n for (const name of CONFIG_FILENAMES) {\n const path = join(root, name);\n if (existsSync(path)) {\n return path;\n }\n }\n return null;\n}\n\nexport async function loadConfluxConfig(root: string): Promise<ResolvedConfluxConfig> {\n const configPath = findConfigPath(root);\n if (!configPath) {\n return resolveConfluxConfig({}, root);\n }\n const imported = await import(pathToFileURL(configPath).href);\n const exported = imported.default ?? imported;\n if (typeof exported === \"function\") {\n const result = await exported();\n if (isResolvedConfig(result)) {\n return result;\n }\n return resolveConfluxConfig(result as ConfluxUserConfig, root);\n }\n if (isResolvedConfig(exported)) {\n return exported;\n }\n return resolveConfluxConfig(exported as ConfluxUserConfig, root);\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nfunction parseEnvLine(line: string): [string, string] | null {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n return null;\n }\n const exportPrefix = trimmed.startsWith(\"export \") ? trimmed.slice(7).trim() : trimmed;\n const eq = exportPrefix.indexOf(\"=\");\n if (eq === -1) {\n return null;\n }\n const key = exportPrefix.slice(0, eq).trim();\n let value = exportPrefix.slice(eq + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n return [key, value];\n}\n\nfunction loadEnvFile(path: string): void {\n if (!existsSync(path)) {\n return;\n }\n const content = readFileSync(path, \"utf8\");\n for (const line of content.split(/\\r?\\n/)) {\n const parsed = parseEnvLine(line);\n if (!parsed) {\n continue;\n }\n const [key, value] = parsed;\n if (process.env[key] === undefined) {\n process.env[key] = value;\n }\n }\n}\n\nexport function loadProjectEnv(root: string): void {\n loadEnvFile(join(root, \".env\"));\n loadEnvFile(join(root, \".env.local\"));\n}\n","import type { ResolvedConfluxConfig } from \"../config/types.js\";\n\nexport const TOKEN_ENV_CANDIDATES = [\"FLUXER_BOT_TOKEN\", \"BOT_TOKEN\", \"TOKEN\"] as const;\n\nexport function resolveBotToken(config: ResolvedConfluxConfig): string {\n if (config.token) {\n return config.token;\n }\n if (config.env) {\n const fromNamed = process.env[config.env];\n if (fromNamed) {\n return fromNamed;\n }\n throw new Error(\n `Bot token env var \"${config.env}\" is not set (check .env or your environment)`,\n );\n }\n for (const name of TOKEN_ENV_CANDIDATES) {\n const value = process.env[name];\n if (value) {\n return value;\n }\n }\n throw new Error(\n `No bot token found. Set one of ${TOKEN_ENV_CANDIDATES.join(\", \")} in .env or use token/env in conflux.config`,\n );\n}\n","import type { Client } from \"@fluxerjs/core\";\n\nimport type { Conflux } from \"../core/conflux.js\";\nimport { isEventPipelineHalted, stopAllEvents } from \"./pipeline.js\";\nimport type { AnyEventHandler, EventHandlerContext, EventHandlerRegistry } from \"./types.js\";\n\nfunction createHandlerContext(client: Client, conflux: Conflux): EventHandlerContext {\n return {\n client,\n conflux,\n stopAllEvents,\n };\n}\n\nasync function runHandlerBatch(\n handlers: AnyEventHandler[],\n fluxerArgs: unknown[],\n ctx: EventHandlerContext,\n): Promise<void> {\n for (const handler of handlers) {\n if (isEventPipelineHalted()) {\n break;\n }\n await handler(...fluxerArgs, ctx);\n }\n}\n\nexport function registerConfluxEventHandlers(\n client: Client,\n conflux: Conflux,\n registry: EventHandlerRegistry,\n): void {\n for (const [eventName, handlers] of registry) {\n client.on(eventName, (...fluxerArgs: unknown[]) => {\n if (isEventPipelineHalted()) {\n return;\n }\n const ctx = createHandlerContext(client, conflux);\n void runHandlerBatch(handlers, fluxerArgs, ctx);\n });\n }\n}\n","import { pathToFileURL } from \"node:url\";\n\nimport { Client } from \"@fluxerjs/core\";\n\nimport type { Conflux } from \"../core/conflux.js\";\n\nfunction isFluxerClient(value: unknown): value is Client {\n if (value instanceof Client) {\n return true;\n }\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const candidate = value as Record<string, unknown>;\n return (\n typeof candidate.login === \"function\" &&\n typeof candidate.on === \"function\" &&\n typeof candidate.once === \"function\"\n );\n}\n\nexport type EntryModule = {\n client: Client;\n configure?: (conflux: Conflux) => void | Promise<void>;\n};\n\nexport async function loadEntryModule(entryPath: string): Promise<EntryModule> {\n const entryModule = await import(pathToFileURL(entryPath).href);\n const namedExport = entryModule.client;\n let client: Client | null = null;\n if (isFluxerClient(namedExport)) {\n client = namedExport;\n } else if (isFluxerClient(entryModule.default)) {\n client = entryModule.default;\n }\n if (!client) {\n throw new Error(\n `Conflux entry must export a @fluxerjs/core Client as named export \\`client\\` or as default export: ${entryPath}`,\n );\n }\n const configure = entryModule.configure;\n if (configure !== undefined && typeof configure !== \"function\") {\n throw new Error(`Conflux entry export \\`configure\\` must be a function: ${entryPath}`);\n }\n return { client, configure };\n}\n\nexport async function loadEntryClient(entryPath: string): Promise<Client> {\n const entry = await loadEntryModule(entryPath);\n return entry.client;\n}\n","import { existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { Events } from \"@fluxerjs/core\";\n\nimport type { FluxerClientEventName } from \"../events/fluxer-events.js\";\nimport type { AnyEventHandler, EventHandlerRegistry } from \"../events/types.js\";\nimport { isLoadableModule } from \"./directory-modules.js\";\n\nconst FLUXER_EVENT_NAMES = new Set<string>(Object.values(Events));\n\nfunction isAnyEventHandler(value: unknown): value is AnyEventHandler {\n return typeof value === \"function\";\n}\n\nfunction listEventNames(eventsDir: string): string[] {\n if (!existsSync(eventsDir)) {\n return [];\n }\n return readdirSync(eventsDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .sort((a, b) => a.localeCompare(b));\n}\n\nfunction sortedHandlerFiles(eventDir: string): string[] {\n return readdirSync(eventDir, { withFileTypes: true })\n .filter((entry) => entry.isFile() && isLoadableModule(entry.name))\n .map((entry) => entry.name)\n .sort((a, b) => a.localeCompare(b))\n .map((name) => join(eventDir, name));\n}\n\nfunction assertKnownEventName(eventName: string, eventsDir: string): void {\n if (!FLUXER_EVENT_NAMES.has(eventName)) {\n throw new Error(\n `Unknown event folder \"${eventName}\" under ${eventsDir}. Name the folder with a Fluxer event string (for example ready, messageCreate). See Events in @fluxerjs/core.`,\n );\n }\n}\n\nexport async function loadEventHandlerRegistry(eventsDir: string): Promise<EventHandlerRegistry> {\n const registry: EventHandlerRegistry = new Map();\n for (const eventName of listEventNames(eventsDir)) {\n assertKnownEventName(eventName, eventsDir);\n const eventDir = join(eventsDir, eventName);\n const handlers: AnyEventHandler[] = [];\n for (const filePath of sortedHandlerFiles(eventDir)) {\n const module = await import(pathToFileURL(filePath).href);\n const handler = module.default;\n if (!isAnyEventHandler(handler)) {\n throw new Error(`Event handler must default-export a function: ${filePath}`);\n }\n handlers.push(handler);\n }\n if (handlers.length > 0) {\n registry.set(eventName as FluxerClientEventName, handlers);\n }\n }\n return registry;\n}\n","import { existsSync } from \"node:fs\";\n\nimport { loadCommandRegistry } from \"../commands/load-registry.js\";\nimport { registerConfluxCommands } from \"../commands/register-commands.js\";\nimport { loadConfluxConfig } from \"../config/load-config.js\";\nimport type { ConfluxOptions } from \"../config/types.js\";\nimport { Conflux } from \"../core/conflux.js\";\nimport { loadProjectEnv, resolveBotToken } from \"../env/index.js\";\nimport { resetEventPipeline } from \"../events/pipeline.js\";\nimport { registerConfluxEventHandlers } from \"../events/register-handlers.js\";\nimport { loadEntryModule, loadEventHandlerRegistry } from \"../loader/index.js\";\nimport { setConfig } from \"./state.js\";\n\nexport type RunConfluxOptions = ConfluxOptions & {\n entry?: string;\n eventsDir?: string;\n commandsDir?: string;\n production?: boolean;\n};\n\nexport async function runConflux(options: RunConfluxOptions = {}): Promise<Conflux> {\n const root = options.root ?? process.cwd();\n if (options.production) {\n process.env.NODE_ENV = \"production\";\n }\n loadProjectEnv(root);\n const loaded = await loadConfluxConfig(root);\n const config = {\n ...loaded,\n entry: options.entry ?? loaded.entry,\n eventsDir: options.eventsDir ?? loaded.eventsDir,\n commandsDir: options.commandsDir ?? loaded.commandsDir,\n };\n const token = resolveBotToken(config);\n setConfig(config);\n resetEventPipeline();\n if (!existsSync(config.entry)) {\n throw new Error(`Conflux entry not found: ${config.entry}`);\n }\n const { client, configure } = await loadEntryModule(config.entry);\n const conflux = new Conflux({ root: config.root });\n conflux.client = client;\n await configure?.(conflux);\n const commandRegistry = await loadCommandRegistry(config.commandsDir);\n const eventHandlers = await loadEventHandlerRegistry(config.eventsDir);\n registerConfluxEventHandlers(client, conflux, eventHandlers);\n registerConfluxCommands(client, conflux, commandRegistry, config.commandsDir);\n await client.login(token);\n return conflux;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
//#region src/cli/parse-args.ts
|
|
4
|
+
function parseArgs(argv) {
|
|
5
|
+
let command = null;
|
|
6
|
+
let root = null;
|
|
7
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
8
|
+
const arg = argv[i];
|
|
9
|
+
if (arg === "--root" && argv[i + 1]) {
|
|
10
|
+
root = argv[i + 1] ?? null;
|
|
11
|
+
i += 1;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (!arg.startsWith("-") && !command) command = arg;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
command,
|
|
18
|
+
root
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const CLI_USAGE = `Usage: conflux <command> [--root <dir>]
|
|
22
|
+
|
|
23
|
+
Commands:
|
|
24
|
+
dev Watch and run the bot in development
|
|
25
|
+
build Production build to outDir
|
|
26
|
+
start Run the bot in production
|
|
27
|
+
run Alias for dev`;
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
Object.defineProperty(exports, 'CLI_USAGE', {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return CLI_USAGE;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, 'parseArgs', {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return parseArgs;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=parse-args-73A1_Lee.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-args-73A1_Lee.cjs","names":["command: string | null","root: string | null"],"sources":["../src/cli/parse-args.ts"],"sourcesContent":["export type ParsedCliArgs = {\n command: string | null;\n root: string | null;\n};\n\nexport function parseArgs(argv: string[]): ParsedCliArgs {\n let command: string | null = null;\n let root: string | null = null;\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (arg === \"--root\" && argv[i + 1]) {\n root = argv[i + 1] ?? null;\n i += 1;\n continue;\n }\n if (!arg.startsWith(\"-\") && !command) {\n command = arg;\n }\n }\n return { command, root };\n}\n\nexport const CLI_USAGE = `Usage: conflux <command> [--root <dir>]\n\nCommands:\n dev Watch and run the bot in development\n build Production build to outDir\n start Run the bot in production\n run Alias for dev`;\n"],"mappings":";;;AAKA,SAAgB,UAAU,MAA+B;CACvD,IAAIA,UAAyB;CAC7B,IAAIC,OAAsB;AAC1B,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;EACvC,MAAM,MAAM,KAAK;AACjB,MAAI,QAAQ,YAAY,KAAK,IAAI,IAAI;AACnC,UAAO,KAAK,IAAI,MAAM;AACtB,QAAK;AACL;;AAEF,MAAI,CAAC,IAAI,WAAW,IAAI,IAAI,CAAC,QAC3B,WAAU;;AAGd,QAAO;EAAE;EAAS;EAAM;;AAG1B,MAAa,YAAY"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
//#region src/cli/parse-args.ts
|
|
3
|
+
function parseArgs(argv) {
|
|
4
|
+
let command = null;
|
|
5
|
+
let root = null;
|
|
6
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
7
|
+
const arg = argv[i];
|
|
8
|
+
if (arg === "--root" && argv[i + 1]) {
|
|
9
|
+
root = argv[i + 1] ?? null;
|
|
10
|
+
i += 1;
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (!arg.startsWith("-") && !command) command = arg;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
command,
|
|
17
|
+
root
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const CLI_USAGE = `Usage: conflux <command> [--root <dir>]
|
|
21
|
+
|
|
22
|
+
Commands:
|
|
23
|
+
dev Watch and run the bot in development
|
|
24
|
+
build Production build to outDir
|
|
25
|
+
start Run the bot in production
|
|
26
|
+
run Alias for dev`;
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { parseArgs as n, CLI_USAGE as t };
|
|
30
|
+
//# sourceMappingURL=parse-args-fMvnTEQ2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-args-fMvnTEQ2.js","names":["command: string | null","root: string | null"],"sources":["../src/cli/parse-args.ts"],"sourcesContent":["export type ParsedCliArgs = {\n command: string | null;\n root: string | null;\n};\n\nexport function parseArgs(argv: string[]): ParsedCliArgs {\n let command: string | null = null;\n let root: string | null = null;\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (arg === \"--root\" && argv[i + 1]) {\n root = argv[i + 1] ?? null;\n i += 1;\n continue;\n }\n if (!arg.startsWith(\"-\") && !command) {\n command = arg;\n }\n }\n return { command, root };\n}\n\nexport const CLI_USAGE = `Usage: conflux <command> [--root <dir>]\n\nCommands:\n dev Watch and run the bot in development\n build Production build to outDir\n start Run the bot in production\n run Alias for dev`;\n"],"mappings":";;AAKA,SAAgB,UAAU,MAA+B;CACvD,IAAIA,UAAyB;CAC7B,IAAIC,OAAsB;AAC1B,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;EACvC,MAAM,MAAM,KAAK;AACjB,MAAI,QAAQ,YAAY,KAAK,IAAI,IAAI;AACnC,UAAO,KAAK,IAAI,MAAM;AACtB,QAAK;AACL;;AAEF,MAAI,CAAC,IAAI,WAAW,IAAI,IAAI,CAAC,QAC3B,WAAU;;AAGd,QAAO;EAAE;EAAS;EAAM;;AAG1B,MAAa,YAAY"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/events/pipeline.ts
|
|
3
|
+
let eventsHalted = false;
|
|
4
|
+
function resetEventPipeline() {
|
|
5
|
+
eventsHalted = false;
|
|
6
|
+
}
|
|
7
|
+
function stopAllEvents() {
|
|
8
|
+
eventsHalted = true;
|
|
9
|
+
}
|
|
10
|
+
function isEventPipelineHalted() {
|
|
11
|
+
return eventsHalted;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
Object.defineProperty(exports, 'isEventPipelineHalted', {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () {
|
|
18
|
+
return isEventPipelineHalted;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(exports, 'resetEventPipeline', {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () {
|
|
24
|
+
return resetEventPipeline;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports, 'stopAllEvents', {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () {
|
|
30
|
+
return stopAllEvents;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=pipeline-B7aJQrzJ.cjs.map
|