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.
- package/assets/templates/javascript/jsconfig.json +14 -2
- package/assets/templates/typescript/tsconfig.json +14 -2
- package/dist/_virtual/{_@oxc-project_runtime@0.99.0 → _@oxc-project_runtime@0.103.0}/helpers/decorate.mjs +1 -1
- package/dist/bin/commands/build.mjs +1 -1
- package/dist/bin/commands/build.mjs.map +1 -1
- package/dist/bin/commands/create.mjs +6 -7
- package/dist/bin/commands/create.mjs.map +1 -1
- package/dist/bin/commands/createModule.mjs +1 -1
- package/dist/bin/commands/createModule.mjs.map +1 -1
- package/dist/bin/commands/start.mjs +8 -8
- package/dist/bin/commands/start.mjs.map +1 -1
- package/dist/bin/reciple.mjs +0 -0
- package/dist/classes/cli/CLI.d.mts +1 -1
- package/dist/classes/cli/CLI.mjs +2 -2
- package/dist/classes/cli/CLI.mjs.map +1 -1
- package/dist/classes/cli/ConfigReader.d.mts +21 -29
- package/dist/classes/cli/ConfigReader.mjs +39 -62
- package/dist/classes/cli/ConfigReader.mjs.map +1 -1
- package/dist/classes/client/EventListeners.mjs +1 -1
- package/dist/classes/client/EventListeners.mjs.map +1 -1
- package/dist/classes/client/ModuleLoader.d.mts +1 -1
- package/dist/classes/client/ModuleLoader.mjs.map +1 -1
- package/dist/classes/managers/ModuleManager.mjs +1 -1
- package/dist/classes/modules/PostconditionModule.mjs +1 -1
- package/dist/classes/modules/PreconditionModule.mjs +1 -1
- package/dist/classes/modules/commands/ContextMenuCommandModule.mjs +1 -1
- package/dist/classes/modules/commands/MessageCommandModule.mjs +1 -1
- package/dist/classes/modules/commands/SlashCommandModule.mjs +1 -1
- package/dist/classes/templates/TemplateBuilder.d.mts +7 -2
- package/dist/classes/templates/TemplateBuilder.mjs +108 -77
- package/dist/classes/templates/TemplateBuilder.mjs.map +1 -1
- package/dist/classes/validation/BaseModuleValidator.d.mts +11 -11
- package/dist/classes/validation/CommandModuleValidator.d.mts +18 -18
- package/dist/classes/validation/EventModuleValidator.d.mts +9 -9
- package/dist/classes/validation/PostconditionModule.d.mts +8 -8
- package/dist/classes/validation/PreconditionModule.d.mts +8 -8
- package/dist/helpers/constants.d.mts +1 -2
- package/dist/helpers/constants.mjs +1 -1
- package/dist/helpers/constants.mjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/package.mjs +12 -15
- package/dist/package.mjs.map +1 -1
- package/package.json +12 -15
- package/LICENSE +0 -155
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigReader.mjs","names":["filepath: string"
|
|
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 +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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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?.
|
|
103
|
-
if (!filepath) filepath = await ConfigReader.
|
|
104
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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?.
|
|
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
|
-
|
|
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: {},
|