bakit 2.0.0-alpha.24 → 2.0.0-alpha.25
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/cli.js +21 -31
- package/dist/hooks.js +11 -21
- package/dist/index.d.ts +82 -12
- package/dist/index.js +189 -68
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,71 +1,61 @@
|
|
|
1
1
|
import { config } from 'dotenv';
|
|
2
2
|
import { program } from 'commander';
|
|
3
3
|
import { fork } from 'child_process';
|
|
4
|
-
import path, { resolve
|
|
4
|
+
import path, { resolve } from 'path';
|
|
5
5
|
import chokidar from 'chokidar';
|
|
6
|
+
import { RPC } from 'bakit';
|
|
6
7
|
|
|
7
8
|
// src/cli/bin.ts
|
|
8
|
-
function getTopLevelDirectory(path2, entryDir) {
|
|
9
|
-
return relative(entryDir, path2).split(sep)[0] ?? null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// src/cli/process/DevProcessManager.ts
|
|
13
9
|
var DevProcessManager = class {
|
|
14
10
|
constructor(options) {
|
|
15
11
|
this.options = options;
|
|
16
12
|
}
|
|
17
|
-
|
|
13
|
+
rpc = null;
|
|
18
14
|
restartTimer = null;
|
|
19
15
|
start() {
|
|
20
16
|
console.log("Starting bakit in dev mode..."), this.startChild(), this.startWatcher();
|
|
21
17
|
}
|
|
22
18
|
startChild() {
|
|
23
|
-
if (this.
|
|
24
|
-
|
|
25
|
-
this.child = fork(entry, {
|
|
19
|
+
if (this.rpc)
|
|
20
|
+
return;
|
|
21
|
+
let entry = path.resolve(this.options.entry), child = fork(entry, {
|
|
26
22
|
execArgv: ["--import", "bakit/register"],
|
|
27
23
|
stdio: "inherit",
|
|
28
24
|
env: {
|
|
29
25
|
...process.env,
|
|
30
26
|
NODE_ENV: "development"
|
|
31
27
|
}
|
|
32
|
-
}), this.child.on("exit", () => {
|
|
33
|
-
this.child = null;
|
|
34
28
|
});
|
|
29
|
+
this.rpc = new RPC(child), this.rpc.on("restart", (fileUpdated) => this.scheduleRestart(fileUpdated));
|
|
35
30
|
}
|
|
36
31
|
restartChild() {
|
|
37
|
-
if (!this.
|
|
32
|
+
if (!this.rpc)
|
|
38
33
|
return this.startChild();
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
this.
|
|
42
|
-
}),
|
|
34
|
+
let child = this.rpc.transport;
|
|
35
|
+
child.once("exit", () => {
|
|
36
|
+
this.rpc = null, this.startChild();
|
|
37
|
+
}), child.kill("SIGTERM");
|
|
43
38
|
}
|
|
44
39
|
startWatcher() {
|
|
45
|
-
let { rootDir } = this.options
|
|
46
|
-
chokidar.watch(rootDir, {
|
|
40
|
+
let { rootDir } = this.options, watcher = chokidar.watch(rootDir, {
|
|
47
41
|
ignoreInitial: true,
|
|
48
42
|
awaitWriteFinish: {
|
|
49
43
|
stabilityThreshold: 200,
|
|
50
44
|
pollInterval: 50
|
|
51
45
|
}
|
|
52
|
-
}).on("change", (path2) => {
|
|
53
|
-
this.onFileChanged(path2);
|
|
54
46
|
});
|
|
47
|
+
watcher.on("change", (path2) => this.onFileUpdate("fileChange", path2)), watcher.on("unlink", (path2) => this.onFileUpdate("fileRemove", path2));
|
|
55
48
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this.child.connected && this.child.send({ type: `hmr:${top}`, path: resolve(path2) });
|
|
62
|
-
return;
|
|
49
|
+
onFileUpdate(type, path2) {
|
|
50
|
+
try {
|
|
51
|
+
this.rpc?.send(type, resolve(path2));
|
|
52
|
+
} catch {
|
|
53
|
+
this.scheduleRestart(true);
|
|
63
54
|
}
|
|
64
|
-
this.scheduleRestart();
|
|
65
55
|
}
|
|
66
|
-
scheduleRestart() {
|
|
56
|
+
scheduleRestart(fileUpdated = false) {
|
|
67
57
|
this.restartTimer && clearTimeout(this.restartTimer), this.restartTimer = setTimeout(() => {
|
|
68
|
-
console.log("
|
|
58
|
+
fileUpdated && console.log("File changes detected, restarting..."), this.restartChild(), this.restartTimer = null;
|
|
69
59
|
}, 150);
|
|
70
60
|
}
|
|
71
61
|
};
|
package/dist/hooks.js
CHANGED
|
@@ -3,14 +3,15 @@ import { readFile } from 'fs/promises';
|
|
|
3
3
|
import { Module } from 'module';
|
|
4
4
|
import { dirname, resolve as resolve$1, basename } from 'path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
6
|
+
import { RPC } from 'bakit';
|
|
6
7
|
|
|
7
8
|
// src/lib/loader/hooks.ts
|
|
8
|
-
var EXTENSIONS = [".js", ".ts"],
|
|
9
|
+
var EXTENSIONS = [".js", ".ts"], rpc, versions, esbuild;
|
|
9
10
|
function isDevelopment() {
|
|
10
11
|
return process.env.NODE_ENV === "development";
|
|
11
12
|
}
|
|
12
13
|
async function initialize({ port }) {
|
|
13
|
-
|
|
14
|
+
rpc = new RPC(port), versions = /* @__PURE__ */ new Map(), rpc.on("message", onUnload), isDevelopment() && (esbuild = await import('esbuild'));
|
|
14
15
|
}
|
|
15
16
|
async function resolve(specifier, context, nextResolve) {
|
|
16
17
|
if (shouldSkip(specifier))
|
|
@@ -27,10 +28,9 @@ async function resolve(specifier, context, nextResolve) {
|
|
|
27
28
|
let urlObj = new URL(url);
|
|
28
29
|
if (isDevelopment()) {
|
|
29
30
|
let filePath = fileURLToPath(urlObj), version = createVersion(filePath);
|
|
30
|
-
urlObj.searchParams.set("hmr", version), parentURL &&
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
child: url
|
|
31
|
+
urlObj.searchParams.set("hmr", version), parentURL && rpc.send("dependencyAdd", {
|
|
32
|
+
parentURL,
|
|
33
|
+
url
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
return {
|
|
@@ -62,8 +62,8 @@ async function load(url, context, nextLoad) {
|
|
|
62
62
|
return nextLoad(url, context);
|
|
63
63
|
}
|
|
64
64
|
function createVersion(filename) {
|
|
65
|
-
let version = versions
|
|
66
|
-
return version || (version = Date.now().toString(), versions
|
|
65
|
+
let version = versions.get(filename);
|
|
66
|
+
return version || (version = Date.now().toString(), versions.set(filename, version)), version;
|
|
67
67
|
}
|
|
68
68
|
function shouldSkip(specifier) {
|
|
69
69
|
if (Module.isBuiltin(specifier) || specifier.includes("/node_modules/"))
|
|
@@ -74,19 +74,9 @@ function shouldSkip(specifier) {
|
|
|
74
74
|
}
|
|
75
75
|
return true;
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
let
|
|
79
|
-
|
|
80
|
-
parentPort?.postMessage({
|
|
81
|
-
id,
|
|
82
|
-
data: false
|
|
83
|
-
});
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
versions?.delete(data), parentPort?.postMessage({
|
|
87
|
-
id,
|
|
88
|
-
data: true
|
|
89
|
-
});
|
|
77
|
+
function onUnload(id, path) {
|
|
78
|
+
let deleted = versions.delete(resolve$1(path));
|
|
79
|
+
rpc.success(id, deleted);
|
|
90
80
|
}
|
|
91
81
|
|
|
92
82
|
export { initialize, load, resolve };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ import * as discord_js from 'discord.js';
|
|
|
2
2
|
import { ChatInputCommandInteraction, CacheType, Message, User, MessageCreateOptions, InteractionReplyOptions, Awaitable, Collection, Events, IntentsBitField, ClientEvents, Client, ClientOptions, GatewayIntentBits } from 'discord.js';
|
|
3
3
|
import { inspect } from 'node:util';
|
|
4
4
|
import z from 'zod';
|
|
5
|
+
import EventEmitter from 'node:events';
|
|
6
|
+
import { Serializable, ChildProcess } from 'node:child_process';
|
|
7
|
+
import { MessagePort as MessagePort$1 } from 'node:worker_threads';
|
|
5
8
|
|
|
6
9
|
declare enum ParamUserType {
|
|
7
10
|
Bot = "bot",
|
|
@@ -367,12 +370,18 @@ declare class ProjectCacheManager {
|
|
|
367
370
|
declare class Instance {
|
|
368
371
|
client: BakitClient;
|
|
369
372
|
cache: ProjectCacheManager;
|
|
373
|
+
private rpc;
|
|
370
374
|
constructor();
|
|
371
375
|
start(): Promise<void>;
|
|
372
376
|
private initProcess;
|
|
373
377
|
private loadModules;
|
|
374
378
|
private initIntents;
|
|
375
|
-
private
|
|
379
|
+
private isInHotDirectory;
|
|
380
|
+
private isFileHotReloadable;
|
|
381
|
+
private restart;
|
|
382
|
+
shutdown(): Promise<void>;
|
|
383
|
+
private onFileRemove;
|
|
384
|
+
private onFileChange;
|
|
376
385
|
}
|
|
377
386
|
declare function useApp(): Instance;
|
|
378
387
|
|
|
@@ -449,20 +458,49 @@ declare function extractSnowflakeId(input: string): string | null;
|
|
|
449
458
|
|
|
450
459
|
declare function getTopLevelDirectory(path: string, entryDir: string): string | null;
|
|
451
460
|
|
|
452
|
-
|
|
453
|
-
|
|
461
|
+
declare function $initLoader(): void;
|
|
462
|
+
declare function $unloadFile(path: string): Promise<boolean>;
|
|
463
|
+
declare function isImported(filePath: string): boolean;
|
|
464
|
+
declare function isImportedBy(filePath: string, matcher: string | RegExp | ((path: string) => boolean)): boolean;
|
|
465
|
+
|
|
466
|
+
declare const RPC_RESPONSE_MARK = "$DONE:";
|
|
467
|
+
declare const RPC_RESPONSE_TIMEOUT = 5000;
|
|
468
|
+
interface BaseRPCMessage {
|
|
469
|
+
id: string;
|
|
470
|
+
}
|
|
471
|
+
interface BaseRPCResponse {
|
|
472
|
+
id: `${typeof RPC_RESPONSE_MARK}${string}`;
|
|
473
|
+
}
|
|
474
|
+
interface RPCRequest<Data extends Serializable = Serializable> extends BaseRPCMessage {
|
|
454
475
|
type: string;
|
|
455
476
|
data: Data;
|
|
456
477
|
}
|
|
457
|
-
interface
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
478
|
+
interface RPCSuccessResponse<Data extends Serializable = Serializable> extends BaseRPCResponse {
|
|
479
|
+
data: Data;
|
|
480
|
+
}
|
|
481
|
+
interface RPCErrorResponse extends BaseRPCResponse {
|
|
482
|
+
error: string;
|
|
483
|
+
}
|
|
484
|
+
type RPCResponse<Data extends Serializable = Serializable> = RPCSuccessResponse<Data> | RPCErrorResponse;
|
|
485
|
+
type RPCMessage<Data extends Serializable = Serializable> = RPCRequest<Data> | RPCResponse<Data>;
|
|
486
|
+
interface RPCPendingPromise {
|
|
487
|
+
resolve: (data: any) => void;
|
|
488
|
+
reject: (error: unknown) => void;
|
|
489
|
+
timeout: NodeJS.Timeout;
|
|
490
|
+
}
|
|
491
|
+
declare class RPC extends EventEmitter {
|
|
492
|
+
transport: MessagePort$1 | NodeJS.Process | ChildProcess;
|
|
493
|
+
requests: Map<string, RPCPendingPromise>;
|
|
494
|
+
constructor(transport: MessagePort$1 | NodeJS.Process | ChildProcess);
|
|
495
|
+
postMessage(message: Serializable): void;
|
|
496
|
+
private onMessage;
|
|
497
|
+
private handleResponseMessage;
|
|
498
|
+
private handleRequestMessage;
|
|
499
|
+
send<Data extends Serializable>(type: string, data: Data, id?: string): void;
|
|
500
|
+
success<Data extends Serializable>(id: string, data: Data): void;
|
|
501
|
+
error(id: string, error: string): void;
|
|
502
|
+
request<Data extends Serializable, Output extends Serializable>(type: string, data: Data, id?: string): Promise<Output>;
|
|
461
503
|
}
|
|
462
|
-
declare function $initLoader(): void;
|
|
463
|
-
declare function $postLoaderMessage<Data>(type: string, data: Data, wait?: false): void;
|
|
464
|
-
declare function $postLoaderMessage<Data, Output = unknown>(type: string, data: Data, wait: true): Promise<Output>;
|
|
465
|
-
declare function $unloadFile(path: string): Promise<boolean>;
|
|
466
504
|
|
|
467
505
|
declare const messageCommandHandler: Listener<Events.MessageCreate>;
|
|
468
506
|
declare const chatInputCommandHandler: Listener<Events.InteractionCreate>;
|
|
@@ -494,4 +532,36 @@ declare function loadConfig(cwd?: string): Promise<ProjectConfig>;
|
|
|
494
532
|
*/
|
|
495
533
|
declare function getConfig(): ProjectConfig;
|
|
496
534
|
|
|
497
|
-
|
|
535
|
+
interface InitializeData {
|
|
536
|
+
port: MessagePort;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
interface ResolveContext {
|
|
540
|
+
conditions: string[];
|
|
541
|
+
importAttributes: Record<string, string>;
|
|
542
|
+
parentURL?: string;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
interface ResolveResult {
|
|
546
|
+
url: string;
|
|
547
|
+
shortCircuit?: boolean;
|
|
548
|
+
format?: string | null | undefined;
|
|
549
|
+
importAttributes?: Record<string, string>;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
interface LoadContext {
|
|
553
|
+
conditions: string[];
|
|
554
|
+
format: string | null | undefined;
|
|
555
|
+
importAttributes: Record<string, string>;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
interface LoadResult {
|
|
559
|
+
source: string | ArrayBuffer | Uint8Array;
|
|
560
|
+
format: string;
|
|
561
|
+
shortCircuit?: boolean;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
type NextResolve = (specifier: string, context: ResolveContext) => Promise<ResolveResult>;
|
|
565
|
+
type NextLoad = (url: string, context: LoadContext) => Promise<LoadResult>;
|
|
566
|
+
|
|
567
|
+
export { $initLoader, $unloadFile, type AnyParam, ArgumentError, BakitClient, type BakitClientEvents, BakitError, BaseClientManager, BaseCommandContext, BaseParam, type BaseParamOptions, BaseParamSchema, type BaseRPCMessage, type BaseRPCResponse, ChatInputContext, type ChatInputContextSendOptions, Command, type CommandContext, CommandManager, type CommandOptions, type CommandOptionsInput, CommandOptionsSchema, Context, type ContextSendOptions, EVENT_INTENT_MAPPING, type ErrorHookCallback, type GetPrefixFunction, HookOrder, HookState, type InferParamTuple, type InferParamValue, type InitializeData, Instance, LifecycleManager, Listener, ListenerManager, type ListenerOptions, ListenerOptionsSchema, type LoadContext, type LoadResult, type MainHookCallback, MessageContext, type MessageContextSendOptions, type NextLoad, type NextResolve, type NumberOptions, NumberParam, NumberParamSchema, type ParamResolvedOutputType, ParamUserType, Params, ProjectCacheManager, type ProjectConfig, type ProjectConfigInput, ProjectConfigSchema, RPC, type RPCErrorResponse, type RPCMessage, type RPCPendingPromise, type RPCRequest, type RPCResponse, type RPCSuccessResponse, RPC_RESPONSE_MARK, RPC_RESPONSE_TIMEOUT, type ResolveContext, type ResolveResult, type StringOptions, StringParam, StringParamSchema, type UserOptions, UserParam, UserParamSchema, chatInputCommandHandler, defineCommand, defineConfig, defineListener, extractSnowflakeId, getConfig, getTopLevelDirectory, isImported, isImportedBy, loadConfig, messageCommandHandler, registerCommandsHandler, tokenize, useApp, validateParamsOrder };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { GatewayIntentBits, Events, Client, Collection, IntentsBitField, SlashCommandBuilder, SlashCommandStringOption, SlashCommandNumberOption, SlashCommandUserOption, ChatInputCommandInteraction, Message } from 'discord.js';
|
|
2
2
|
import { inspect } from 'util';
|
|
3
|
-
import {
|
|
3
|
+
import { pathToFileURL, fileURLToPath } from 'url';
|
|
4
|
+
import { resolve, posix, relative, sep, join, dirname } from 'path';
|
|
4
5
|
import glob from 'tiny-glob';
|
|
5
6
|
import z4 from 'zod';
|
|
6
7
|
import { register } from 'module';
|
|
7
8
|
import { MessageChannel } from 'worker_threads';
|
|
8
|
-
import {
|
|
9
|
+
import { randomUUID, createHash } from 'crypto';
|
|
10
|
+
import EventEmitter from 'events';
|
|
9
11
|
import { existsSync, mkdirSync, rmSync } from 'fs';
|
|
10
12
|
import { mkdir, writeFile, readFile, rm } from 'fs/promises';
|
|
11
|
-
import { createHash } from 'crypto';
|
|
12
13
|
|
|
13
14
|
// src/core/client/BakitClient.ts
|
|
14
15
|
var ParamUserType = /* @__PURE__ */ ((ParamUserType2) => (ParamUserType2.Bot = "bot", ParamUserType2.Normal = "normal", ParamUserType2.Any = "any", ParamUserType2))(ParamUserType || {}), BaseParamSchema = z4.object({
|
|
@@ -164,34 +165,109 @@ function extractSnowflakeId(input) {
|
|
|
164
165
|
function getTopLevelDirectory(path, entryDir) {
|
|
165
166
|
return relative(entryDir, path).split(sep)[0] ?? null;
|
|
166
167
|
}
|
|
167
|
-
var
|
|
168
|
+
var RPC_RESPONSE_MARK = "$DONE:", RPC_RESPONSE_TIMEOUT = 5e3, RPC = class extends EventEmitter {
|
|
169
|
+
constructor(transport) {
|
|
170
|
+
super();
|
|
171
|
+
this.transport = transport;
|
|
172
|
+
this.transport.on("message", (message) => this.onMessage(message));
|
|
173
|
+
}
|
|
174
|
+
requests = /* @__PURE__ */ new Map();
|
|
175
|
+
postMessage(message) {
|
|
176
|
+
let { transport } = this;
|
|
177
|
+
"send" in transport ? transport.send(message) : "postMessage" in transport ? transport.postMessage(message) : console.warn(`${transport.constructor.name} doesn't support IPC`);
|
|
178
|
+
}
|
|
179
|
+
onMessage(message) {
|
|
180
|
+
if (message.id.startsWith(RPC_RESPONSE_MARK)) {
|
|
181
|
+
this.handleResponseMessage(message);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if ("type" in message) {
|
|
185
|
+
this.handleRequestMessage(message);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
handleResponseMessage(message) {
|
|
190
|
+
let id = message.id.slice(RPC_RESPONSE_MARK.length), request = this.requests.get(id);
|
|
191
|
+
if (!request)
|
|
192
|
+
return;
|
|
193
|
+
let { reject, resolve: resolve5, timeout } = request;
|
|
194
|
+
this.requests.delete(id), clearTimeout(timeout), "data" in message ? resolve5(message.data) : reject(new Error(message.error));
|
|
195
|
+
}
|
|
196
|
+
handleRequestMessage(message) {
|
|
197
|
+
this.emit("message", message), this.emit(message.type, message.id, message.data);
|
|
198
|
+
}
|
|
199
|
+
send(type, data, id = randomUUID()) {
|
|
200
|
+
let message = {
|
|
201
|
+
id,
|
|
202
|
+
type,
|
|
203
|
+
data
|
|
204
|
+
};
|
|
205
|
+
this.postMessage(message);
|
|
206
|
+
}
|
|
207
|
+
success(id, data) {
|
|
208
|
+
let message = {
|
|
209
|
+
id: `${RPC_RESPONSE_MARK}${id}`,
|
|
210
|
+
data
|
|
211
|
+
};
|
|
212
|
+
this.postMessage(message);
|
|
213
|
+
}
|
|
214
|
+
error(id, error) {
|
|
215
|
+
let message = {
|
|
216
|
+
id: `${RPC_RESPONSE_MARK}${id}`,
|
|
217
|
+
error
|
|
218
|
+
};
|
|
219
|
+
this.postMessage(message);
|
|
220
|
+
}
|
|
221
|
+
request(type, data, id = randomUUID()) {
|
|
222
|
+
return new Promise((resolve5, reject) => {
|
|
223
|
+
let timeout = setTimeout(() => {
|
|
224
|
+
this.requests.delete(id) && reject(new Error("Request timed out"));
|
|
225
|
+
}, RPC_RESPONSE_TIMEOUT);
|
|
226
|
+
this.requests.set(id, {
|
|
227
|
+
resolve: resolve5,
|
|
228
|
+
reject,
|
|
229
|
+
timeout
|
|
230
|
+
}), this.send(type, data, id);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
var rpc, reverseDependencyGraph = /* @__PURE__ */ new Map();
|
|
168
235
|
function $initLoader() {
|
|
169
|
-
let
|
|
170
|
-
port1 = channel.port1, port2 = channel.port2;
|
|
171
|
-
let hookPath = new URL("./hooks.js", import.meta.url).href;
|
|
236
|
+
let { port1, port2 } = new MessageChannel(), hookPath = new URL("./hooks.js", import.meta.url).href;
|
|
172
237
|
register(hookPath, import.meta.url, {
|
|
173
238
|
data: { port: port1 },
|
|
174
239
|
transferList: [port1]
|
|
175
|
-
}), port2.on("
|
|
240
|
+
}), rpc = new RPC(port2), rpc.on("dependencyAdd", (_id, data) => onDependencyAdd(data)), port2.unref();
|
|
176
241
|
}
|
|
177
|
-
function
|
|
178
|
-
|
|
179
|
-
|
|
242
|
+
function $unloadFile(path) {
|
|
243
|
+
if (!rpc)
|
|
244
|
+
throw new Error("Loader isn't initialized");
|
|
245
|
+
return rpc.request("unload", resolve(path));
|
|
180
246
|
}
|
|
181
|
-
function
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
247
|
+
function isImported(filePath) {
|
|
248
|
+
return !!reverseDependencyGraph.get(filePath)?.size;
|
|
249
|
+
}
|
|
250
|
+
function isImportedBy(filePath, matcher) {
|
|
251
|
+
let queue = [filePath], visited = /* @__PURE__ */ new Set();
|
|
252
|
+
for (; queue.length > 0; ) {
|
|
253
|
+
let current = queue.shift();
|
|
254
|
+
if (visited.has(current))
|
|
255
|
+
continue;
|
|
256
|
+
visited.add(current);
|
|
257
|
+
let parents = reverseDependencyGraph.get(current);
|
|
258
|
+
if (parents)
|
|
259
|
+
for (let parent of parents) {
|
|
260
|
+
let isMatch = false;
|
|
261
|
+
if (typeof matcher == "string" ? isMatch = parent === matcher : matcher instanceof RegExp ? isMatch = matcher.test(parent) : typeof matcher == "function" && (isMatch = matcher(parent)), isMatch)
|
|
262
|
+
return true;
|
|
263
|
+
visited.has(parent) || queue.push(parent);
|
|
264
|
+
}
|
|
186
265
|
}
|
|
187
|
-
return
|
|
188
|
-
if (!port2)
|
|
189
|
-
return reject(new Error("Loader is not initialized"));
|
|
190
|
-
pending.set(id, { resolve: resolve4, reject }), port2.postMessage(message);
|
|
191
|
-
});
|
|
266
|
+
return false;
|
|
192
267
|
}
|
|
193
|
-
function
|
|
194
|
-
|
|
268
|
+
function onDependencyAdd(data) {
|
|
269
|
+
let { url, parentURL } = data, path = fileURLToPath(url), parentPath = fileURLToPath(parentURL), entry = reverseDependencyGraph.get(path);
|
|
270
|
+
entry || (entry = /* @__PURE__ */ new Set(), reverseDependencyGraph.set(path, entry)), entry.add(parentPath);
|
|
195
271
|
}
|
|
196
272
|
|
|
197
273
|
// src/core/structures/param/Param.ts
|
|
@@ -475,6 +551,8 @@ var BaseClientManager = class {
|
|
|
475
551
|
this.client = client;
|
|
476
552
|
}
|
|
477
553
|
};
|
|
554
|
+
|
|
555
|
+
// src/core/managers/CommandManager.ts
|
|
478
556
|
var CommandManager = class extends BaseClientManager {
|
|
479
557
|
commands = new Collection();
|
|
480
558
|
entries = new Collection();
|
|
@@ -573,6 +651,8 @@ var Context = class {
|
|
|
573
651
|
this.canceled = true;
|
|
574
652
|
}
|
|
575
653
|
};
|
|
654
|
+
|
|
655
|
+
// src/core/managers/ListenerManager.ts
|
|
576
656
|
var ListenerManager = class extends BaseClientManager {
|
|
577
657
|
listeners = [];
|
|
578
658
|
entries = new Collection();
|
|
@@ -770,7 +850,7 @@ var BaseCommandContext = class extends Context {
|
|
|
770
850
|
return await channel.send(options);
|
|
771
851
|
}
|
|
772
852
|
};
|
|
773
|
-
var ProjectConfigSchema = z4.object({
|
|
853
|
+
var CONFIG_EXTENSIONS = ["ts", "js"], ProjectConfigSchema = z4.object({
|
|
774
854
|
/**
|
|
775
855
|
* The gateway intents to use for the Discord client.
|
|
776
856
|
*
|
|
@@ -789,7 +869,13 @@ var ProjectConfigSchema = z4.object({
|
|
|
789
869
|
* @see {@link https://discord.js.org/docs/packages/discord.js/main/ClientOptions:Interface}
|
|
790
870
|
*/
|
|
791
871
|
clientOptions: z4.custom().optional(),
|
|
872
|
+
/**
|
|
873
|
+
* Your bot prefixes to trigger the commands.
|
|
874
|
+
*/
|
|
792
875
|
prefixes: z4.array(z4.string()).default([]),
|
|
876
|
+
/**
|
|
877
|
+
* Your Discord bot token.
|
|
878
|
+
*/
|
|
793
879
|
token: z4.string()
|
|
794
880
|
});
|
|
795
881
|
function defineConfig(config) {
|
|
@@ -799,7 +885,7 @@ var _config;
|
|
|
799
885
|
async function loadConfig(cwd = process.cwd()) {
|
|
800
886
|
if (_config)
|
|
801
887
|
return console.warn("loadConfig() was called more than once. This shouldn't happen."), _config;
|
|
802
|
-
let globPattern = `bakit.config.{${
|
|
888
|
+
let globPattern = `bakit.config.{${CONFIG_EXTENSIONS.join(",")}}`, [configPath, other] = await glob(globPattern, {
|
|
803
889
|
cwd: cwd.replace(/\\/g, "/"),
|
|
804
890
|
// ensure the path uses `/` instead of `\` on Windows
|
|
805
891
|
absolute: true
|
|
@@ -815,6 +901,39 @@ function getConfig() {
|
|
|
815
901
|
throw new Error("Project config is not loaded.");
|
|
816
902
|
return _config;
|
|
817
903
|
}
|
|
904
|
+
var ProjectCacheManager = class {
|
|
905
|
+
rootDir;
|
|
906
|
+
constructor(root = process.cwd()) {
|
|
907
|
+
this.rootDir = join(root, ".bakit"), this.ensureRoot();
|
|
908
|
+
}
|
|
909
|
+
ensureRoot() {
|
|
910
|
+
existsSync(this.rootDir) || mkdirSync(this.rootDir, { recursive: true });
|
|
911
|
+
}
|
|
912
|
+
getHash(data) {
|
|
913
|
+
return createHash("sha256").update(JSON.stringify(data)).digest("hex");
|
|
914
|
+
}
|
|
915
|
+
async write(path, data) {
|
|
916
|
+
let fullPath = join(this.rootDir, path), dir = dirname(fullPath);
|
|
917
|
+
await mkdir(dir, { recursive: true });
|
|
918
|
+
let content = typeof data == "string" ? data : JSON.stringify(data);
|
|
919
|
+
await writeFile(fullPath, content, "utf-8");
|
|
920
|
+
}
|
|
921
|
+
async read(path) {
|
|
922
|
+
let fullPath = join(this.rootDir, path);
|
|
923
|
+
try {
|
|
924
|
+
let content = await readFile(fullPath, "utf-8");
|
|
925
|
+
return JSON.parse(content);
|
|
926
|
+
} catch {
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
async clear() {
|
|
931
|
+
await rm(this.rootDir, { recursive: true, force: true });
|
|
932
|
+
}
|
|
933
|
+
clearSync() {
|
|
934
|
+
existsSync(this.rootDir) && rmSync(this.rootDir, { recursive: true, force: true });
|
|
935
|
+
}
|
|
936
|
+
};
|
|
818
937
|
var messageCommandHandler = defineListener(Events.MessageCreate), chatInputCommandHandler = defineListener(Events.InteractionCreate), registerCommandsHandler = defineListener({
|
|
819
938
|
name: Events.ClientReady,
|
|
820
939
|
once: true
|
|
@@ -873,46 +992,14 @@ chatInputCommandHandler.main(async (_, interaction) => {
|
|
|
873
992
|
}
|
|
874
993
|
await command.execute(context, ...resolvedArgs);
|
|
875
994
|
});
|
|
876
|
-
var ProjectCacheManager = class {
|
|
877
|
-
rootDir;
|
|
878
|
-
constructor(root = process.cwd()) {
|
|
879
|
-
this.rootDir = join(root, ".bakit"), this.ensureRoot();
|
|
880
|
-
}
|
|
881
|
-
ensureRoot() {
|
|
882
|
-
existsSync(this.rootDir) || mkdirSync(this.rootDir, { recursive: true });
|
|
883
|
-
}
|
|
884
|
-
getHash(data) {
|
|
885
|
-
return createHash("sha256").update(JSON.stringify(data)).digest("hex");
|
|
886
|
-
}
|
|
887
|
-
async write(path, data) {
|
|
888
|
-
let fullPath = join(this.rootDir, path), dir = dirname(fullPath);
|
|
889
|
-
await mkdir(dir, { recursive: true });
|
|
890
|
-
let content = typeof data == "string" ? data : JSON.stringify(data);
|
|
891
|
-
await writeFile(fullPath, content, "utf-8");
|
|
892
|
-
}
|
|
893
|
-
async read(path) {
|
|
894
|
-
let fullPath = join(this.rootDir, path);
|
|
895
|
-
try {
|
|
896
|
-
let content = await readFile(fullPath, "utf-8");
|
|
897
|
-
return JSON.parse(content);
|
|
898
|
-
} catch {
|
|
899
|
-
return null;
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
async clear() {
|
|
903
|
-
await rm(this.rootDir, { recursive: true, force: true });
|
|
904
|
-
}
|
|
905
|
-
clearSync() {
|
|
906
|
-
existsSync(this.rootDir) && rmSync(this.rootDir, { recursive: true, force: true });
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
995
|
|
|
910
996
|
// src/core/internal/Instance.ts
|
|
911
|
-
var Instance = class {
|
|
997
|
+
var HOT_DIRECTORIES = ["listeners", "commands"], SOURCE_ROOT = resolve(process.cwd(), "src"), Instance = class {
|
|
912
998
|
client;
|
|
913
999
|
cache;
|
|
1000
|
+
rpc;
|
|
914
1001
|
constructor() {
|
|
915
|
-
this.cache = new ProjectCacheManager();
|
|
1002
|
+
this.cache = new ProjectCacheManager(), this.rpc = new RPC(process);
|
|
916
1003
|
}
|
|
917
1004
|
async start() {
|
|
918
1005
|
await loadConfig();
|
|
@@ -926,7 +1013,7 @@ var Instance = class {
|
|
|
926
1013
|
), await this.loadModules(), this.initIntents(), await this.client.login(config.token), this.initProcess();
|
|
927
1014
|
}
|
|
928
1015
|
initProcess() {
|
|
929
|
-
process.on("
|
|
1016
|
+
process.env.NODE_ENV === "development" && (this.rpc.on("fileRemove", (_id, path) => this.onFileRemove(path)), this.rpc.on("fileChange", (_id, path) => this.onFileChange(path))), process.on("SIGINT", () => this.shutdown()), process.on("SIGTERM", () => this.shutdown());
|
|
930
1017
|
}
|
|
931
1018
|
loadModules() {
|
|
932
1019
|
let { managers } = this.client, { commands, listeners } = managers;
|
|
@@ -936,13 +1023,47 @@ var Instance = class {
|
|
|
936
1023
|
let config = getConfig(), { options, managers } = this.client, { listeners } = managers, intents;
|
|
937
1024
|
config.intents === "auto" ? intents = listeners.getNeededIntents() : (intents = listeners.getBaseIntents(), typeof config.intents == "bigint" ? intents.bitfield = Number(config.intents) : intents.add(...config.intents)), options.intents = intents;
|
|
938
1025
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1026
|
+
isInHotDirectory(path) {
|
|
1027
|
+
if (!path.startsWith(SOURCE_ROOT))
|
|
1028
|
+
return false;
|
|
1029
|
+
let topLevelDir = getTopLevelDirectory(path, SOURCE_ROOT);
|
|
1030
|
+
return !!topLevelDir && HOT_DIRECTORIES.includes(topLevelDir);
|
|
1031
|
+
}
|
|
1032
|
+
isFileHotReloadable(path) {
|
|
1033
|
+
return path = resolve(path), !(!this.isInHotDirectory(path) || isImportedBy(path, (parentPath) => !this.isInHotDirectory(parentPath)));
|
|
1034
|
+
}
|
|
1035
|
+
restart() {
|
|
1036
|
+
this.rpc.send("restart", {});
|
|
1037
|
+
}
|
|
1038
|
+
async shutdown() {
|
|
1039
|
+
this.client && await this.client.destroy().catch(() => null), process.exit(0);
|
|
1040
|
+
}
|
|
1041
|
+
async onFileRemove(path) {
|
|
1042
|
+
if (!isImported(path))
|
|
1043
|
+
return;
|
|
1044
|
+
if (!this.isFileHotReloadable(path)) {
|
|
1045
|
+
this.restart();
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
let topLevelDir = getTopLevelDirectory(path, SOURCE_ROOT), { listeners, commands } = this.client.managers;
|
|
1049
|
+
switch (topLevelDir) {
|
|
1050
|
+
case "listeners":
|
|
1051
|
+
await listeners.unload(path);
|
|
1052
|
+
break;
|
|
1053
|
+
case "commands":
|
|
1054
|
+
await commands.unload(path);
|
|
1055
|
+
break;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
async onFileChange(path) {
|
|
1059
|
+
if (!isImported(path))
|
|
1060
|
+
return;
|
|
1061
|
+
if (!this.isFileHotReloadable(path)) {
|
|
1062
|
+
this.restart();
|
|
943
1063
|
return;
|
|
944
|
-
|
|
945
|
-
|
|
1064
|
+
}
|
|
1065
|
+
let topLevelDir = getTopLevelDirectory(path, SOURCE_ROOT), { listeners, commands } = this.client.managers;
|
|
1066
|
+
switch (topLevelDir) {
|
|
946
1067
|
case "listeners":
|
|
947
1068
|
await listeners.reload(path);
|
|
948
1069
|
break;
|
|
@@ -966,4 +1087,4 @@ var Params = {
|
|
|
966
1087
|
user: createFactory(UserParam)
|
|
967
1088
|
};
|
|
968
1089
|
|
|
969
|
-
export { $initLoader, $
|
|
1090
|
+
export { $initLoader, $unloadFile, ArgumentError, BakitClient, BakitError, BaseClientManager, BaseCommandContext, BaseParam, BaseParamSchema, ChatInputContext, Command, CommandManager, CommandOptionsSchema, Context, EVENT_INTENT_MAPPING, HookOrder, HookState, Instance, LifecycleManager, Listener, ListenerManager, ListenerOptionsSchema, MessageContext, NumberParam, NumberParamSchema, ParamUserType, Params, ProjectCacheManager, ProjectConfigSchema, RPC, RPC_RESPONSE_MARK, RPC_RESPONSE_TIMEOUT, StringParam, StringParamSchema, UserParam, UserParamSchema, chatInputCommandHandler, defineCommand, defineConfig, defineListener, extractSnowflakeId, getConfig, getTopLevelDirectory, isImported, isImportedBy, loadConfig, messageCommandHandler, registerCommandsHandler, tokenize, useApp, validateParamsOrder };
|