reciple 9.9.0 → 10.0.1-dev.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.
Files changed (163) hide show
  1. package/LICENSE +155 -674
  2. package/assets/config/reciple.config.js +87 -0
  3. package/assets/config/reciple.config.ts +80 -0
  4. package/assets/global/README.md +1 -0
  5. package/assets/global/gitignore +121 -0
  6. package/assets/global/nodemon.json +13 -0
  7. package/assets/modules/javascript/Base.js +21 -0
  8. package/assets/modules/javascript/ClientEvent.js +14 -0
  9. package/assets/modules/javascript/ContextMenuCommand.js +17 -0
  10. package/assets/modules/javascript/Event.js +17 -0
  11. package/assets/modules/javascript/MessageCommand.js +16 -0
  12. package/assets/modules/javascript/RESTEvent.js +14 -0
  13. package/assets/modules/javascript/SlashCommand.js +16 -0
  14. package/assets/modules/typescript/Base.ts +17 -0
  15. package/assets/modules/typescript/ClientEvent.ts +15 -0
  16. package/assets/modules/typescript/ContextMenuCommand.ts +15 -0
  17. package/assets/modules/typescript/Event.ts +16 -0
  18. package/assets/modules/typescript/MessageCommand.ts +14 -0
  19. package/assets/modules/typescript/RESTEvent.ts +15 -0
  20. package/assets/modules/typescript/SlashCommand.ts +14 -0
  21. package/assets/templates/javascript/jsconfig.json +17 -0
  22. package/assets/templates/typescript/tsconfig.json +17 -0
  23. package/dist/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs +10 -0
  24. package/dist/bin/commands/build.d.mts +16 -0
  25. package/dist/bin/commands/build.mjs +24 -0
  26. package/dist/bin/commands/build.mjs.map +1 -0
  27. package/dist/bin/commands/create.d.mts +23 -0
  28. package/dist/bin/commands/create.mjs +48 -0
  29. package/dist/bin/commands/create.mjs.map +1 -0
  30. package/dist/bin/commands/createModule.d.mts +21 -0
  31. package/dist/bin/commands/createModule.mjs +40 -0
  32. package/dist/bin/commands/createModule.mjs.map +1 -0
  33. package/dist/bin/commands/start.d.mts +18 -0
  34. package/dist/bin/commands/start.mjs +104 -0
  35. package/dist/bin/commands/start.mjs.map +1 -0
  36. package/dist/bin/reciple.d.mts +1 -0
  37. package/dist/bin/reciple.mjs +9 -0
  38. package/dist/bin/reciple.mjs.map +1 -0
  39. package/dist/classes/NotAnError.d.mts +7 -0
  40. package/dist/classes/NotAnError.mjs +11 -0
  41. package/dist/classes/NotAnError.mjs.map +1 -0
  42. package/dist/classes/cli/CLI.d.mts +54 -0
  43. package/dist/classes/cli/CLI.mjs +156 -0
  44. package/dist/classes/cli/CLI.mjs.map +1 -0
  45. package/dist/classes/cli/CLISubcommand.d.mts +27 -0
  46. package/dist/classes/cli/CLISubcommand.mjs +23 -0
  47. package/dist/classes/cli/CLISubcommand.mjs.map +1 -0
  48. package/dist/classes/cli/ConfigReader.d.mts +81 -0
  49. package/dist/classes/cli/ConfigReader.mjs +141 -0
  50. package/dist/classes/cli/ConfigReader.mjs.map +1 -0
  51. package/dist/classes/cli/RuntimeEnvironment.d.mts +14 -0
  52. package/dist/classes/cli/RuntimeEnvironment.mjs +36 -0
  53. package/dist/classes/cli/RuntimeEnvironment.mjs.map +1 -0
  54. package/dist/classes/client/EventListeners.d.mts +26 -0
  55. package/dist/classes/client/EventListeners.mjs +103 -0
  56. package/dist/classes/client/EventListeners.mjs.map +1 -0
  57. package/dist/classes/client/ModuleLoader.d.mts +55 -0
  58. package/dist/classes/client/ModuleLoader.mjs +152 -0
  59. package/dist/classes/client/ModuleLoader.mjs.map +1 -0
  60. package/dist/classes/managers/ModuleManager.d.mts +55 -0
  61. package/dist/classes/managers/ModuleManager.mjs +107 -0
  62. package/dist/classes/managers/ModuleManager.mjs.map +1 -0
  63. package/dist/classes/modules/BaseModule.d.mts +34 -0
  64. package/dist/classes/modules/BaseModule.mjs +33 -0
  65. package/dist/classes/modules/BaseModule.mjs.map +1 -0
  66. package/dist/classes/modules/PostconditionModule.d.mts +20 -0
  67. package/dist/classes/modules/PostconditionModule.mjs +24 -0
  68. package/dist/classes/modules/PostconditionModule.mjs.map +1 -0
  69. package/dist/classes/modules/PreconditionModule.d.mts +20 -0
  70. package/dist/classes/modules/PreconditionModule.mjs +24 -0
  71. package/dist/classes/modules/PreconditionModule.mjs.map +1 -0
  72. package/dist/classes/modules/commands/ContextMenuCommandModule.d.mts +24 -0
  73. package/dist/classes/modules/commands/ContextMenuCommandModule.mjs +27 -0
  74. package/dist/classes/modules/commands/ContextMenuCommandModule.mjs.map +1 -0
  75. package/dist/classes/modules/commands/MessageCommandModule.d.mts +24 -0
  76. package/dist/classes/modules/commands/MessageCommandModule.mjs +27 -0
  77. package/dist/classes/modules/commands/MessageCommandModule.mjs.map +1 -0
  78. package/dist/classes/modules/commands/SlashCommandModule.d.mts +24 -0
  79. package/dist/classes/modules/commands/SlashCommandModule.mjs +27 -0
  80. package/dist/classes/modules/commands/SlashCommandModule.mjs.map +1 -0
  81. package/dist/classes/modules/events/ClientEventModule.d.mts +11 -0
  82. package/dist/classes/modules/events/ClientEventModule.mjs +10 -0
  83. package/dist/classes/modules/events/ClientEventModule.mjs.map +1 -0
  84. package/dist/classes/modules/events/EventModule.d.mts +29 -0
  85. package/dist/classes/modules/events/EventModule.mjs +26 -0
  86. package/dist/classes/modules/events/EventModule.mjs.map +1 -0
  87. package/dist/classes/modules/events/RESTEventModule.d.mts +11 -0
  88. package/dist/classes/modules/events/RESTEventModule.mjs +10 -0
  89. package/dist/classes/modules/events/RESTEventModule.mjs.map +1 -0
  90. package/dist/classes/templates/ModuleTemplateBuilder.d.mts +84 -0
  91. package/dist/classes/templates/ModuleTemplateBuilder.mjs +288 -0
  92. package/dist/classes/templates/ModuleTemplateBuilder.mjs.map +1 -0
  93. package/dist/classes/templates/TemplateBuilder.d.mts +78 -0
  94. package/dist/classes/templates/TemplateBuilder.mjs +351 -0
  95. package/dist/classes/templates/TemplateBuilder.mjs.map +1 -0
  96. package/dist/classes/validation/BaseModuleValidator.d.mts +44 -0
  97. package/dist/classes/validation/BaseModuleValidator.mjs +46 -0
  98. package/dist/classes/validation/BaseModuleValidator.mjs.map +1 -0
  99. package/dist/classes/validation/CommandModuleValidator.d.mts +117 -0
  100. package/dist/classes/validation/CommandModuleValidator.mjs +16 -0
  101. package/dist/classes/validation/CommandModuleValidator.mjs.map +1 -0
  102. package/dist/classes/validation/EventModuleValidator.d.mts +59 -0
  103. package/dist/classes/validation/EventModuleValidator.mjs +42 -0
  104. package/dist/classes/validation/EventModuleValidator.mjs.map +1 -0
  105. package/dist/classes/validation/PostconditionModule.d.mts +30 -0
  106. package/dist/classes/validation/PostconditionModule.mjs +34 -0
  107. package/dist/classes/validation/PostconditionModule.mjs.map +1 -0
  108. package/dist/classes/validation/PreconditionModule.d.mts +28 -0
  109. package/dist/classes/validation/PreconditionModule.mjs +29 -0
  110. package/dist/classes/validation/PreconditionModule.mjs.map +1 -0
  111. package/dist/helpers/constants.d.mts +20 -0
  112. package/dist/helpers/constants.mjs +28 -0
  113. package/dist/helpers/constants.mjs.map +1 -0
  114. package/dist/helpers/types.d.mts +20 -0
  115. package/dist/helpers/types.mjs +1 -0
  116. package/dist/index.d.mts +39 -0
  117. package/dist/index.mjs +39 -0
  118. package/dist/index.mjs.map +1 -0
  119. package/dist/package.mjs +80 -0
  120. package/dist/package.mjs.map +1 -0
  121. package/package.json +61 -46
  122. package/README.md +0 -206
  123. package/dist/bin.d.ts +0 -2
  124. package/dist/bin.js +0 -4
  125. package/dist/bin.js.map +0 -1
  126. package/dist/classes/CLI.d.ts +0 -55
  127. package/dist/classes/CLI.js +0 -191
  128. package/dist/classes/CLI.js.map +0 -1
  129. package/dist/classes/Config.d.ts +0 -26
  130. package/dist/classes/Config.js +0 -73
  131. package/dist/classes/Config.js.map +0 -1
  132. package/dist/classes/EventHandlers.d.ts +0 -9
  133. package/dist/classes/EventHandlers.js +0 -71
  134. package/dist/classes/EventHandlers.js.map +0 -1
  135. package/dist/classes/ModuleLoader.d.ts +0 -25
  136. package/dist/classes/ModuleLoader.js +0 -91
  137. package/dist/classes/ModuleLoader.js.map +0 -1
  138. package/dist/commands/init.d.ts +0 -7
  139. package/dist/commands/init.js +0 -10
  140. package/dist/commands/init.js.map +0 -1
  141. package/dist/commands/modules.d.ts +0 -9
  142. package/dist/commands/modules.js +0 -33
  143. package/dist/commands/modules.js.map +0 -1
  144. package/dist/commands/shard.d.ts +0 -9
  145. package/dist/commands/shard.js +0 -102
  146. package/dist/commands/shard.js.map +0 -1
  147. package/dist/commands/start.d.ts +0 -9
  148. package/dist/commands/start.js +0 -95
  149. package/dist/commands/start.js.map +0 -1
  150. package/dist/exports.d.ts +0 -6
  151. package/dist/exports.js +0 -7
  152. package/dist/exports.js.map +0 -1
  153. package/dist/index.d.ts +0 -15
  154. package/dist/index.js +0 -8
  155. package/dist/index.js.map +0 -1
  156. package/dist/types/constants.d.ts +0 -6
  157. package/dist/types/constants.js +0 -29
  158. package/dist/types/constants.js.map +0 -1
  159. package/dist/types/structures.d.ts +0 -36
  160. package/dist/types/structures.js +0 -2
  161. package/dist/types/structures.js.map +0 -1
  162. package/static/config.d.mts +0 -5
  163. package/static/config.mjs +0 -105
