@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-B7aJQrzJ.cjs","names":[],"sources":["../src/events/pipeline.ts"],"sourcesContent":["let eventsHalted = false;\n\nexport function resetEventPipeline(): void {\n eventsHalted = false;\n}\n\nexport function stopAllEvents(): void {\n eventsHalted = true;\n}\n\nexport function isEventPipelineHalted(): boolean {\n return eventsHalted;\n}\n"],"mappings":";;AAAA,IAAI,eAAe;AAEnB,SAAgB,qBAA2B;AACzC,gBAAe;;AAGjB,SAAgB,gBAAsB;AACpC,gBAAe;;AAGjB,SAAgB,wBAAiC;AAC/C,QAAO"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/events/pipeline.ts
|
|
2
|
+
let eventsHalted = false;
|
|
3
|
+
function resetEventPipeline() {
|
|
4
|
+
eventsHalted = false;
|
|
5
|
+
}
|
|
6
|
+
function stopAllEvents() {
|
|
7
|
+
eventsHalted = true;
|
|
8
|
+
}
|
|
9
|
+
function isEventPipelineHalted() {
|
|
10
|
+
return eventsHalted;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { resetEventPipeline as n, stopAllEvents as r, isEventPipelineHalted as t };
|
|
15
|
+
//# sourceMappingURL=pipeline-BkDu0cvJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-BkDu0cvJ.js","names":[],"sources":["../src/events/pipeline.ts"],"sourcesContent":["let eventsHalted = false;\n\nexport function resetEventPipeline(): void {\n eventsHalted = false;\n}\n\nexport function stopAllEvents(): void {\n eventsHalted = true;\n}\n\nexport function isEventPipelineHalted(): boolean {\n return eventsHalted;\n}\n"],"mappings":";AAAA,IAAI,eAAe;AAEnB,SAAgB,qBAA2B;AACzC,gBAAe;;AAGjB,SAAgB,gBAAsB;AACpC,gBAAe;;AAGjB,SAAgB,wBAAiC;AAC/C,QAAO"}
|
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
//#region rolldown:runtime
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
let node_path = require("node:path");
|
|
26
|
+
node_path = __toESM(node_path);
|
|
27
|
+
let node_url = require("node:url");
|
|
28
|
+
node_url = __toESM(node_url);
|
|
29
|
+
let node_fs = require("node:fs");
|
|
30
|
+
node_fs = __toESM(node_fs);
|
|
31
|
+
let __fluxerjs_core = require("@fluxerjs/core");
|
|
32
|
+
__fluxerjs_core = __toESM(__fluxerjs_core);
|
|
33
|
+
|
|
34
|
+
//#region src/loader/directory-modules.ts
|
|
35
|
+
const MODULE_EXTENSIONS = [
|
|
36
|
+
".ts",
|
|
37
|
+
".js",
|
|
38
|
+
".mts",
|
|
39
|
+
".mjs",
|
|
40
|
+
".cjs"
|
|
41
|
+
];
|
|
42
|
+
function isLoadableModule(name) {
|
|
43
|
+
return MODULE_EXTENSIONS.some((ext) => name.endsWith(ext));
|
|
44
|
+
}
|
|
45
|
+
function collectEventDirectoryModulePaths(dir) {
|
|
46
|
+
if (!(0, node_fs.existsSync)(dir)) return [];
|
|
47
|
+
const paths = [];
|
|
48
|
+
for (const entry of (0, node_fs.readdirSync)(dir, { withFileTypes: true })) {
|
|
49
|
+
if (!entry.isDirectory()) continue;
|
|
50
|
+
const eventDir = (0, node_path.join)(dir, entry.name);
|
|
51
|
+
const files = (0, node_fs.readdirSync)(eventDir, { withFileTypes: true }).filter((file) => file.isFile() && isLoadableModule(file.name)).map((file) => file.name).sort((a, b) => a.localeCompare(b));
|
|
52
|
+
for (const file of files) paths.push((0, node_path.join)(eventDir, file));
|
|
53
|
+
}
|
|
54
|
+
return paths;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/commands/discover-paths.ts
|
|
59
|
+
function stem(name) {
|
|
60
|
+
const dot = name.lastIndexOf(".");
|
|
61
|
+
return dot === -1 ? name : name.slice(0, dot);
|
|
62
|
+
}
|
|
63
|
+
function classifyPlusFile(filePath, fileName, out) {
|
|
64
|
+
const base = stem(fileName);
|
|
65
|
+
if (base === "+global-middleware") {
|
|
66
|
+
out.globalMiddlewarePaths.push(filePath);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (base === "+middleware") {
|
|
70
|
+
out.directoryMiddlewarePaths.set((0, node_path.dirname)(filePath), filePath);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (base.startsWith("+") && base.endsWith(".middleware")) {
|
|
74
|
+
const commandName = base.slice(1, -11);
|
|
75
|
+
if (!commandName) throw new Error(`Invalid command middleware file name: ${filePath}`);
|
|
76
|
+
const key = `${(0, node_path.dirname)(filePath)}\0${commandName}`;
|
|
77
|
+
out.commandMiddlewarePaths.set(key, filePath);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
throw new Error(`Unrecognized middleware file: ${filePath}`);
|
|
81
|
+
}
|
|
82
|
+
function walkDirectory(dir, out) {
|
|
83
|
+
const entries = (0, node_fs.readdirSync)(dir, { withFileTypes: true });
|
|
84
|
+
for (const entry of entries) {
|
|
85
|
+
const entryPath = (0, node_path.join)(dir, entry.name);
|
|
86
|
+
if (entry.isDirectory()) {
|
|
87
|
+
walkDirectory(entryPath, out);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (!entry.isFile() || !isLoadableModule(entry.name)) continue;
|
|
91
|
+
if (entry.name.startsWith("+")) {
|
|
92
|
+
classifyPlusFile(entryPath, entry.name, out);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
out.commandPaths.push(entryPath);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function discoverCommandPaths(commandsDir) {
|
|
99
|
+
const out = {
|
|
100
|
+
commandPaths: [],
|
|
101
|
+
globalMiddlewarePaths: [],
|
|
102
|
+
directoryMiddlewarePaths: /* @__PURE__ */ new Map(),
|
|
103
|
+
commandMiddlewarePaths: /* @__PURE__ */ new Map()
|
|
104
|
+
};
|
|
105
|
+
if (!(0, node_fs.existsSync)(commandsDir)) return out;
|
|
106
|
+
walkDirectory(commandsDir, out);
|
|
107
|
+
out.commandPaths.sort((a, b) => a.localeCompare(b));
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/commands/validate-registry.ts
|
|
113
|
+
function validateDiscoveredMiddleware(discovered, commandsDir) {
|
|
114
|
+
if (discovered.globalMiddlewarePaths.length > 1) throw new Error(`Only one +global-middleware module is allowed under ${commandsDir}. Found: ${discovered.globalMiddlewarePaths.join(", ")}`);
|
|
115
|
+
}
|
|
116
|
+
function validateCommandTriggers(commands) {
|
|
117
|
+
const triggerOwners = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const command of commands) {
|
|
119
|
+
const triggers = [command.data.name, ...command.data.aliases ?? []];
|
|
120
|
+
for (const trigger of triggers) {
|
|
121
|
+
if (!trigger) throw new Error(`Command at ${command.filePath} has an empty trigger name or alias`);
|
|
122
|
+
const key = trigger.toLowerCase();
|
|
123
|
+
const existing = triggerOwners.get(key);
|
|
124
|
+
if (existing) throw new Error(`Duplicate command trigger "${trigger}" in ${command.filePath} (already used by ${existing})`);
|
|
125
|
+
triggerOwners.set(key, command.filePath);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/commands/load-registry.ts
|
|
132
|
+
function isCommandData(value) {
|
|
133
|
+
if (!value || typeof value !== "object") return false;
|
|
134
|
+
const data = value;
|
|
135
|
+
return typeof data.name === "string" && data.name.length > 0;
|
|
136
|
+
}
|
|
137
|
+
function isMessageCommand(value) {
|
|
138
|
+
return typeof value === "function";
|
|
139
|
+
}
|
|
140
|
+
function readMiddleware(module$1) {
|
|
141
|
+
const candidate = module$1.middleware ?? module$1.default;
|
|
142
|
+
if (!candidate || typeof candidate !== "object") throw new Error("Middleware module must default-export or export `middleware`");
|
|
143
|
+
const middleware = candidate;
|
|
144
|
+
if (typeof middleware.beforeExecute !== "function" || typeof middleware.afterExecute !== "function") throw new Error("Middleware must define beforeExecute and afterExecute functions");
|
|
145
|
+
return middleware;
|
|
146
|
+
}
|
|
147
|
+
async function loadMiddlewareFile(filePath) {
|
|
148
|
+
const module$1 = await import((0, node_url.pathToFileURL)(filePath).href);
|
|
149
|
+
try {
|
|
150
|
+
return readMiddleware(module$1);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
153
|
+
throw new Error(`${message}: ${filePath}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function loadCommandFile(filePath) {
|
|
157
|
+
const module$1 = await import((0, node_url.pathToFileURL)(filePath).href);
|
|
158
|
+
const data = module$1.data;
|
|
159
|
+
if (!isCommandData(data)) throw new Error(`Command module must export \`data\` with a non-empty name: ${filePath}`);
|
|
160
|
+
const message = module$1.message;
|
|
161
|
+
if (!isMessageCommand(message)) throw new Error(`Command module must export \`message\` function: ${filePath}`);
|
|
162
|
+
const namedAfter = module$1.after;
|
|
163
|
+
const after = typeof namedAfter === "function" ? namedAfter : typeof message.after === "function" ? message.after : void 0;
|
|
164
|
+
return {
|
|
165
|
+
filePath,
|
|
166
|
+
directory: (0, node_path.dirname)(filePath),
|
|
167
|
+
data,
|
|
168
|
+
message,
|
|
169
|
+
after
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
async function loadMiddlewareMaps(discovered) {
|
|
173
|
+
const globalMiddleware = discovered.globalMiddlewarePaths.length === 1 ? await loadMiddlewareFile(discovered.globalMiddlewarePaths[0]) : null;
|
|
174
|
+
const directoryMiddleware = /* @__PURE__ */ new Map();
|
|
175
|
+
for (const [dir, filePath] of discovered.directoryMiddlewarePaths) directoryMiddleware.set(dir, await loadMiddlewareFile(filePath));
|
|
176
|
+
const commandMiddleware = /* @__PURE__ */ new Map();
|
|
177
|
+
for (const [key, filePath] of discovered.commandMiddlewarePaths) commandMiddleware.set(key, await loadMiddlewareFile(filePath));
|
|
178
|
+
return {
|
|
179
|
+
globalMiddleware,
|
|
180
|
+
directoryMiddleware,
|
|
181
|
+
commandMiddleware
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async function loadCommandRegistry(commandsDir) {
|
|
185
|
+
const discovered = discoverCommandPaths(commandsDir);
|
|
186
|
+
validateDiscoveredMiddleware(discovered, commandsDir);
|
|
187
|
+
const commands = [];
|
|
188
|
+
for (const filePath of discovered.commandPaths) commands.push(await loadCommandFile(filePath));
|
|
189
|
+
validateCommandTriggers(commands);
|
|
190
|
+
const middleware = await loadMiddlewareMaps(discovered);
|
|
191
|
+
const byTrigger = /* @__PURE__ */ new Map();
|
|
192
|
+
for (const command of commands) {
|
|
193
|
+
byTrigger.set(command.data.name.toLowerCase(), command);
|
|
194
|
+
for (const alias of command.data.aliases ?? []) byTrigger.set(alias.toLowerCase(), command);
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
commands,
|
|
198
|
+
byTrigger,
|
|
199
|
+
...middleware
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region src/config/defaults.ts
|
|
205
|
+
const CONFIG_FILENAMES = [
|
|
206
|
+
"conflux.config.ts",
|
|
207
|
+
"conflux.config.js",
|
|
208
|
+
"conflux.config.mjs",
|
|
209
|
+
"conflux.config.cjs",
|
|
210
|
+
"conflux.config.mts",
|
|
211
|
+
"conflux.config.cts"
|
|
212
|
+
];
|
|
213
|
+
function resolveConfluxConfig(config, root) {
|
|
214
|
+
const resolvedRoot = (0, node_path.resolve)(root, config.root ?? ".");
|
|
215
|
+
return {
|
|
216
|
+
root: resolvedRoot,
|
|
217
|
+
outDir: (0, node_path.resolve)(resolvedRoot, config.outDir ?? "dist"),
|
|
218
|
+
entry: (0, node_path.resolve)(resolvedRoot, config.entry ?? "src/index.ts"),
|
|
219
|
+
commandsDir: (0, node_path.resolve)(resolvedRoot, config.commandsDir ?? "src/commands"),
|
|
220
|
+
eventsDir: (0, node_path.resolve)(resolvedRoot, config.eventsDir ?? "src/events"),
|
|
221
|
+
token: config.token,
|
|
222
|
+
env: config.env
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/config/load-config.ts
|
|
228
|
+
function isResolvedConfig(value) {
|
|
229
|
+
if (!value || typeof value !== "object") return false;
|
|
230
|
+
const record = value;
|
|
231
|
+
return typeof record.root === "string" && typeof record.entry === "string" && typeof record.outDir === "string";
|
|
232
|
+
}
|
|
233
|
+
function findConfigPath(root) {
|
|
234
|
+
for (const name of CONFIG_FILENAMES) {
|
|
235
|
+
const path = (0, node_path.join)(root, name);
|
|
236
|
+
if ((0, node_fs.existsSync)(path)) return path;
|
|
237
|
+
}
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
async function loadConfluxConfig(root) {
|
|
241
|
+
const configPath = findConfigPath(root);
|
|
242
|
+
if (!configPath) return resolveConfluxConfig({}, root);
|
|
243
|
+
const imported = await import((0, node_url.pathToFileURL)(configPath).href);
|
|
244
|
+
const exported = imported.default ?? imported;
|
|
245
|
+
if (typeof exported === "function") {
|
|
246
|
+
const result = await exported();
|
|
247
|
+
if (isResolvedConfig(result)) return result;
|
|
248
|
+
return resolveConfluxConfig(result, root);
|
|
249
|
+
}
|
|
250
|
+
if (isResolvedConfig(exported)) return exported;
|
|
251
|
+
return resolveConfluxConfig(exported, root);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/commands/check-permissions.ts
|
|
256
|
+
function memberHasPermissions(permissions, required) {
|
|
257
|
+
if (required.length === 0) return true;
|
|
258
|
+
if (!permissions) return false;
|
|
259
|
+
return permissions.has(required);
|
|
260
|
+
}
|
|
261
|
+
async function checkCommandPermissions(message, userPermissions, botPermissions) {
|
|
262
|
+
const guild = message.guild;
|
|
263
|
+
if (!guild) {
|
|
264
|
+
if (userPermissions?.length || botPermissions?.length) return false;
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
if (userPermissions?.length) {
|
|
268
|
+
if (!memberHasPermissions((await guild.members.resolve(message.author.id)).permissions, userPermissions)) return false;
|
|
269
|
+
}
|
|
270
|
+
if (botPermissions?.length) {
|
|
271
|
+
if (!memberHasPermissions((guild.members.me ?? await guild.members.fetchMe().catch(() => null))?.permissions, botPermissions)) return false;
|
|
272
|
+
}
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region src/commands/resolve-middleware.ts
|
|
278
|
+
function directoryChain(commandsDir, commandDir) {
|
|
279
|
+
const dirs = [];
|
|
280
|
+
let current = commandDir;
|
|
281
|
+
while (true) {
|
|
282
|
+
dirs.unshift(current);
|
|
283
|
+
if (current === commandsDir) break;
|
|
284
|
+
current = (0, node_path.dirname)(current);
|
|
285
|
+
}
|
|
286
|
+
return dirs;
|
|
287
|
+
}
|
|
288
|
+
function resolveMiddlewareChain(registry, command, commandsDir) {
|
|
289
|
+
const chain = [];
|
|
290
|
+
if (registry.globalMiddleware) chain.push(registry.globalMiddleware);
|
|
291
|
+
for (const dir of directoryChain(commandsDir, command.directory)) {
|
|
292
|
+
const middleware = registry.directoryMiddleware.get(dir);
|
|
293
|
+
if (middleware) chain.push(middleware);
|
|
294
|
+
}
|
|
295
|
+
const commandKey = `${command.directory}\0${command.data.name}`;
|
|
296
|
+
const commandMiddleware = registry.commandMiddleware.get(commandKey);
|
|
297
|
+
if (commandMiddleware) chain.push(commandMiddleware);
|
|
298
|
+
return chain;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/commands/dispatch.ts
|
|
303
|
+
function parseWithPrefixes(content, prefixes) {
|
|
304
|
+
for (const prefix of prefixes) {
|
|
305
|
+
const parsed = (0, __fluxerjs_core.parsePrefixCommand)(content, prefix);
|
|
306
|
+
if (parsed) return parsed;
|
|
307
|
+
}
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
function passesGuildFilter(message, guilds) {
|
|
311
|
+
if (!guilds?.length) return true;
|
|
312
|
+
if (!message.guildId) return true;
|
|
313
|
+
return guilds.includes(message.guildId);
|
|
314
|
+
}
|
|
315
|
+
function createCommandContext(message, client, conflux, commandName, args, data) {
|
|
316
|
+
return {
|
|
317
|
+
message,
|
|
318
|
+
client,
|
|
319
|
+
conflux,
|
|
320
|
+
data,
|
|
321
|
+
commandName,
|
|
322
|
+
args: () => args
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
async function dispatchPrefixCommand(message, client, conflux, registry, commandsDir) {
|
|
326
|
+
if (message.author.bot) return;
|
|
327
|
+
const prefixes = await conflux.resolvePrefixes();
|
|
328
|
+
const parsed = parseWithPrefixes(message.content, prefixes);
|
|
329
|
+
if (!parsed) return;
|
|
330
|
+
const command = registry.byTrigger.get(parsed.command.toLowerCase());
|
|
331
|
+
if (!command) return;
|
|
332
|
+
if (!passesGuildFilter(message, command.data.guilds)) return;
|
|
333
|
+
if (!await checkCommandPermissions(message, command.data.userPermissions, command.data.botPermissions)) return;
|
|
334
|
+
const ctx = createCommandContext(message, client, conflux, parsed.command, parsed.args, command.data);
|
|
335
|
+
const middlewares = resolveMiddlewareChain(registry, command, commandsDir);
|
|
336
|
+
for (const middleware of middlewares) await middleware.beforeExecute(ctx);
|
|
337
|
+
await command.message(ctx);
|
|
338
|
+
if (command.after) await command.after(ctx);
|
|
339
|
+
for (let i = middlewares.length - 1; i >= 0; i -= 1) await middlewares[i].afterExecute(ctx);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region src/commands/register-commands.ts
|
|
344
|
+
function registerConfluxCommands(client, conflux, registry, commandsDir) {
|
|
345
|
+
client.on("messageCreate", (message) => {
|
|
346
|
+
dispatchPrefixCommand(message, client, conflux, registry, commandsDir);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
//#endregion
|
|
351
|
+
//#region src/core/conflux.ts
|
|
352
|
+
var Conflux = class {
|
|
353
|
+
options;
|
|
354
|
+
client = null;
|
|
355
|
+
prefixResolver = null;
|
|
356
|
+
constructor(options = {}) {
|
|
357
|
+
this.options = options;
|
|
358
|
+
}
|
|
359
|
+
setPrefix(resolver) {
|
|
360
|
+
this.prefixResolver = resolver;
|
|
361
|
+
}
|
|
362
|
+
async resolvePrefixes() {
|
|
363
|
+
if (!this.prefixResolver) return ["!"];
|
|
364
|
+
const result = await this.prefixResolver();
|
|
365
|
+
return Array.isArray(result) ? result : [result];
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
//#endregion
|
|
370
|
+
//#region src/env/project-env.ts
|
|
371
|
+
function parseEnvLine(line) {
|
|
372
|
+
const trimmed = line.trim();
|
|
373
|
+
if (!trimmed || trimmed.startsWith("#")) return null;
|
|
374
|
+
const exportPrefix = trimmed.startsWith("export ") ? trimmed.slice(7).trim() : trimmed;
|
|
375
|
+
const eq = exportPrefix.indexOf("=");
|
|
376
|
+
if (eq === -1) return null;
|
|
377
|
+
const key = exportPrefix.slice(0, eq).trim();
|
|
378
|
+
let value = exportPrefix.slice(eq + 1).trim();
|
|
379
|
+
if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
|
|
380
|
+
return [key, value];
|
|
381
|
+
}
|
|
382
|
+
function loadEnvFile(path) {
|
|
383
|
+
if (!(0, node_fs.existsSync)(path)) return;
|
|
384
|
+
const content = (0, node_fs.readFileSync)(path, "utf8");
|
|
385
|
+
for (const line of content.split(/\r?\n/)) {
|
|
386
|
+
const parsed = parseEnvLine(line);
|
|
387
|
+
if (!parsed) continue;
|
|
388
|
+
const [key, value] = parsed;
|
|
389
|
+
if (process.env[key] === void 0) process.env[key] = value;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function loadProjectEnv(root) {
|
|
393
|
+
loadEnvFile((0, node_path.join)(root, ".env"));
|
|
394
|
+
loadEnvFile((0, node_path.join)(root, ".env.local"));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/env/resolve-token.ts
|
|
399
|
+
const TOKEN_ENV_CANDIDATES = [
|
|
400
|
+
"FLUXER_BOT_TOKEN",
|
|
401
|
+
"BOT_TOKEN",
|
|
402
|
+
"TOKEN"
|
|
403
|
+
];
|
|
404
|
+
function resolveBotToken(config) {
|
|
405
|
+
if (config.token) return config.token;
|
|
406
|
+
if (config.env) {
|
|
407
|
+
const fromNamed = process.env[config.env];
|
|
408
|
+
if (fromNamed) return fromNamed;
|
|
409
|
+
throw new Error(`Bot token env var "${config.env}" is not set (check .env or your environment)`);
|
|
410
|
+
}
|
|
411
|
+
for (const name of TOKEN_ENV_CANDIDATES) {
|
|
412
|
+
const value = process.env[name];
|
|
413
|
+
if (value) return value;
|
|
414
|
+
}
|
|
415
|
+
throw new Error(`No bot token found. Set one of ${TOKEN_ENV_CANDIDATES.join(", ")} in .env or use token/env in conflux.config`);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
//#endregion
|
|
419
|
+
//#region src/events/pipeline.ts
|
|
420
|
+
let eventsHalted = false;
|
|
421
|
+
function resetEventPipeline() {
|
|
422
|
+
eventsHalted = false;
|
|
423
|
+
}
|
|
424
|
+
function stopAllEvents() {
|
|
425
|
+
eventsHalted = true;
|
|
426
|
+
}
|
|
427
|
+
function isEventPipelineHalted() {
|
|
428
|
+
return eventsHalted;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
//#endregion
|
|
432
|
+
//#region src/events/register-handlers.ts
|
|
433
|
+
function createHandlerContext(client, conflux) {
|
|
434
|
+
return {
|
|
435
|
+
client,
|
|
436
|
+
conflux,
|
|
437
|
+
stopAllEvents
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
async function runHandlerBatch(handlers, fluxerArgs, ctx) {
|
|
441
|
+
for (const handler of handlers) {
|
|
442
|
+
if (isEventPipelineHalted()) break;
|
|
443
|
+
await handler(...fluxerArgs, ctx);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function registerConfluxEventHandlers(client, conflux, registry) {
|
|
447
|
+
for (const [eventName, handlers] of registry) client.on(eventName, (...fluxerArgs) => {
|
|
448
|
+
if (isEventPipelineHalted()) return;
|
|
449
|
+
runHandlerBatch(handlers, fluxerArgs, createHandlerContext(client, conflux));
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
//#endregion
|
|
454
|
+
//#region src/loader/entry-client.ts
|
|
455
|
+
function isFluxerClient(value) {
|
|
456
|
+
if (value instanceof __fluxerjs_core.Client) return true;
|
|
457
|
+
if (!value || typeof value !== "object") return false;
|
|
458
|
+
const candidate = value;
|
|
459
|
+
return typeof candidate.login === "function" && typeof candidate.on === "function" && typeof candidate.once === "function";
|
|
460
|
+
}
|
|
461
|
+
async function loadEntryModule(entryPath) {
|
|
462
|
+
const entryModule = await import((0, node_url.pathToFileURL)(entryPath).href);
|
|
463
|
+
const namedExport = entryModule.client;
|
|
464
|
+
let client = null;
|
|
465
|
+
if (isFluxerClient(namedExport)) client = namedExport;
|
|
466
|
+
else if (isFluxerClient(entryModule.default)) client = entryModule.default;
|
|
467
|
+
if (!client) throw new Error(`Conflux entry must export a @fluxerjs/core Client as named export \`client\` or as default export: ${entryPath}`);
|
|
468
|
+
const configure = entryModule.configure;
|
|
469
|
+
if (configure !== void 0 && typeof configure !== "function") throw new Error(`Conflux entry export \`configure\` must be a function: ${entryPath}`);
|
|
470
|
+
return {
|
|
471
|
+
client,
|
|
472
|
+
configure
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
//#endregion
|
|
477
|
+
//#region src/loader/event-handlers.ts
|
|
478
|
+
const FLUXER_EVENT_NAMES = new Set(Object.values(__fluxerjs_core.Events));
|
|
479
|
+
function isAnyEventHandler(value) {
|
|
480
|
+
return typeof value === "function";
|
|
481
|
+
}
|
|
482
|
+
function listEventNames(eventsDir) {
|
|
483
|
+
if (!(0, node_fs.existsSync)(eventsDir)) return [];
|
|
484
|
+
return (0, node_fs.readdirSync)(eventsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
485
|
+
}
|
|
486
|
+
function sortedHandlerFiles(eventDir) {
|
|
487
|
+
return (0, node_fs.readdirSync)(eventDir, { withFileTypes: true }).filter((entry) => entry.isFile() && isLoadableModule(entry.name)).map((entry) => entry.name).sort((a, b) => a.localeCompare(b)).map((name) => (0, node_path.join)(eventDir, name));
|
|
488
|
+
}
|
|
489
|
+
function assertKnownEventName(eventName, eventsDir) {
|
|
490
|
+
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.`);
|
|
491
|
+
}
|
|
492
|
+
async function loadEventHandlerRegistry(eventsDir) {
|
|
493
|
+
const registry = /* @__PURE__ */ new Map();
|
|
494
|
+
for (const eventName of listEventNames(eventsDir)) {
|
|
495
|
+
assertKnownEventName(eventName, eventsDir);
|
|
496
|
+
const eventDir = (0, node_path.join)(eventsDir, eventName);
|
|
497
|
+
const handlers = [];
|
|
498
|
+
for (const filePath of sortedHandlerFiles(eventDir)) {
|
|
499
|
+
const handler = (await import((0, node_url.pathToFileURL)(filePath).href)).default;
|
|
500
|
+
if (!isAnyEventHandler(handler)) throw new Error(`Event handler must default-export a function: ${filePath}`);
|
|
501
|
+
handlers.push(handler);
|
|
502
|
+
}
|
|
503
|
+
if (handlers.length > 0) registry.set(eventName, handlers);
|
|
504
|
+
}
|
|
505
|
+
return registry;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
//#endregion
|
|
509
|
+
//#region src/runtime/state.ts
|
|
510
|
+
const state = { config: null };
|
|
511
|
+
function setConfig(config) {
|
|
512
|
+
state.config = config;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
//#endregion
|
|
516
|
+
//#region src/runtime/run-conflux.ts
|
|
517
|
+
async function runConflux(options = {}) {
|
|
518
|
+
const root = options.root ?? process.cwd();
|
|
519
|
+
if (options.production) process.env.NODE_ENV = "production";
|
|
520
|
+
loadProjectEnv(root);
|
|
521
|
+
const loaded = await loadConfluxConfig(root);
|
|
522
|
+
const config = {
|
|
523
|
+
...loaded,
|
|
524
|
+
entry: options.entry ?? loaded.entry,
|
|
525
|
+
eventsDir: options.eventsDir ?? loaded.eventsDir,
|
|
526
|
+
commandsDir: options.commandsDir ?? loaded.commandsDir
|
|
527
|
+
};
|
|
528
|
+
const token = resolveBotToken(config);
|
|
529
|
+
setConfig(config);
|
|
530
|
+
resetEventPipeline();
|
|
531
|
+
if (!(0, node_fs.existsSync)(config.entry)) throw new Error(`Conflux entry not found: ${config.entry}`);
|
|
532
|
+
const { client, configure } = await loadEntryModule(config.entry);
|
|
533
|
+
const conflux = new Conflux({ root: config.root });
|
|
534
|
+
conflux.client = client;
|
|
535
|
+
await configure?.(conflux);
|
|
536
|
+
const commandRegistry = await loadCommandRegistry(config.commandsDir);
|
|
537
|
+
registerConfluxEventHandlers(client, conflux, await loadEventHandlerRegistry(config.eventsDir));
|
|
538
|
+
registerConfluxCommands(client, conflux, commandRegistry, config.commandsDir);
|
|
539
|
+
await client.login(token);
|
|
540
|
+
return conflux;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
//#endregion
|
|
544
|
+
Object.defineProperty(exports, '__toESM', {
|
|
545
|
+
enumerable: true,
|
|
546
|
+
get: function () {
|
|
547
|
+
return __toESM;
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
Object.defineProperty(exports, 'collectEventDirectoryModulePaths', {
|
|
551
|
+
enumerable: true,
|
|
552
|
+
get: function () {
|
|
553
|
+
return collectEventDirectoryModulePaths;
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
Object.defineProperty(exports, 'discoverCommandPaths', {
|
|
557
|
+
enumerable: true,
|
|
558
|
+
get: function () {
|
|
559
|
+
return discoverCommandPaths;
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
Object.defineProperty(exports, 'findConfigPath', {
|
|
563
|
+
enumerable: true,
|
|
564
|
+
get: function () {
|
|
565
|
+
return findConfigPath;
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
Object.defineProperty(exports, 'loadCommandRegistry', {
|
|
569
|
+
enumerable: true,
|
|
570
|
+
get: function () {
|
|
571
|
+
return loadCommandRegistry;
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
Object.defineProperty(exports, 'loadConfluxConfig', {
|
|
575
|
+
enumerable: true,
|
|
576
|
+
get: function () {
|
|
577
|
+
return loadConfluxConfig;
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
Object.defineProperty(exports, 'runConflux', {
|
|
581
|
+
enumerable: true,
|
|
582
|
+
get: function () {
|
|
583
|
+
return runConflux;
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
//# sourceMappingURL=run-conflux-B_44EsUH.cjs.map
|