reciple 10.0.1-dev.1 → 10.0.1-dev.11

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 (46) hide show
  1. package/assets/templates/javascript/jsconfig.json +14 -2
  2. package/assets/templates/typescript/tsconfig.json +14 -2
  3. package/dist/_virtual/{_@oxc-project_runtime@0.99.0 → _@oxc-project_runtime@0.103.0}/helpers/decorate.mjs +1 -1
  4. package/dist/bin/commands/build.mjs +1 -1
  5. package/dist/bin/commands/build.mjs.map +1 -1
  6. package/dist/bin/commands/create.mjs +6 -7
  7. package/dist/bin/commands/create.mjs.map +1 -1
  8. package/dist/bin/commands/createModule.mjs +1 -1
  9. package/dist/bin/commands/createModule.mjs.map +1 -1
  10. package/dist/bin/commands/start.mjs +8 -8
  11. package/dist/bin/commands/start.mjs.map +1 -1
  12. package/dist/bin/reciple.mjs +0 -0
  13. package/dist/classes/cli/CLI.d.mts +1 -1
  14. package/dist/classes/cli/CLI.mjs +2 -2
  15. package/dist/classes/cli/CLI.mjs.map +1 -1
  16. package/dist/classes/cli/ConfigReader.d.mts +21 -29
  17. package/dist/classes/cli/ConfigReader.mjs +39 -62
  18. package/dist/classes/cli/ConfigReader.mjs.map +1 -1
  19. package/dist/classes/client/EventListeners.mjs +1 -1
  20. package/dist/classes/client/EventListeners.mjs.map +1 -1
  21. package/dist/classes/client/ModuleLoader.d.mts +1 -1
  22. package/dist/classes/client/ModuleLoader.mjs.map +1 -1
  23. package/dist/classes/managers/ModuleManager.mjs +1 -1
  24. package/dist/classes/modules/PostconditionModule.mjs +1 -1
  25. package/dist/classes/modules/PreconditionModule.mjs +1 -1
  26. package/dist/classes/modules/commands/ContextMenuCommandModule.mjs +1 -1
  27. package/dist/classes/modules/commands/MessageCommandModule.mjs +1 -1
  28. package/dist/classes/modules/commands/SlashCommandModule.mjs +1 -1
  29. package/dist/classes/templates/TemplateBuilder.d.mts +7 -2
  30. package/dist/classes/templates/TemplateBuilder.mjs +108 -77
  31. package/dist/classes/templates/TemplateBuilder.mjs.map +1 -1
  32. package/dist/classes/validation/BaseModuleValidator.d.mts +11 -11
  33. package/dist/classes/validation/CommandModuleValidator.d.mts +18 -18
  34. package/dist/classes/validation/EventModuleValidator.d.mts +9 -9
  35. package/dist/classes/validation/PostconditionModule.d.mts +8 -8
  36. package/dist/classes/validation/PreconditionModule.d.mts +8 -8
  37. package/dist/helpers/constants.d.mts +1 -2
  38. package/dist/helpers/constants.mjs +1 -1
  39. package/dist/helpers/constants.mjs.map +1 -1
  40. package/dist/index.d.mts +3 -3
  41. package/dist/index.mjs +3 -3
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/package.mjs +12 -15
  44. package/dist/package.mjs.map +1 -1
  45. package/package.json +12 -15
  46. package/LICENSE +0 -155