@@ -0,0 +1,81 @@
1
+ import { CLI } from "./CLI.mjs";
2
+ import { BuildConfig } from "../../helpers/types.mjs";
3
+ import { ModuleLoader } from "../client/ModuleLoader.mjs";
4
+ import { ModuleManager } from "../managers/ModuleManager.mjs";
5
+ import { EventListeners } from "../client/EventListeners.mjs";
6
+ import { Logger } from "prtyprnt";
7
+ import { Client, Config } from "@reciple/core";
8
+ import { Options } from "unrun";
9
+ import { UserConfig } from "tsdown";
10
+
11
+ //#region src/classes/cli/ConfigReader.d.ts
12
+ declare module "@reciple/core" {
13
+ interface Config {
14
+ token?: string;
15
+ modules?: ModuleLoader.Config;
16
+ logger?: Logger | Logger.Options;
17
+ }
18
+ interface Client {
19
+ readonly modules: ModuleManager;
20
+ readonly moduleLoader: ModuleLoader;
21
+ readonly eventListeners: EventListeners;
22
+ readonly cli: CLI;
23
+ logger: Logger;
24
+ }
25
+ }
26
+ declare class ConfigReader {
27
+ readonly filepath: string;
28
+ private _client;
29
+ private _config;
30
+ private _build;
31
+ get client(): Client<boolean>;
32
+ get config(): Config;
33
+ get build(): UserConfig;
34
+ constructor(filepath: string);
35
+ read(options?: Omit<ConfigReader.ReadOptions, 'filepath'>): Promise<ConfigReader>;
36
+ create(options?: Omit<ConfigReader.CreateOptions, 'filepath'>): Promise<ConfigReader>;
37
+ exists(): Promise<boolean>;
38
+ static create(options: ConfigReader.CreateOptions): Promise<ConfigReader>;
39
+ static hasFile(filepath: string): Promise<boolean>;
40
+ static findConfig(directory: string, type?: 'ts' | 'js'): Promise<string | null>;
41
+ static getDefaultContent(type?: 'ts' | 'js'): Promise<string>;
42
+ }
43
+ declare namespace ConfigReader {
44
+ function getProjectLang(dir: string): Promise<'ts' | 'js'>;
45
+ interface Structure {
46
+ client: Client;
47
+ config: Config;
48
+ }
49
+ interface ReadOptions extends Options {
50
+ createIfNotExists?: boolean;
51
+ createOptions?: Omit<CreateOptions, 'path'>;
52
+ }
53
+ interface CreateOptions {
54
+ filepath: string;
55
+ overwrite?: boolean;
56
+ throwOnConflict?: boolean;
57
+ type?: 'ts' | 'js';
58
+ readOptions?: Omit<ReadOptions, ''>;
59
+ }
60
+ const FileTypes: {
61
+ ts: string[];
62
+ js: string[];
63
+ };
64
+ const defaultConfigFilePaths: {
65
+ ts: string;
66
+ js: string;
67
+ };
68
+ const defaultConfigFilenames: string[];
69
+ function normalizeTsdownConfig({
70
+ type,
71
+ overrides
72
+ }?: {
73
+ type?: 'ts' | 'js';
74
+ overrides?: BuildConfig;
75
+ }): UserConfig;
76
+ function createConfigFilename(type: 'ts' | 'js', esm?: boolean): string;
77
+ function getLangTypeFromFilename(filename: string): 'ts' | 'js' | null;
78
+ }
79
+ //#endregion
80
+ export { ConfigReader };
81
+ //# sourceMappingURL=ConfigReader.d.mts.map
@@ -0,0 +1,141 @@
1
+ import { CLI } from "./CLI.mjs";
2
+ import path from "node:path";
3
+ import { colors } from "@reciple/utils";
4
+ import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
5
+ import { Client, RecipleError } from "@reciple/core";
6
+ import { unrun } from "unrun";
7
+ import { resolveTSConfig } from "pkg-types";
8
+
9
+ //#region src/classes/cli/ConfigReader.ts
10
+ var ConfigReader = class ConfigReader {
11
+ _client = null;
12
+ _config = null;
13
+ _build = null;
14
+ get client() {
15
+ if (!this._client) throw new RecipleError("client is not yet loaded from config.");
16
+ return this._client;
17
+ }
18
+ get config() {
19
+ return this._config ?? {};
20
+ }
21
+ get build() {
22
+ return ConfigReader.normalizeTsdownConfig({ overrides: this._build ?? {} });
23
+ }
24
+ constructor(filepath) {
25
+ this.filepath = filepath;
26
+ }
27
+ async read(options) {
28
+ if (!await ConfigReader.hasFile(this.filepath) && options?.createIfNotExists !== false) return ConfigReader.create({
29
+ filepath: this.filepath,
30
+ readOptions: options
31
+ });
32
+ const { module } = await unrun({
33
+ ...options,
34
+ path: this.filepath
35
+ });
36
+ if (!module || !module.client || !(module.client instanceof Client)) throw new RecipleError(`exported client is not an instance of ${colors.cyan("Client")} from ${colors.green("\"@reciple/core\"")}.`);
37
+ this._client = module.client;
38
+ this._config = module.config;
39
+ this._build = module.build;
40
+ return this;
41
+ }
42
+ async create(options) {
43
+ return ConfigReader.create({
44
+ ...options,
45
+ filepath: this.filepath
46
+ });
47
+ }
48
+ async exists() {
49
+ return await ConfigReader.hasFile(this.filepath);
50
+ }
51
+ static async create(options) {
52
+ const type = options.type ?? ConfigReader.getLangTypeFromFilename(options.filepath) ?? "js";
53
+ if (await ConfigReader.hasFile(options.filepath) && !options.overwrite) {
54
+ if (options.throwOnConflict !== false) throw new RecipleError(`config file already exists at ${colors.green(options.filepath)}`);
55
+ const reader$1 = new ConfigReader(options.filepath);
56
+ await reader$1.read(options.readOptions);
57
+ return reader$1;
58
+ }
59
+ await mkdir(path.dirname(options.filepath), { recursive: true });
60
+ await writeFile(options.filepath, await this.getDefaultContent(type));
61
+ const reader = new ConfigReader(options.filepath);
62
+ await reader.read(options.readOptions);
63
+ return reader;
64
+ }
65
+ static async hasFile(filepath) {
66
+ return stat(filepath).then((s) => s.isFile()).catch(() => false);
67
+ }
68
+ static async findConfig(directory, type) {
69
+ const validFiles = ConfigReader.defaultConfigFilenames.filter((f) => type ? ConfigReader.FileTypes[type].includes(f) : true);
70
+ const files = (await readdir(directory)).find((f) => validFiles.includes(f));
71
+ return files ? path.join(directory, files) : null;
72
+ }
73
+ static async getDefaultContent(type = "js") {
74
+ const filepath = ConfigReader.defaultConfigFilePaths[type];
75
+ return await readFile(filepath, "utf-8");
76
+ }
77
+ };
78
+ (function(_ConfigReader) {
79
+ async function getProjectLang(dir) {
80
+ const hasTsConfig = !!await resolveTSConfig(dir, { try: true });
81
+ const configLangIsTypescript = (await ConfigReader.findConfig(dir).then((f) => f ?? "")).endsWith("ts");
82
+ return hasTsConfig || configLangIsTypescript ? "ts" : "js";
83
+ }
84
+ _ConfigReader.getProjectLang = getProjectLang;
85
+ const FileTypes = _ConfigReader.FileTypes = {
86
+ ts: [
87
+ "ts",
88
+ "mts",
89
+ "tsx"
90
+ ],
91
+ js: [
92
+ "js",
93
+ "mjs",
94
+ "jsx"
95
+ ]
96
+ };
97
+ _ConfigReader.defaultConfigFilePaths = {
98
+ ts: path.join(CLI.root, "assets/config", `reciple.config.ts`),
99
+ js: path.join(CLI.root, "assets/config", `reciple.config.js`)
100
+ };
101
+ _ConfigReader.defaultConfigFilenames = [
102
+ "reciple.config.ts",
103
+ "reciple.config.mts",
104
+ "reciple.config.js",
105
+ "reciple.config.mjs"
106
+ ];
107
+ function normalizeTsdownConfig({ type, overrides } = {}) {
108
+ return {
109
+ entry: [`./src/**/*.{ts,tsx,js,jsx}`],
110
+ outDir: "./modules",
111
+ tsconfig: `./${type ?? "ts"}config.json`,
112
+ external: [],
113
+ noExternal: [],
114
+ sourcemap: true,
115
+ treeshake: true,
116
+ clean: true,
117
+ ...overrides,
118
+ watch: false,
119
+ platform: "node",
120
+ format: "esm",
121
+ unbundle: true,
122
+ skipNodeModulesBundle: true
123
+ };
124
+ }
125
+ _ConfigReader.normalizeTsdownConfig = normalizeTsdownConfig;
126
+ function createConfigFilename(type, esm = false) {
127
+ return `reciple.config.${type === "ts" ? esm ? "mts" : "ts" : esm ? "mjs" : "js"}`;
128
+ }
129
+ _ConfigReader.createConfigFilename = createConfigFilename;
130
+ function getLangTypeFromFilename(filename) {
131
+ const extention = path.extname(filename).slice(1);
132
+ if (FileTypes.ts.includes(extention)) return "ts";
133
+ if (FileTypes.js.includes(extention)) return "js";
134
+ return null;
135
+ }
136
+ _ConfigReader.getLangTypeFromFilename = getLangTypeFromFilename;
137
+ })(ConfigReader || (ConfigReader = {}));
138
+
139
+ //#endregion
140
+ export { ConfigReader };
141
+ //# sourceMappingURL=ConfigReader.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigReader.mjs","names":["filepath: string","reader"],"sources":["../../../src/classes/cli/ConfigReader.ts"],"sourcesContent":["import { Client, RecipleError, type Config } from '@reciple/core';\nimport { colors } from '@reciple/utils';\nimport { CLI } from './CLI.js';\nimport path from 'node:path';\nimport { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport type { ModuleLoader } from '../client/ModuleLoader.js';\nimport type { Logger } from 'prtyprnt';\nimport type { ModuleManager } from '../managers/ModuleManager.js';\nimport type { BuildConfig } from '../../helpers/types.js';\nimport type { EventListeners } from '../client/EventListeners.js';\nimport type { UserConfig } from 'tsdown';\nimport { unrun, type Options } from 'unrun';\nimport { resolveTSConfig } from 'pkg-types';\n\ndeclare module \"@reciple/core\" {\n interface Config {\n token?: string;\n modules?: ModuleLoader.Config;\n logger?: Logger|Logger.Options;\n }\n\n interface Client {\n readonly modules: ModuleManager;\n readonly moduleLoader: ModuleLoader;\n readonly eventListeners: EventListeners;\n readonly cli: CLI;\n logger: Logger;\n }\n}\n\nexport class ConfigReader {\n private _client: Client|null = null;\n private _config: Config|null = null;\n private _build: BuildConfig|null = null;\n\n get client() {\n if (!this._client) throw new RecipleError('client is not yet loaded from config.');\n return this._client;\n }\n\n get config() {\n return this._config ?? {};\n }\n\n get build() {\n return ConfigReader.normalizeTsdownConfig({\n overrides: this._build ?? {}\n });\n }\n\n constructor(public readonly filepath: string) {}\n\n public async read(options?: Omit<ConfigReader.ReadOptions, 'filepath'>): Promise<ConfigReader> {\n if (!await ConfigReader.hasFile(this.filepath) && options?.createIfNotExists !== false) return ConfigReader.create({\n filepath: this.filepath,\n readOptions: options\n });\n\n const { module } = await unrun<Config>({ ...options, path: this.filepath });\n\n if (!module || !module.client || !(module.client instanceof Client)) {\n throw new RecipleError(`exported client is not an instance of ${colors.cyan('Client')} from ${colors.green('\"@reciple/core\"')}.`);\n }\n\n this._client = module.client;\n this._config = module.config;\n this._build = module.build;\n\n return this;\n }\n\n public async create(options?: Omit<ConfigReader.CreateOptions, 'filepath'>): Promise<ConfigReader> {\n return ConfigReader.create({ ...options, filepath: this.filepath });\n }\n\n public async exists(): Promise<boolean> {\n return await ConfigReader.hasFile(this.filepath);\n }\n\n public static async create(options: ConfigReader.CreateOptions): Promise<ConfigReader> {\n const type = options.type ?? ConfigReader.getLangTypeFromFilename(options.filepath) ?? 'js';\n\n if (await ConfigReader.hasFile(options.filepath) && !options.overwrite) {\n if (options.throwOnConflict !== false) throw new RecipleError(`config file already exists at ${colors.green(options.filepath)}`);\n\n const reader = new ConfigReader(options.filepath);\n await reader.read(options.readOptions);\n return reader;\n }\n\n await mkdir(path.dirname(options.filepath), { recursive: true });\n await writeFile(options.filepath, await this.getDefaultContent(type));\n\n const reader = new ConfigReader(options.filepath);\n\n await reader.read(options.readOptions);\n return reader;\n }\n\n public static async hasFile(filepath: string): Promise<boolean> {\n return stat(filepath)\n .then(s => s.isFile())\n .catch(() => false);\n }\n\n public static async findConfig(directory: string, type?: 'ts'|'js'): Promise<string|null> {\n const validFiles = ConfigReader.defaultConfigFilenames.filter(f => type ? ConfigReader.FileTypes[type].includes(f) : true);\n const files = (await readdir(directory)).find(f => validFiles.includes(f));\n return files ? path.join(directory, files) : null;\n }\n\n public static async getDefaultContent(type: 'ts'|'js' = 'js'): Promise<string> {\n const filepath = ConfigReader.defaultConfigFilePaths[type];\n const content = await readFile(filepath, 'utf-8');\n return content;\n }\n}\n\nexport namespace ConfigReader {\n export async function getProjectLang(dir: string): Promise<'ts'|'js'> {\n const hasTsConfig = !!await resolveTSConfig(dir, { try: true });\n const configLangIsTypescript = (await ConfigReader.findConfig(dir).then(f => f ?? '')).endsWith('ts');\n\n return hasTsConfig || configLangIsTypescript ? 'ts' : 'js';\n }\n\n export interface Structure {\n client: Client;\n config: Config;\n }\n\n export interface ReadOptions extends Options {\n createIfNotExists?: boolean;\n createOptions?: Omit<CreateOptions, 'path'>;\n }\n\n export interface CreateOptions {\n filepath: string;\n overwrite?: boolean;\n throwOnConflict?: boolean;\n type?: 'ts' | 'js';\n readOptions?: Omit<ReadOptions, ''>;\n }\n\n export const FileTypes = {\n ts: ['ts', 'mts', 'tsx'],\n js: ['js', 'mjs', 'jsx']\n };\n\n export const defaultConfigFilePaths = {\n ts: path.join(CLI.root, 'assets/config', `reciple.config.ts`),\n js: path.join(CLI.root, 'assets/config', `reciple.config.js`)\n };\n\n export const defaultConfigFilenames = [\n 'reciple.config.ts',\n 'reciple.config.mts',\n 'reciple.config.js',\n 'reciple.config.mjs'\n ];\n\n export function normalizeTsdownConfig({ type, overrides }: { type?: 'ts' | 'js', overrides?: BuildConfig; } = {}): UserConfig {\n return {\n entry: [`./src/**/*.{ts,tsx,js,jsx}`],\n outDir: './modules',\n tsconfig: `./${type ?? 'ts'}config.json`,\n external: [],\n noExternal: [],\n sourcemap: true,\n treeshake: true,\n clean: true,\n ...overrides,\n watch: false,\n platform: 'node',\n format: 'esm',\n unbundle: true,\n skipNodeModulesBundle: true\n };\n }\n\n export function createConfigFilename(type: 'ts'|'js', esm: boolean = false): string {\n return `reciple.config.${type === 'ts' ? esm ? 'mts' : 'ts' : esm ? 'mjs' : 'js'}`;\n }\n\n export function getLangTypeFromFilename(filename: string): 'ts'|'js'|null {\n const extention = path.extname(filename).slice(1);\n\n if (FileTypes.ts.includes(extention)) return 'ts';\n if (FileTypes.js.includes(extention)) return 'js';\n return null;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Client } from "@reciple/core";
2
+
3
+ //#region src/classes/cli/RuntimeEnvironment.d.ts
4
+ declare class RuntimeEnvironment {}
5
+ declare namespace RuntimeEnvironment {
6
+ let stopping: boolean;
7
+ type Type = 'node' | 'deno' | 'bun';
8
+ function get(): Type | null;
9
+ function sleep(time: number): Promise<void>;
10
+ function handleExitSignal(client: Client, signal: NodeJS.Signals): Promise<void>;
11
+ }
12
+ //#endregion
13
+ export { RuntimeEnvironment };
14
+ //# sourceMappingURL=RuntimeEnvironment.d.mts.map
@@ -0,0 +1,36 @@
1
+ import { colors } from "@reciple/utils";
2
+ import { setTimeout } from "node:timers/promises";
3
+
4
+ //#region src/classes/cli/RuntimeEnvironment.ts
5
+ var RuntimeEnvironment = class {};
6
+ (function(_RuntimeEnvironment) {
7
+ let stopping = _RuntimeEnvironment.stopping = false;
8
+ function get() {
9
+ if ("isBun" in process && process.isBun) return "bun";
10
+ if ("deno" in process.versions && process.versions.deno) return "deno";
11
+ if (process.versions.node) return "node";
12
+ return null;
13
+ }
14
+ _RuntimeEnvironment.get = get;
15
+ async function sleep(time) {
16
+ return setTimeout(time);
17
+ }
18
+ _RuntimeEnvironment.sleep = sleep;
19
+ async function handleExitSignal(client, signal) {
20
+ if (stopping) return;
21
+ stopping = true;
22
+ client.logger?.warn(`Received exit signal: ${signal}`);
23
+ await client.destroy();
24
+ client.eventListeners.unregisterAll();
25
+ const signalString = signal === "SIGINT" ? "keyboard interrupt" : signal === "SIGTERM" ? "terminate" : String(signal);
26
+ await sleep(10);
27
+ client.logger?.warn(`Process exited: ${colors.yellow(signalString)}`);
28
+ client.logger?.closeFileWriteStream();
29
+ process.exit(0);
30
+ }
31
+ _RuntimeEnvironment.handleExitSignal = handleExitSignal;
32
+ })(RuntimeEnvironment || (RuntimeEnvironment = {}));
33
+
34
+ //#endregion
35
+ export { RuntimeEnvironment };
36
+ //# sourceMappingURL=RuntimeEnvironment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeEnvironment.mjs","names":[],"sources":["../../../src/classes/cli/RuntimeEnvironment.ts"],"sourcesContent":["import { colors } from '@reciple/utils';\nimport type { Client } from '@reciple/core';\nimport { setTimeout } from 'node:timers/promises';\n\nexport class RuntimeEnvironment {}\n\nexport namespace RuntimeEnvironment {\n export let stopping = false;\n\n export type Type = 'node'|'deno'|'bun';\n\n export function get(): Type|null {\n if ('isBun' in process && process.isBun) return 'bun';\n if ('deno' in process.versions && process.versions.deno) return 'deno';\n if (process.versions.node) return 'node';\n\n return null;\n }\n\n export async function sleep(time: number): Promise<void> {\n return setTimeout(time);\n }\n\n export async function handleExitSignal(client: Client, signal: NodeJS.Signals) {\n if (stopping) return;\n\n stopping = true;\n\n client.logger?.warn(`Received exit signal: ${signal}`);\n\n await client.destroy();\n client.eventListeners.unregisterAll();\n\n const signalString = signal === 'SIGINT' ? 'keyboard interrupt' : signal === 'SIGTERM' ? 'terminate' : String(signal);\n\n await sleep(10);\n\n client.logger?.warn(`Process exited: ${colors.yellow(signalString)}`);\n client.logger?.closeFileWriteStream();\n process.exit(0);\n }\n}\n"],"mappings":";;;;AAIA,IAAa,qBAAb,MAAgC;;CAGrB,IAAI,0CAAW;CAIf,SAAS,MAAiB;AAC7B,MAAI,WAAW,WAAW,QAAQ,MAAO,QAAO;AAChD,MAAI,UAAU,QAAQ,YAAY,QAAQ,SAAS,KAAM,QAAO;AAChE,MAAI,QAAQ,SAAS,KAAM,QAAO;AAElC,SAAO;;;CAGJ,eAAe,MAAM,MAA6B;AACrD,SAAO,WAAW,KAAK;;;CAGpB,eAAe,iBAAiB,QAAgB,QAAwB;AAC3E,MAAI,SAAU;AAEd,aAAW;AAEX,SAAO,QAAQ,KAAK,yBAAyB,SAAS;AAEtD,QAAM,OAAO,SAAS;AACtB,SAAO,eAAe,eAAe;EAErC,MAAM,eAAe,WAAW,WAAW,uBAAuB,WAAW,YAAY,cAAc,OAAO,OAAO;AAErH,QAAM,MAAM,GAAG;AAEf,SAAO,QAAQ,KAAK,mBAAmB,OAAO,OAAO,aAAa,GAAG;AACrE,SAAO,QAAQ,sBAAsB;AACrC,UAAQ,KAAK,EAAE"}
@@ -0,0 +1,26 @@
1
+ import { Client } from "@reciple/core";
2
+ import { EventEmitter } from "node:events";
3
+
4
+ //#region src/classes/client/EventListeners.d.ts
5
+ declare class EventListeners {
6
+ registeredEvents: EventListeners.RegisteredEvent[];
7
+ register(event: EventListeners.RegisteredEvent): this;
8
+ unregister(event: EventListeners.RegisteredEvent): this;
9
+ unregisterAll(): this;
10
+ registerProcessExitEvents(listener: (signal: NodeJS.Signals) => any): this;
11
+ unregisterProcessExitEvents(listener: (signal: NodeJS.Signals) => any): this;
12
+ }
13
+ declare namespace EventListeners {
14
+ const processExitEvents: string[];
15
+ interface RegisteredEvent {
16
+ event: string | symbol;
17
+ emitter: EventEmitter;
18
+ once?: boolean;
19
+ onEvent: (...args: any) => any;
20
+ }
21
+ function registerLoggerEventListeners(client: Client): void;
22
+ function registerCommandsEventListeners(client: Client): void;
23
+ }
24
+ //#endregion
25
+ export { EventListeners };
26
+ //# sourceMappingURL=EventListeners.d.mts.map
@@ -0,0 +1,103 @@
1
+ import { BaseModule } from "../modules/BaseModule.mjs";
2
+ import { Format, colors } from "@reciple/utils";
3
+ import { CommandType } from "@reciple/core";
4
+
5
+ //#region src/classes/client/EventListeners.ts
6
+ var EventListeners = class EventListeners {
7
+ registeredEvents = [];
8
+ register(event) {
9
+ event.onEvent = event.onEvent.bind(event);
10
+ if (event.once) event.emitter.once(event.event, event.onEvent);
11
+ else event.emitter.on(event.event, event.onEvent);
12
+ this.registeredEvents.push(event);
13
+ return this;
14
+ }
15
+ unregister(event) {
16
+ event.emitter.removeListener(event.event, event.onEvent);
17
+ this.registeredEvents = this.registeredEvents.filter((e) => e !== event);
18
+ return this;
19
+ }
20
+ unregisterAll() {
21
+ this.registeredEvents.forEach((event) => this.unregister(event));
22
+ this.registeredEvents = [];
23
+ return this;
24
+ }
25
+ registerProcessExitEvents(listener) {
26
+ for (const event of EventListeners.processExitEvents) this.register({
27
+ emitter: process,
28
+ event,
29
+ onEvent: listener
30
+ });
31
+ return this;
32
+ }
33
+ unregisterProcessExitEvents(listener) {
34
+ for (const event of EventListeners.processExitEvents) this.unregister({
35
+ emitter: process,
36
+ event,
37
+ onEvent: listener
38
+ });
39
+ return this;
40
+ }
41
+ };
42
+ (function(_EventListeners) {
43
+ _EventListeners.processExitEvents = [
44
+ "SIGHUP",
45
+ "SIGINT",
46
+ "SIGQUIT",
47
+ "SIGABRT",
48
+ "SIGALRM",
49
+ "SIGTERM",
50
+ "SIGBREAK",
51
+ "SIGUSR2"
52
+ ];
53
+ function registerLoggerEventListeners(client) {
54
+ const defineModuleManagerEvent = (event, onEvent) => ({
55
+ emitter: client.modules,
56
+ event,
57
+ onEvent
58
+ });
59
+ const defineModuleLoaderEvent = (event, onEvent) => ({
60
+ emitter: client.moduleLoader,
61
+ event,
62
+ onEvent
63
+ });
64
+ const defineClientEvent = (event, onEvent) => ({
65
+ emitter: client,
66
+ event,
67
+ onEvent
68
+ });
69
+ const events = [
70
+ defineModuleManagerEvent("modulePreEnable", (module) => client.logger.log(`Enabling module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}`)),
71
+ defineModuleManagerEvent("moduleEnable", (module) => client.logger.log(`Enabled module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}`)),
72
+ defineModuleManagerEvent("modulePreReady", (module) => client.logger.log(`Preparing module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}`)),
73
+ defineModuleManagerEvent("moduleReady", (module) => client.logger.log(`Ready module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}`)),
74
+ defineModuleManagerEvent("modulePreDisable", (module) => client.logger.log(`Disabling module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}`)),
75
+ defineModuleManagerEvent("moduleDisable", (module) => client.logger.log(`Disabled module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}`)),
76
+ defineModuleManagerEvent("moduleEnableError", (module, error) => client.logger.error(`Failed to enable module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}:`, error)),
77
+ defineModuleManagerEvent("moduleReadyError", (module, error) => client.logger.error(`Failed to ready module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}:`, error)),
78
+ defineModuleManagerEvent("moduleDisableError", (module, error) => client.logger.error(`Failed to disable module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}:`, error)),
79
+ defineModuleLoaderEvent("modulesResolving", () => client.logger.log(colors.green("🔍 Resolving modules..."))),
80
+ defineModuleLoaderEvent("modulesResolved", (modules) => client.logger.log(colors.green(`✅ Resolved ${modules.length} ${Format.plural(modules.length, "module")}.`))),
81
+ defineModuleLoaderEvent("moduleResolving", (filepath) => client.logger.debug(`Resolving module ${colors.cyan(`"${filepath}"`)}`)),
82
+ defineModuleLoaderEvent("moduleResolved", (module) => client.logger.debug(`Resolved module ${colors.cyan(`"${BaseModule.getFilepath(module) || module.id}"`)}`)),
83
+ defineModuleLoaderEvent("moduleResolveError", (error) => client.logger.error(`Failed to resolve module:`, error)),
84
+ defineClientEvent("debug", (message) => client.logger.debug(message))
85
+ ];
86
+ for (const event of events) client.eventListeners.register(event);
87
+ }
88
+ _EventListeners.registerLoggerEventListeners = registerLoggerEventListeners;
89
+ function registerCommandsEventListeners(client) {
90
+ const defineCommandsEvent = (event, onEvent) => ({
91
+ emitter: client.commands,
92
+ event,
93
+ onEvent
94
+ });
95
+ const events = [defineCommandsEvent("applicationCommandsRegister", (commands, guildId) => client.logger.log(colors.green(`📩 Registered ${colors.cyan(commands.size)} application ${Format.plural(commands.size, "command")}${guildId ? ` to guild ${colors.magenta(guildId)}` : colors.magenta(" globally")}.`))), defineCommandsEvent("commandExecute", (data) => client.logger.debug(`Executed ${CommandType[data.command.type].toLowerCase()} command ${colors.cyan(`"${data.command.data.name}"`)} ${colors.magenta(`(${data.command.id})`)}`))];
96
+ for (const event of events) client.eventListeners.register(event);
97
+ }
98
+ _EventListeners.registerCommandsEventListeners = registerCommandsEventListeners;
99
+ })(EventListeners || (EventListeners = {}));
100
+
101
+ //#endregion
102
+ export { EventListeners };
103
+ //# sourceMappingURL=EventListeners.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventListeners.mjs","names":["events: RegisteredEvent[]"],"sources":["../../../src/classes/client/EventListeners.ts"],"sourcesContent":["import { CommandType, type Client, type CommandManager } from '@reciple/core';\nimport type { EventEmitter } from 'node:events';\nimport type { ModuleManager } from '../managers/ModuleManager.js';\nimport { BaseModule } from '../modules/BaseModule.js';\nimport { colors, Format } from '@reciple/utils';\nimport type { ModuleLoader } from './ModuleLoader.js';\n\nexport class EventListeners {\n public registeredEvents: EventListeners.RegisteredEvent[] = [];\n\n public register(event: EventListeners.RegisteredEvent): this {\n event.onEvent = event.onEvent.bind(event);\n\n if (event.once) {\n event.emitter.once(event.event, event.onEvent);\n } else {\n event.emitter.on(event.event, event.onEvent);\n }\n\n this.registeredEvents.push(event);\n return this;\n }\n\n public unregister(event: EventListeners.RegisteredEvent): this {\n event.emitter.removeListener(event.event, event.onEvent);\n this.registeredEvents = this.registeredEvents.filter(e => e !== event);\n return this;\n }\n\n public unregisterAll(): this {\n this.registeredEvents.forEach(event => this.unregister(event));\n this.registeredEvents = [];\n return this;\n }\n\n public registerProcessExitEvents(listener: (signal: NodeJS.Signals) => any): this {\n for (const event of EventListeners.processExitEvents) {\n this.register({ emitter: process, event, onEvent: listener });\n }\n\n return this;\n }\n\n public unregisterProcessExitEvents(listener: (signal: NodeJS.Signals) => any): this {\n for (const event of EventListeners.processExitEvents) {\n this.unregister({ emitter: process, event, onEvent: listener });\n }\n\n return this;\n }\n}\n\nexport namespace EventListeners {\n export const processExitEvents = [\n 'SIGHUP',\n 'SIGINT',\n 'SIGQUIT',\n 'SIGABRT',\n 'SIGALRM',\n 'SIGTERM',\n 'SIGBREAK',\n 'SIGUSR2',\n ];\n\n export interface RegisteredEvent {\n event: string|symbol;\n emitter: EventEmitter;\n once?: boolean;\n onEvent: (...args: any) => any;\n }\n\n export function registerLoggerEventListeners(client: Client) {\n const defineModuleManagerEvent = <E extends keyof ModuleManager.Events>(event: E, onEvent: (...args: ModuleManager.Events[E]) => any): RegisteredEvent => ({ emitter: client.modules, event, onEvent });\n const defineModuleLoaderEvent = <E extends keyof ModuleLoader.Events>(event: E, onEvent: (...args: ModuleLoader.Events[E]) => any): RegisteredEvent => ({ emitter: client.moduleLoader, event, onEvent });\n const defineClientEvent = <E extends keyof Client.Events>(event: E, onEvent: (...args: Client.Events[E]) => any): RegisteredEvent => ({ emitter: client, event, onEvent });\n\n const events: RegisteredEvent[] = [\n defineModuleManagerEvent('modulePreEnable', (module) => client.logger.log(`Enabling module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}`)),\n defineModuleManagerEvent('moduleEnable', (module) => client.logger.log(`Enabled module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}`)),\n defineModuleManagerEvent('modulePreReady', (module) => client.logger.log(`Preparing module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}`)),\n defineModuleManagerEvent('moduleReady', (module) => client.logger.log(`Ready module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}`)),\n defineModuleManagerEvent('modulePreDisable', (module) => client.logger.log(`Disabling module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}`)),\n defineModuleManagerEvent('moduleDisable', (module) => client.logger.log(`Disabled module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}`)),\n defineModuleManagerEvent('moduleEnableError', (module, error) => client.logger.error(`Failed to enable module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}:`, error)),\n defineModuleManagerEvent('moduleReadyError', (module, error) => client.logger.error(`Failed to ready module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}:`, error)),\n defineModuleManagerEvent('moduleDisableError', (module, error) => client.logger.error(`Failed to disable module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}:`, error)),\n defineModuleLoaderEvent('modulesResolving', () => client.logger.log(colors.green('🔍 Resolving modules...'))),\n defineModuleLoaderEvent('modulesResolved', (modules) => client.logger.log(colors.green(`✅ Resolved ${modules.length} ${Format.plural(modules.length, 'module')}.`))),\n defineModuleLoaderEvent('moduleResolving', (filepath) => client.logger.debug(`Resolving module ${colors.cyan(`\"${filepath}\"`)}`)),\n defineModuleLoaderEvent('moduleResolved', (module) => client.logger.debug(`Resolved module ${colors.cyan(`\"${BaseModule.getFilepath(module) || module.id}\"`)}`)),\n defineModuleLoaderEvent('moduleResolveError', (error) => client.logger.error(`Failed to resolve module:`, error)),\n defineClientEvent('debug', (message) => client.logger.debug(message)),\n ];\n\n for (const event of events) {\n client.eventListeners.register(event);\n }\n }\n\n export function registerCommandsEventListeners(client: Client) {\n const defineCommandsEvent = <E extends keyof CommandManager.Events>(event: E, onEvent: (...args: CommandManager.Events[E]) => any): RegisteredEvent => ({ emitter: client.commands!, event, onEvent });\n\n const events: RegisteredEvent[] = [\n defineCommandsEvent('applicationCommandsRegister', (commands, guildId) => client.logger.log(colors.green(`📩 Registered ${colors.cyan(commands.size)} application ${Format.plural(commands.size, 'command')}${guildId ? ` to guild ${colors.magenta(guildId)}` : colors.magenta(' globally')}.`))),\n defineCommandsEvent('commandExecute', (data) => client.logger.debug(`Executed ${CommandType[data.command.type].toLowerCase()} command ${colors.cyan(`\"${data.command.data.name}\"`)} ${colors.magenta(`(${data.command.id})`)}`)),\n ];\n\n for (const event of events) {\n client.eventListeners.register(event);\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { AnyModule } from "../../helpers/types.mjs";
2
+ import { Logger } from "prtyprnt";
3
+ import { Client, RecipleError } from "@reciple/core";
4
+ import { Awaitable } from "discord.js";
5
+ import * as globby0 from "globby";
6
+ import { EventEmitter } from "node:events";
7
+
8
+ //#region src/classes/client/ModuleLoader.d.ts
9
+ declare class ModuleLoader extends EventEmitter<ModuleLoader.Events> {
10
+ readonly client: Client;
11
+ readonly logger: Logger;
12
+ constructor(client: Client);
13
+ findModules(ignoreErrors?: boolean): Promise<AnyModule[]>;
14
+ static scanForDirectories(config?: Pick<ModuleLoader.Config, 'directories' | 'ignore'> & {
15
+ cwd?: string;
16
+ createDirectories?: boolean;
17
+ }): Promise<string[]>;
18
+ static scanForModules(config?: ModuleLoader.Config & {
19
+ cwd?: string;
20
+ createDirectories?: boolean;
21
+ }): Promise<string[]>;
22
+ static resolveModulePath(filepath: string, options?: {
23
+ cwd?: string;
24
+ }): Promise<AnyModule>;
25
+ static resolveSourceDirectories(options: ModuleLoader.ResolveSourceDirectoryOptions): Promise<string[]>;
26
+ private emitOrThrow;
27
+ }
28
+ declare namespace ModuleLoader {
29
+ let globby: typeof globby0 | null;
30
+ const fileTypes: string[];
31
+ interface Config {
32
+ directories?: string[];
33
+ ignore?: string[];
34
+ filter?: (filepath: string) => Awaitable<boolean>;
35
+ sort?: (a: string, b: string) => number;
36
+ }
37
+ interface Events {
38
+ moduleResolveError: [error: RecipleError];
39
+ moduleResolved: [module: AnyModule];
40
+ moduleResolving: [filepath: string];
41
+ modulesResolved: [modules: AnyModule[]];
42
+ modulesResolving: [files: string[]];
43
+ }
44
+ interface ResolveSourceDirectoryOptions {
45
+ directories: string[];
46
+ baseUrl: string;
47
+ rootDir: string;
48
+ outDir: string;
49
+ cwd?: string;
50
+ }
51
+ function getGlobby(): Promise<typeof globby0>;
52
+ }
53
+ //#endregion
54
+ export { ModuleLoader };
55
+ //# sourceMappingURL=ModuleLoader.d.mts.map
@@ -0,0 +1,152 @@
1
+ import { ModuleType } from "../../helpers/constants.mjs";
2
+ import { BaseModule } from "../modules/BaseModule.mjs";
3
+ import { BaseModuleValidator } from "../validation/BaseModuleValidator.mjs";
4
+ import { PostconditionModule } from "../modules/PostconditionModule.mjs";
5
+ import { PreconditionModule } from "../modules/PreconditionModule.mjs";
6
+ import { EventModule } from "../modules/events/EventModule.mjs";
7
+ import { MessageCommandModule } from "../modules/commands/MessageCommandModule.mjs";
8
+ import { SlashCommandModule } from "../modules/commands/SlashCommandModule.mjs";
9
+ import { ContextMenuCommandModule } from "../modules/commands/ContextMenuCommandModule.mjs";
10
+ import { CommandModuleValidator } from "../validation/CommandModuleValidator.mjs";
11
+ import { EventModuleValidator } from "../validation/EventModuleValidator.mjs";
12
+ import { PreconditionModuleValidator } from "../validation/PreconditionModule.mjs";
13
+ import { PostconditionModuleValidator } from "../validation/PostconditionModule.mjs";
14
+ import path from "node:path";
15
+ import { colors, recursiveDefaults } from "@reciple/utils";
16
+ import { mkdir, readdir, stat } from "node:fs/promises";
17
+ import { CommandType, RecipleError } from "@reciple/core";
18
+ import "discord.js";
19
+ import micromatch from "micromatch";
20
+ import { globby, isDynamicPattern } from "globby";
21
+ import { EventEmitter } from "node:events";
22
+
23
+ //#region src/classes/client/ModuleLoader.ts
24
+ var ModuleLoader = class ModuleLoader extends EventEmitter {
25
+ logger;
26
+ constructor(client) {
27
+ super();
28
+ this.client = client;
29
+ this.logger = this.client.logger.clone({ label: "ModuleLoader" });
30
+ }
31
+ async findModules(ignoreErrors = false) {
32
+ const modulePaths = await ModuleLoader.scanForModules(this.client.config?.modules);
33
+ const modules = [];
34
+ this.emit("modulesResolving", modulePaths);
35
+ for (const path$1 of modulePaths) try {
36
+ this.emit("moduleResolving", path$1);
37
+ const resolved = await ModuleLoader.resolveModulePath(path$1);
38
+ Object.assign(resolved, {
39
+ client: this.client,
40
+ __$filepath: path$1
41
+ });
42
+ modules.push(resolved);
43
+ this.emit("moduleResolved", resolved);
44
+ } catch (error) {
45
+ if (ignoreErrors) continue;
46
+ this.emitOrThrow("moduleResolveError", new RecipleError({
47
+ message: `Failed to load module: ${colors.cyan(path$1)}`,
48
+ cause: error
49
+ }));
50
+ }
51
+ this.emit("modulesResolved", modules);
52
+ return modules;
53
+ }
54
+ static async scanForDirectories(config) {
55
+ const cwd = config?.cwd ?? process.cwd();
56
+ let scanned = [];
57
+ let directories = [];
58
+ for (const directory of config?.directories ?? []) {
59
+ if (isDynamicPattern(directory, { cwd })) {
60
+ const matches = await globby(directory, {
61
+ cwd,
62
+ ignore: config?.ignore,
63
+ onlyDirectories: true,
64
+ baseNameMatch: true,
65
+ absolute: true
66
+ });
67
+ scanned.push(...matches);
68
+ continue;
69
+ }
70
+ scanned.push(path.join(cwd, directory));
71
+ }
72
+ for (const directory of scanned) {
73
+ if (!await stat(directory).catch(() => void 0) && config?.createDirectories !== false) await mkdir(directory, { recursive: true });
74
+ directories.push(directory);
75
+ }
76
+ return directories;
77
+ }
78
+ static async scanForModules(config) {
79
+ const directories = await ModuleLoader.scanForDirectories(config);
80
+ let modules = [];
81
+ for (const directory of directories) {
82
+ let files = await readdir(directory);
83
+ if (config?.ignore?.length) files = micromatch.not(files, config.ignore, {
84
+ cwd: directory,
85
+ matchBase: true,
86
+ dot: true
87
+ });
88
+ files = files.map((f) => path.join(directory, f));
89
+ for (const file of files) {
90
+ if (config?.filter ? !await config?.filter(file) : ModuleLoader.fileTypes.every((type) => !file.endsWith(`.${type}`))) continue;
91
+ modules.push(file);
92
+ }
93
+ }
94
+ if (config?.sort) modules.sort(config.sort);
95
+ return modules;
96
+ }
97
+ static async resolveModulePath(filepath, options) {
98
+ if (!await stat(filepath).catch(() => void 0)) throw new RecipleError(`Module not found: ${filepath}`);
99
+ const data = recursiveDefaults(await import(`file://${path.resolve(options?.cwd ?? process.cwd(), filepath)}`));
100
+ if (BaseModule.isModule(data)) return data;
101
+ switch (data?.moduleType) {
102
+ case ModuleType.Command:
103
+ CommandModuleValidator.isValid(data);
104
+ switch (data.type) {
105
+ case CommandType.Message: return MessageCommandModule.from(data);
106
+ case CommandType.Slash: return SlashCommandModule.from(data);
107
+ case CommandType.ContextMenu: return ContextMenuCommandModule.from(data);
108
+ default: throw new RecipleError(`Unknown command type from module: ${colors.cyan(filepath)}`);
109
+ }
110
+ case ModuleType.Event:
111
+ EventModuleValidator.isValid(data);
112
+ return EventModule.from(data);
113
+ case ModuleType.Precondition:
114
+ PreconditionModuleValidator.isValid(data);
115
+ return PreconditionModule.from(data);
116
+ case ModuleType.Postcondition:
117
+ PostconditionModuleValidator.isValid(data);
118
+ return PostconditionModule.from(data);
119
+ case ModuleType.Base:
120
+ default:
121
+ BaseModuleValidator.isValid(data);
122
+ return BaseModule.from(data);
123
+ }
124
+ }
125
+ static async resolveSourceDirectories(options) {
126
+ const dir = path.isAbsolute(options.baseUrl) ? options.baseUrl : path.resolve(path.join(options.cwd ?? process.cwd(), options.baseUrl));
127
+ const root = path.resolve(path.join(dir, options.rootDir));
128
+ const out = path.resolve(path.join(dir, options.outDir));
129
+ return options.directories.map((directory) => path.resolve(directory).replace(out, root));
130
+ }
131
+ emitOrThrow(event, error) {
132
+ if (this.client.listenerCount(event) > 0) return this.emit(event, error);
133
+ throw error;
134
+ }
135
+ };
136
+ (function(_ModuleLoader) {
137
+ let globby$1 = _ModuleLoader.globby = null;
138
+ _ModuleLoader.fileTypes = [
139
+ "js",
140
+ "mjs",
141
+ "jsx"
142
+ ];
143
+ async function getGlobby() {
144
+ if (globby$1) return globby$1;
145
+ return globby$1 = await import("globby");
146
+ }
147
+ _ModuleLoader.getGlobby = getGlobby;
148
+ })(ModuleLoader || (ModuleLoader = {}));
149
+
150
+ //#endregion
151
+ export { ModuleLoader };
152
+ //# sourceMappingURL=ModuleLoader.mjs.map