@@ -1 +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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"}
1
+ {"version":3,"file":"ConfigReader.mjs","names":["filepath: string"],"sources":["../../../src/classes/cli/ConfigReader.ts"],"sourcesContent":["import type { ModuleLoader } from '../client/ModuleLoader.js';\nimport type { ModuleManager } from '../managers/ModuleManager.js';\nimport type { EventListeners } from '../client/EventListeners.js';\nimport type { Logger } from '@prtty/print';\nimport { CLI } from './CLI.js';\nimport { Client, RecipleError, type Config } from '@reciple/core';\nimport type { BuildConfig } from '../../helpers/types.js';\nimport type { UserConfig as TsdownConfig } from 'tsdown';\nimport path from 'node:path';\nimport { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport { resolveTSConfig } from 'pkg-types';\nimport { unrun, type Options as UnrunOptions } from 'unrun';\nimport { colors } from '@reciple/utils';\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<UnrunOptions, 'path'>): Promise<ConfigReader> {\n const { module } = await unrun<Config>({\n ...options,\n path: this.filepath\n });\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, 'path'>): Promise<ConfigReader> {\n const exists = await ConfigReader.exists(this.filepath);\n\n if (exists && options.throwIfExists === true) {\n throw new RecipleError(`Config file already exists at ${colors.green(path.relative(process.cwd(), this.filepath))}.`);\n }\n\n if (!exists || exists && options.overwrite !== false) {\n await mkdir(path.dirname(this.filepath), { recursive: true });\n await writeFile(this.filepath, await ConfigReader.getDefaultContent(options.type));\n }\n\n return this.read(options.readOptions);\n }\n\n public static async exists(file: string): Promise<boolean> {\n return await stat(file).then(s => s.isFile()).catch(() => false);\n }\n\n public static async create(options: ConfigReader.CreateOptions): Promise<ConfigReader> {\n return new ConfigReader(options.path).create(options);\n }\n\n public static async find(options?: ConfigReader.FindOptions): Promise<string|null> {\n const filenames = ConfigReader.configFilenames.filter(f => !options?.lang || f.endsWith(options.lang));\n const cwd = options?.cwd ?? process.cwd();\n const directories = [cwd];\n\n directories.push(...(options?.directories ?? [path.join(cwd, '.config')]));\n\n for (const directory of directories) {\n const stats = await stat(directory).catch(() => undefined);\n\n if (!stats?.isDirectory()) continue;\n\n const file = (await readdir(directory)).find(f => filenames.includes(f));\n if (file) return path.join(directory, file);\n }\n\n return null;\n }\n}\n\nexport namespace ConfigReader {\n export interface CreateOptions {\n path: string;\n overwrite?: boolean;\n throwIfExists?: boolean;\n type: LangType;\n readOptions?: Omit<UnrunOptions, 'path'>;\n }\n\n export interface FindOptions {\n cwd?: string;\n lang?: LangType;\n directories?: string[];\n }\n\n export async function getProjectLang(cwd: string): Promise<LangType> {\n const hasTsConfig = !!await resolveTSConfig(cwd, { try: true });\n const configLangIsTypescript = !!(await ConfigReader.find({ cwd, lang: 'ts' }));\n\n return hasTsConfig || configLangIsTypescript ? 'ts' : 'js';\n }\n\n export type LangType = 'ts'|'js';\n\n export const defaultConfigPath = {\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 async function getDefaultContent(type: LangType): Promise<string> {\n const filepath = ConfigReader.defaultConfigPath[type];\n const content = await readFile(filepath, 'utf-8');\n return content;\n }\n\n export const configFilenames = [\n 'reciple.config.ts',\n 'reciple.config.mts',\n 'reciple.config.js',\n 'reciple.config.mjs'\n ];\n\n export function createConfigFilename(type: LangType, esm: boolean = false): string {\n return `reciple.config.${esm ? 'm' : ''}${type}`;\n }\n\n export function normalizeTsdownConfig({ type, overrides }: { type?: LangType; overrides?: BuildConfig; } = {}): TsdownConfig {\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"],"mappings":"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"}
@@ -92,7 +92,7 @@ var EventListeners = class EventListeners {
92
92
  event,
93
93
  onEvent
94
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})`)}`))];
95
+ const events = [defineCommandsEvent("applicationCommandsRegister", (commands, guildId) => client.logger.log(colors.green(`📩 Registered ${colors.cyan(commands.size.toLocaleString())} 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
96
  for (const event of events) client.eventListeners.register(event);
97
97
  }
98
98
  _EventListeners.registerCommandsEventListeners = registerCommandsEventListeners;
@@ -1 +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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"}
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.toLocaleString())} 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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"}
@@ -1,5 +1,5 @@
1
1
  import { AnyModule } from "../../helpers/types.mjs";
2
- import { Logger } from "prtyprnt";
2
+ import { Logger } from "@prtty/print";
3
3
  import { Client, RecipleError } from "@reciple/core";
4
4
  import { Awaitable } from "discord.js";
5
5
  import * as globby0 from "globby";
@@ -1 +1 @@
1
- {"version":3,"file":"ModuleLoader.mjs","names":["client: Client","modules: AnyModule[]","path","scanned: string[]","directories: string[]","modules: string[]","globby: typeof import('globby')|null","globby"],"sources":["../../../src/classes/client/ModuleLoader.ts"],"sourcesContent":["import { type Awaitable } from 'discord.js';\nimport path from 'node:path';\nimport { mkdir, readdir, stat } from 'node:fs/promises';\nimport micromatch from 'micromatch';\nimport { globby, isDynamicPattern } from 'globby';\nimport { CommandType, RecipleError, type Client } from '@reciple/core';\nimport type { AnyModule, AnyModuleData } from '../../helpers/types.js';\nimport { colors, recursiveDefaults } from '@reciple/utils';\nimport { BaseModule } from '../modules/BaseModule.js';\nimport { BaseModuleValidator } from '../validation/BaseModuleValidator.js';\nimport { ModuleType } from '../../helpers/constants.js';\nimport { PostconditionModule } from '../modules/PostconditionModule.js';\nimport { PreconditionModule } from '../modules/PreconditionModule.js';\nimport { EventModule } from '../modules/events/EventModule.js';\nimport { MessageCommandModule } from '../modules/commands/MessageCommandModule.js';\nimport { SlashCommandModule } from '../modules/commands/SlashCommandModule.js';\nimport { ContextMenuCommandModule } from '../modules/commands/ContextMenuCommandModule.js';\nimport { CommandModuleValidator } from '../validation/CommandModuleValidator.js';\nimport { EventModuleValidator } from '../validation/EventModuleValidator.js';\nimport { PreconditionModuleValidator } from '../validation/PreconditionModule.js';\nimport { PostconditionModuleValidator } from '../validation/PostconditionModule.js';\nimport type { Logger } from 'prtyprnt';\nimport { EventEmitter } from 'node:events';\n\nexport class ModuleLoader extends EventEmitter<ModuleLoader.Events> {\n public readonly logger: Logger;\n\n constructor(public readonly client: Client) {\n super();\n\n this.logger = this.client.logger.clone({\n label: 'ModuleLoader'\n });\n }\n\n public async findModules(ignoreErrors: boolean = false): Promise<AnyModule[]> {\n const modulePaths = await ModuleLoader.scanForModules(this.client.config?.modules);\n const modules: AnyModule[] = [];\n\n this.emit('modulesResolving', modulePaths);\n\n for (const path of modulePaths) {\n try {\n this.emit('moduleResolving', path);\n const resolved = await ModuleLoader.resolveModulePath(path);\n\n Object.assign(resolved, { client: this.client, __$filepath: path });\n modules.push(resolved);\n\n this.emit('moduleResolved', resolved);\n } catch (error) {\n if (ignoreErrors) continue;\n\n this.emitOrThrow('moduleResolveError', new RecipleError({\n message: `Failed to load module: ${colors.cyan(path)}`,\n cause: error\n }));\n }\n }\n\n this.emit('modulesResolved', modules);\n return modules;\n }\n\n public static async scanForDirectories(config?: Pick<ModuleLoader.Config, 'directories'|'ignore'> & { cwd?: string; createDirectories?: boolean; }) {\n const cwd = config?.cwd ?? process.cwd();\n\n let scanned: string[] = [];\n let directories: string[] = [];\n\n for (const directory of config?.directories ?? []) {\n if (isDynamicPattern(directory, { cwd })) {\n const matches = await globby(directory, {\n cwd,\n ignore: config?.ignore,\n onlyDirectories: true,\n baseNameMatch: true,\n absolute: true\n });\n\n scanned.push(...matches);\n continue;\n }\n\n scanned.push(path.join(cwd, directory));\n }\n\n for (const directory of scanned) {\n const stats = await stat(directory).catch(() => undefined);\n\n if (!stats && config?.createDirectories !== false) {\n await mkdir(directory, { recursive: true });\n }\n\n directories.push(directory);\n }\n\n return directories;\n }\n\n public static async scanForModules(config?: ModuleLoader.Config & { cwd?: string; createDirectories?: boolean; }): Promise<string[]> {\n const directories = await ModuleLoader.scanForDirectories(config);\n\n let modules: string[] = [];\n\n for (const directory of directories) {\n let files = await readdir(directory);\n\n if (config?.ignore?.length) {\n files = micromatch.not(files, config.ignore, {\n cwd: directory,\n matchBase: true,\n dot: true\n });\n }\n\n files = files.map(f => path.join(directory, f));\n\n for (const file of files) {\n if (config?.filter ? !(await config?.filter(file)) : ModuleLoader.fileTypes.every(type => !file.endsWith(`.${type}`))) continue;\n modules.push(file);\n }\n }\n\n if (config?.sort) modules.sort(config.sort);\n\n return modules;\n }\n\n public static async resolveModulePath(filepath: string, options?: { cwd?: string; }): Promise<AnyModule> {\n const stats = await stat(filepath).catch(() => undefined);\n if (!stats) throw new RecipleError(`Module not found: ${filepath}`);\n\n const data = recursiveDefaults<AnyModule|AnyModuleData|undefined>(await import(`file://${path.resolve(options?.cwd ?? process.cwd(), filepath)}`));\n if (BaseModule.isModule(data)) return data;\n\n switch (data?.moduleType) {\n case ModuleType.Command:\n CommandModuleValidator.isValid(data);\n switch (data.type) {\n case CommandType.Message: return MessageCommandModule.from(data);\n case CommandType.Slash: return SlashCommandModule.from(data);\n case CommandType.ContextMenu: return ContextMenuCommandModule.from(data);\n default: throw new RecipleError(`Unknown command type from module: ${colors.cyan(filepath)}`);\n }\n case ModuleType.Event:\n EventModuleValidator.isValid(data);\n return EventModule.from(data);\n case ModuleType.Precondition:\n PreconditionModuleValidator.isValid(data);\n return PreconditionModule.from(data);\n case ModuleType.Postcondition:\n PostconditionModuleValidator.isValid(data);\n return PostconditionModule.from(data);\n case ModuleType.Base:\n default:\n BaseModuleValidator.isValid(data);\n return BaseModule.from(data);\n }\n }\n\n public static async resolveSourceDirectories(options: ModuleLoader.ResolveSourceDirectoryOptions): Promise<string[]> {\n const dir = path.isAbsolute(options.baseUrl) ? options.baseUrl : path.resolve(path.join(options.cwd ?? process.cwd(), options.baseUrl));\n\n const root = path.resolve(path.join(dir, options.rootDir));\n const out = path.resolve(path.join(dir, options.outDir));\n\n return options.directories.map(directory => path.resolve(directory).replace(out, root));\n }\n\n private emitOrThrow<K extends keyof Pick<ModuleLoader.Events, 'moduleResolveError'>>(event: K, error: RecipleError) {\n if (this.client.listenerCount(event) > 0) {\n // @ts-expect-error\n return this.emit(event, error);\n }\n\n throw error;\n }\n}\n\nexport namespace ModuleLoader {\n export let globby: typeof import('globby')|null = null;\n\n export const fileTypes = [\n 'js',\n 'mjs',\n 'jsx'\n ];\n\n export interface Config {\n directories?: string[];\n ignore?: string[];\n filter?: (filepath: string) => Awaitable<boolean>;\n sort?: (a: string, b: string) => number;\n }\n\n export interface Events {\n moduleResolveError: [error: RecipleError];\n moduleResolved: [module: AnyModule];\n moduleResolving: [filepath: string];\n modulesResolved: [modules: AnyModule[]];\n modulesResolving: [files: string[]];\n }\n\n export interface ResolveSourceDirectoryOptions {\n directories: string[];\n baseUrl: string;\n rootDir: string;\n outDir: string;\n cwd?: string;\n }\n\n export async function getGlobby(): Promise<typeof import('globby')> {\n if (globby) return globby;\n\n return globby = await import('globby');\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ModuleLoader.mjs","names":["client: Client","modules: AnyModule[]","path","scanned: string[]","directories: string[]","modules: string[]","globby: typeof import('globby')|null","globby"],"sources":["../../../src/classes/client/ModuleLoader.ts"],"sourcesContent":["import { type Awaitable } from 'discord.js';\nimport path from 'node:path';\nimport { mkdir, readdir, stat } from 'node:fs/promises';\nimport micromatch from 'micromatch';\nimport { globby, isDynamicPattern } from 'globby';\nimport { CommandType, RecipleError, type Client } from '@reciple/core';\nimport type { AnyModule, AnyModuleData } from '../../helpers/types.js';\nimport { colors, recursiveDefaults } from '@reciple/utils';\nimport { BaseModule } from '../modules/BaseModule.js';\nimport { BaseModuleValidator } from '../validation/BaseModuleValidator.js';\nimport { ModuleType } from '../../helpers/constants.js';\nimport { PostconditionModule } from '../modules/PostconditionModule.js';\nimport { PreconditionModule } from '../modules/PreconditionModule.js';\nimport { EventModule } from '../modules/events/EventModule.js';\nimport { MessageCommandModule } from '../modules/commands/MessageCommandModule.js';\nimport { SlashCommandModule } from '../modules/commands/SlashCommandModule.js';\nimport { ContextMenuCommandModule } from '../modules/commands/ContextMenuCommandModule.js';\nimport { CommandModuleValidator } from '../validation/CommandModuleValidator.js';\nimport { EventModuleValidator } from '../validation/EventModuleValidator.js';\nimport { PreconditionModuleValidator } from '../validation/PreconditionModule.js';\nimport { PostconditionModuleValidator } from '../validation/PostconditionModule.js';\nimport type { Logger } from '@prtty/print';\nimport { EventEmitter } from 'node:events';\n\nexport class ModuleLoader extends EventEmitter<ModuleLoader.Events> {\n public readonly logger: Logger;\n\n constructor(public readonly client: Client) {\n super();\n\n this.logger = this.client.logger.clone({\n label: 'ModuleLoader'\n });\n }\n\n public async findModules(ignoreErrors: boolean = false): Promise<AnyModule[]> {\n const modulePaths = await ModuleLoader.scanForModules(this.client.config?.modules);\n const modules: AnyModule[] = [];\n\n this.emit('modulesResolving', modulePaths);\n\n for (const path of modulePaths) {\n try {\n this.emit('moduleResolving', path);\n const resolved = await ModuleLoader.resolveModulePath(path);\n\n Object.assign(resolved, { client: this.client, __$filepath: path });\n modules.push(resolved);\n\n this.emit('moduleResolved', resolved);\n } catch (error) {\n if (ignoreErrors) continue;\n\n this.emitOrThrow('moduleResolveError', new RecipleError({\n message: `Failed to load module: ${colors.cyan(path)}`,\n cause: error\n }));\n }\n }\n\n this.emit('modulesResolved', modules);\n return modules;\n }\n\n public static async scanForDirectories(config?: Pick<ModuleLoader.Config, 'directories'|'ignore'> & { cwd?: string; createDirectories?: boolean; }) {\n const cwd = config?.cwd ?? process.cwd();\n\n let scanned: string[] = [];\n let directories: string[] = [];\n\n for (const directory of config?.directories ?? []) {\n if (isDynamicPattern(directory, { cwd })) {\n const matches = await globby(directory, {\n cwd,\n ignore: config?.ignore,\n onlyDirectories: true,\n baseNameMatch: true,\n absolute: true\n });\n\n scanned.push(...matches);\n continue;\n }\n\n scanned.push(path.join(cwd, directory));\n }\n\n for (const directory of scanned) {\n const stats = await stat(directory).catch(() => undefined);\n\n if (!stats && config?.createDirectories !== false) {\n await mkdir(directory, { recursive: true });\n }\n\n directories.push(directory);\n }\n\n return directories;\n }\n\n public static async scanForModules(config?: ModuleLoader.Config & { cwd?: string; createDirectories?: boolean; }): Promise<string[]> {\n const directories = await ModuleLoader.scanForDirectories(config);\n\n let modules: string[] = [];\n\n for (const directory of directories) {\n let files = await readdir(directory);\n\n if (config?.ignore?.length) {\n files = micromatch.not(files, config.ignore, {\n cwd: directory,\n matchBase: true,\n dot: true\n });\n }\n\n files = files.map(f => path.join(directory, f));\n\n for (const file of files) {\n if (config?.filter ? !(await config?.filter(file)) : ModuleLoader.fileTypes.every(type => !file.endsWith(`.${type}`))) continue;\n modules.push(file);\n }\n }\n\n if (config?.sort) modules.sort(config.sort);\n\n return modules;\n }\n\n public static async resolveModulePath(filepath: string, options?: { cwd?: string; }): Promise<AnyModule> {\n const stats = await stat(filepath).catch(() => undefined);\n if (!stats) throw new RecipleError(`Module not found: ${filepath}`);\n\n const data = recursiveDefaults<AnyModule|AnyModuleData|undefined>(await import(`file://${path.resolve(options?.cwd ?? process.cwd(), filepath)}`));\n if (BaseModule.isModule(data)) return data;\n\n switch (data?.moduleType) {\n case ModuleType.Command:\n CommandModuleValidator.isValid(data);\n switch (data.type) {\n case CommandType.Message: return MessageCommandModule.from(data);\n case CommandType.Slash: return SlashCommandModule.from(data);\n case CommandType.ContextMenu: return ContextMenuCommandModule.from(data);\n default: throw new RecipleError(`Unknown command type from module: ${colors.cyan(filepath)}`);\n }\n case ModuleType.Event:\n EventModuleValidator.isValid(data);\n return EventModule.from(data);\n case ModuleType.Precondition:\n PreconditionModuleValidator.isValid(data);\n return PreconditionModule.from(data);\n case ModuleType.Postcondition:\n PostconditionModuleValidator.isValid(data);\n return PostconditionModule.from(data);\n case ModuleType.Base:\n default:\n BaseModuleValidator.isValid(data);\n return BaseModule.from(data);\n }\n }\n\n public static async resolveSourceDirectories(options: ModuleLoader.ResolveSourceDirectoryOptions): Promise<string[]> {\n const dir = path.isAbsolute(options.baseUrl) ? options.baseUrl : path.resolve(path.join(options.cwd ?? process.cwd(), options.baseUrl));\n\n const root = path.resolve(path.join(dir, options.rootDir));\n const out = path.resolve(path.join(dir, options.outDir));\n\n return options.directories.map(directory => path.resolve(directory).replace(out, root));\n }\n\n private emitOrThrow<K extends keyof Pick<ModuleLoader.Events, 'moduleResolveError'>>(event: K, error: RecipleError) {\n if (this.client.listenerCount(event) > 0) {\n // @ts-expect-error\n return this.emit(event, error);\n }\n\n throw error;\n }\n}\n\nexport namespace ModuleLoader {\n export let globby: typeof import('globby')|null = null;\n\n export const fileTypes = [\n 'js',\n 'mjs',\n 'jsx'\n ];\n\n export interface Config {\n directories?: string[];\n ignore?: string[];\n filter?: (filepath: string) => Awaitable<boolean>;\n sort?: (a: string, b: string) => number;\n }\n\n export interface Events {\n moduleResolveError: [error: RecipleError];\n moduleResolved: [module: AnyModule];\n moduleResolving: [filepath: string];\n modulesResolved: [modules: AnyModule[]];\n modulesResolving: [files: string[]];\n }\n\n export interface ResolveSourceDirectoryOptions {\n directories: string[];\n baseUrl: string;\n rootDir: string;\n outDir: string;\n cwd?: string;\n }\n\n export async function getGlobby(): Promise<typeof import('globby')> {\n if (globby) return globby;\n\n return globby = await import('globby');\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ModuleType } from "../../helpers/constants.mjs";
2
2
  import { BaseModule } from "../modules/BaseModule.mjs";
3
- import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.mjs";
4
4
  import { BaseManager, RecipleError } from "@reciple/core";
5
5
  import { mix } from "ts-mixer";
6
6
  import { EventEmitter } from "node:events";
@@ -1,6 +1,6 @@
1
1
  import { ModuleType } from "../../helpers/constants.mjs";
2
2
  import { BaseModule } from "./BaseModule.mjs";
3
- import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.mjs";
4
4
  import { CommandPostcondition } from "@reciple/core";
5
5
  import { hasMixin, mix } from "ts-mixer";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { ModuleType } from "../../helpers/constants.mjs";
2
2
  import { BaseModule } from "./BaseModule.mjs";
3
- import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.mjs";
4
4
  import { CommandPrecondition } from "@reciple/core";
5
5
  import { hasMixin, mix } from "ts-mixer";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { ModuleType } from "../../../helpers/constants.mjs";
2
2
  import { BaseModule } from "../BaseModule.mjs";
3
- import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
+ import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.mjs";
4
4
  import { ContextMenuCommand } from "@reciple/core";
5
5
  import { DiscordSnowflake } from "@sapphire/snowflake";
6
6
  import { hasMixin, mix } from "ts-mixer";
@@ -1,6 +1,6 @@
1
1
  import { ModuleType } from "../../../helpers/constants.mjs";
2
2
  import { BaseModule } from "../BaseModule.mjs";
3
- import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
+ import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.mjs";
4
4
  import { MessageCommand, MessageCommandBuilder } from "@reciple/core";
5
5
  import { DiscordSnowflake } from "@sapphire/snowflake";
6
6
  import { hasMixin, mix } from "ts-mixer";
@@ -1,6 +1,6 @@
1
1
  import { ModuleType } from "../../../helpers/constants.mjs";
2
2
  import { BaseModule } from "../BaseModule.mjs";
3
- import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
+ import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.mjs";
4
4
  import { SlashCommand } from "@reciple/core";
5
5
  import { DiscordSnowflake } from "@sapphire/snowflake";
6
6
  import { hasMixin, mix } from "ts-mixer";
@@ -13,6 +13,7 @@ declare class TemplateBuilder {
13
13
  config?: ConfigReader;
14
14
  packageJson?: PackageJsonBuilder;
15
15
  packageManager?: PackageManagerName;
16
+ dependenciesInstalled: boolean;
16
17
  get directory(): string;
17
18
  get relativeDirectory(): string;
18
19
  get packageJsonPath(): string;
@@ -21,10 +22,12 @@ declare class TemplateBuilder {
21
22
  init(): Promise<this>;
22
23
  createDirectory(options?: TemplateBuilder.CreateDirectoryOptions): Promise<this>;
23
24
  setupLanguage(options?: TemplateBuilder.SetupLanguageOptions): Promise<this>;
25
+ createEnvFile(options?: TemplateBuilder.CreateEnvFileOptions): Promise<this>;
24
26
  createConfig(options?: TemplateBuilder.CreateConfigOptions): Promise<this>;
25
27
  createTemplate(options?: TemplateBuilder.CreateModulesOptions): Promise<this>;
26
28
  setPackageManager(options?: TemplateBuilder.SetPackageManagerOptions): Promise<this>;
27
- createEnvFile(options?: TemplateBuilder.CreateEnvFileOptions): Promise<this>;
29
+ installDependencies(options?: TemplateBuilder.InstallDependenciesOptions): Promise<this>;
30
+ createModules(): Promise<this>;
28
31
  build(options?: TemplateBuilder.BuildOptions): Promise<this>;
29
32
  }
30
33
  declare namespace TemplateBuilder {
@@ -52,13 +55,15 @@ declare namespace TemplateBuilder {
52
55
  interface SetPackageManagerOptions {
53
56
  packageManager?: PackageManagerName;
54
57
  }
58
+ interface InstallDependenciesOptions {
59
+ value?: boolean;
60
+ }
55
61
  interface CreateEnvFileOptions {
56
62
  envFile?: string;
57
63
  tokenKey?: string;
58
64
  env?: Record<string, string>;
59
65
  }
60
66
  interface BuildOptions {
61
- skipInstallDependencies?: boolean;
62
67
  skipBuild?: boolean;
63
68
  }
64
69
  interface CopyOptions {
@@ -7,7 +7,7 @@ import path from "node:path";
7
7
  import { PackageJsonBuilder, colors } from "@reciple/utils";
8
8
  import { parse } from "@dotenvx/dotenvx";
9
9
  import { copyFile, mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
10
- import { confirm, intro, isCancel, outro, select, text } from "@clack/prompts";
10
+ import { confirm, intro, isCancel, log, outro, select, text } from "@clack/prompts";
11
11
  import micromatch from "micromatch";
12
12
  import { existsSync, statSync } from "node:fs";
13
13
  import { slug } from "github-slugger";
@@ -23,6 +23,7 @@ var TemplateBuilder = class TemplateBuilder {
23
23
  config;
24
24
  packageJson;
25
25
  packageManager;
26
+ dependenciesInstalled = false;
26
27
  get directory() {
27
28
  return this._directory ?? process.cwd();
28
29
  }
@@ -98,10 +99,42 @@ var TemplateBuilder = class TemplateBuilder {
98
99
  }
99
100
  return this;
100
101
  }
102
+ async createEnvFile(options) {
103
+ const tokenKey = options?.tokenKey ?? "DISCORD_TOKEN";
104
+ const envFile = options?.envFile ? path.resolve(options.envFile) : path.join(this.directory, ".env");
105
+ const stats = await stat(envFile).catch(() => void 0);
106
+ let env = options?.env ?? {};
107
+ env = stats ? parse(await readFile(envFile, "utf-8"), { processEnv: env }) : env;
108
+ if (env[tokenKey]) {
109
+ const skip = this.defaultAll || await confirm({
110
+ message: "Discord bot token already exists in .env file, do you want to skip?",
111
+ initialValue: true,
112
+ active: "Yes",
113
+ inactive: "No"
114
+ });
115
+ if (isCancel(skip)) throw new NotAnError("Operation cancelled");
116
+ if (skip) return this;
117
+ }
118
+ const token = await text({
119
+ message: "Enter Discord Bot Token",
120
+ placeholder: "Bot Token from Discord Developer Portal",
121
+ defaultValue: env[tokenKey]
122
+ });
123
+ if (isCancel(token)) throw new NotAnError("Operation cancelled");
124
+ env[tokenKey] = token;
125
+ await writeFile(envFile, `\n${tokenKey}="${token}"\n`, {
126
+ encoding: "utf-8",
127
+ flag: "a"
128
+ });
129
+ return this;
130
+ }
101
131
  async createConfig(options) {
102
- let filepath = options?.filepath;
103
- if (!filepath) filepath = await ConfigReader.findConfig(this.directory, this.typescript ? "ts" : this.typescript === false ? "js" : void 0) ?? path.join(this.directory, ConfigReader.createConfigFilename(this.typescript ? "ts" : "js"));
104
- if (await ConfigReader.hasFile(filepath)) {
132
+ let filepath = options?.path;
133
+ if (!filepath) filepath = await ConfigReader.find({
134
+ cwd: this.directory,
135
+ lang: this.typescript ? "ts" : this.typescript === false ? "js" : void 0
136
+ }) ?? path.join(this.directory, ConfigReader.createConfigFilename(this.typescript ? "ts" : "js"));
137
+ if (await ConfigReader.exists(filepath)) {
105
138
  const overwrite = this.defaultAll ? false : await confirm({
106
139
  message: `Config file already exists at ${colors.green(path.relative(process.cwd(), filepath))}. Would you like to overwrite it?`,
107
140
  active: "Yes",
@@ -113,7 +146,7 @@ var TemplateBuilder = class TemplateBuilder {
113
146
  }
114
147
  this.config = await ConfigReader.create({
115
148
  ...options,
116
- filepath,
149
+ path: filepath,
117
150
  type: this.typescript ? "ts" : "js",
118
151
  overwrite: true
119
152
  });
@@ -122,14 +155,6 @@ var TemplateBuilder = class TemplateBuilder {
122
155
  async createTemplate(options) {
123
156
  const source = path.join(CLI.root, "./assets/templates/", this.typescript ? "typescript" : "javascript");
124
157
  const globals = path.join(CLI.root, "./assets/global/");
125
- const modulesDirectory = path.join(this.directory, "src");
126
- const moduleTemplates = await ModuleTemplateBuilder.resolveModuleTemplates(this.typescript ? "ts" : "js");
127
- const moduleOptions = {
128
- cli: this.cli,
129
- config: this.config,
130
- defaultAll: true,
131
- typescript: this.typescript
132
- };
133
158
  function rename(data) {
134
159
  switch (data.basename) {
135
160
  case "gitignore": return ".gitignore";
@@ -145,30 +170,15 @@ var TemplateBuilder = class TemplateBuilder {
145
170
  }
146
171
  }
147
172
  const [template, loader] = CLI.createSpinnerPromise({
148
- promise: Promise.all([
149
- TemplateBuilder.copy(source, this.directory, {
150
- ...options,
151
- rename,
152
- overwrite
153
- }),
154
- TemplateBuilder.copy(globals, this.directory, {
155
- ...options,
156
- rename,
157
- overwrite
158
- }),
159
- new ModuleTemplateBuilder({
160
- ...moduleOptions,
161
- directory: path.join(modulesDirectory, "commands"),
162
- filename: `SlashCommand.${this.typescript ? "ts" : "js"}`,
163
- template: moduleTemplates.find((t) => t.name === "SlashCommand")
164
- }).setupPlaceholders().then((m) => m.build({ silent: true })),
165
- new ModuleTemplateBuilder({
166
- ...moduleOptions,
167
- directory: path.join(modulesDirectory, "events"),
168
- filename: `ClientEvent.${this.typescript ? "ts" : "js"}`,
169
- template: moduleTemplates.find((t) => t.name === "ClientEvent")
170
- }).setupPlaceholders().then((m) => m.build({ silent: true }))
171
- ]),
173
+ promise: Promise.all([TemplateBuilder.copy(source, this.directory, {
174
+ ...options,
175
+ rename,
176
+ overwrite
177
+ }), TemplateBuilder.copy(globals, this.directory, {
178
+ ...options,
179
+ rename,
180
+ overwrite
181
+ })]),
172
182
  message: "Copying template files",
173
183
  successMessage: "Files copied successfully",
174
184
  errorMessage: "Failed to copy files"
@@ -212,7 +222,7 @@ var TemplateBuilder = class TemplateBuilder {
212
222
  if (isCancel(packageManager)) throw new NotAnError("Operation cancelled");
213
223
  this.packageManager = packageManager;
214
224
  }
215
- this.packageJson = await PackageJsonBuilder.read(this.packageJsonPath);
225
+ this.packageJson = await PackageJsonBuilder.read(this.packageJsonPath, true);
216
226
  this.packageJson.merge({
217
227
  name: this.name,
218
228
  version: "0.0.1",
@@ -227,49 +237,69 @@ var TemplateBuilder = class TemplateBuilder {
227
237
  });
228
238
  return this;
229
239
  }
230
- async createEnvFile(options) {
231
- const tokenKey = options?.tokenKey ?? "DISCORD_TOKEN";
232
- const envFile = options?.envFile ? path.resolve(options.envFile) : path.join(this.directory, ".env");
233
- const stats = await stat(envFile).catch(() => void 0);
234
- let env = options?.env ?? {};
235
- env = stats ? parse(await readFile(envFile, "utf-8"), { processEnv: env }) : env;
236
- if (env[tokenKey]) {
237
- const skip = this.defaultAll || await confirm({
238
- message: "Discord bot token already exists in .env file, do you want to skip?",
239
- initialValue: true,
240
- active: "Yes",
241
- inactive: "No"
242
- });
243
- if (isCancel(skip)) throw new NotAnError("Operation cancelled");
244
- if (skip) return this;
240
+ async installDependencies(options) {
241
+ if (options?.value !== false) {
242
+ if (options?.value === void 0) {
243
+ const install = this.defaultAll ? true : await confirm({
244
+ message: `Would you like to install dependencies?`,
245
+ active: "Yes",
246
+ inactive: "No",
247
+ initialValue: true
248
+ });
249
+ if (isCancel(install)) throw new NotAnError("Operation cancelled");
250
+ if (!install) return this;
251
+ }
252
+ await CLI.createSpinnerPromise({
253
+ promise: installDependencies({
254
+ cwd: this.directory,
255
+ packageManager: this.packageManager,
256
+ silent: true
257
+ }),
258
+ indicator: "timer",
259
+ errorMessage: `${colors.bold(colors.red("✗"))} Failed to install dependencies`,
260
+ successMessage: `${colors.bold(colors.green("✔"))} Dependencies installed successfully`,
261
+ message: `${colors.bold(colors.dim("$"))} Installing dependencies`
262
+ })[0];
263
+ this.dependenciesInstalled = true;
245
264
  }
246
- const token = await text({
247
- message: "Enter Discord Bot Token",
248
- placeholder: "Bot Token from Discord Developer Portal",
249
- defaultValue: env[tokenKey]
250
- });
251
- if (isCancel(token)) throw new NotAnError("Operation cancelled");
252
- env[tokenKey] = token;
253
- await writeFile(envFile, `\n${tokenKey}="${token}"\n`, {
254
- encoding: "utf-8",
255
- flag: "a"
265
+ return this;
266
+ }
267
+ async createModules() {
268
+ const modulesDirectory = path.join(this.directory, "src");
269
+ const moduleTemplates = await ModuleTemplateBuilder.resolveModuleTemplates(this.typescript ? "ts" : "js");
270
+ await mkdir(modulesDirectory, { recursive: true });
271
+ if (!this.dependenciesInstalled) {
272
+ log.warn("Dependencies not installed. Skipping module creation.");
273
+ return this;
274
+ }
275
+ const moduleOptions = {
276
+ cli: this.cli,
277
+ config: await this.config?.read(),
278
+ defaultAll: true,
279
+ typescript: this.typescript
280
+ };
281
+ const [template, loader] = CLI.createSpinnerPromise({
282
+ promise: Promise.all([new ModuleTemplateBuilder({
283
+ ...moduleOptions,
284
+ directory: path.join(modulesDirectory, "commands"),
285
+ filename: `SlashCommand.${this.typescript ? "ts" : "js"}`,
286
+ template: moduleTemplates.find((t) => t.name === "SlashCommand")
287
+ }).setupPlaceholders().then((m) => m.build({ silent: true })), new ModuleTemplateBuilder({
288
+ ...moduleOptions,
289
+ directory: path.join(modulesDirectory, "events"),
290
+ filename: `ClientEvent.${this.typescript ? "ts" : "js"}`,
291
+ template: moduleTemplates.find((t) => t.name === "ClientEvent")
292
+ }).setupPlaceholders().then((m) => m.build({ silent: true }))]),
293
+ message: "Creating module templates",
294
+ successMessage: "Module templates created successfully",
295
+ errorMessage: "Failed to create module templates"
256
296
  });
297
+ await template;
257
298
  return this;
258
299
  }
259
300
  async build(options) {
260
301
  await this.packageJson?.write(this.packageJsonPath, true);
261
- if (!options?.skipInstallDependencies) await CLI.createSpinnerPromise({
262
- promise: installDependencies({
263
- cwd: this.directory,
264
- packageManager: this.packageManager,
265
- silent: true
266
- }),
267
- indicator: "timer",
268
- errorMessage: `${colors.bold(colors.red("✗"))} Failed to install dependencies`,
269
- successMessage: `${colors.bold(colors.green("✔"))} Dependencies installed successfully`,
270
- message: `${colors.bold(colors.dim("$"))} Installing dependencies`
271
- })[0];
272
- if (!options?.skipBuild) await CLI.createSpinnerPromise({
302
+ if (!options?.skipBuild && this.dependenciesInstalled) await CLI.createSpinnerPromise({
273
303
  promise: runScript("build", {
274
304
  cwd: this.directory,
275
305
  packageManager: this.packageManager,
@@ -283,7 +313,7 @@ var TemplateBuilder = class TemplateBuilder {
283
313
  outro(`Project created in ${colors.cyan(this.relativeDirectory)}`);
284
314
  console.log(`\n${colors.bold(colors.green("✔"))} Start developing:`);
285
315
  if (this.relativeDirectory !== "./") console.log(` • ${colors.cyan(colors.bold(`cd ${this.relativeDirectory}`))}`);
286
- if (options?.skipInstallDependencies) console.log(` • ${colors.cyan(colors.bold(installDependenciesCommand(this.packageManager ?? "npm")))}`);
316
+ console.log(` • ${colors.cyan(colors.bold(installDependenciesCommand(this.packageManager ?? "npm")))} ${colors.dim("(Install dependencies)")}`);
287
317
  console.log(` • ${colors.cyan(colors.bold(runScriptCommand(this.packageManager ?? "npm", "build")))} ${colors.dim("(Build)")}`);
288
318
  console.log(` • ${colors.cyan(colors.bold(runScriptCommand(this.packageManager ?? "npm", "dev")))} ${colors.dim("(Development)")}`);
289
319
  console.log(` • ${colors.cyan(colors.bold(runScriptCommand(this.packageManager ?? "npm", "start")))} ${colors.dim("(Production)")}`);
@@ -301,7 +331,8 @@ var TemplateBuilder = class TemplateBuilder {
301
331
  },
302
332
  devDependencies: {
303
333
  "@types/node": packageJSON.devDependencies?.["@types/node"],
304
- nodemon: packageJSON.devDependencies?.nodemon
334
+ nodemon: packageJSON.devDependencies?.nodemon,
335
+ typescript: packageJSON.devDependencies?.["typescript"]
305
336
  }
306
337
  },
307
338
  ts: {},