Skip to content

Commit 3897cc4

Browse files
committed
feat: add dirs configuration
1 parent b667574 commit 3897cc4

File tree

8 files changed

+131
-105
lines changed

8 files changed

+131
-105
lines changed

bin/index.mjs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
#!/usr/bin/env node
22

3-
import { createDevHarmonix, createHarmonix } from '../dist/index.mjs'
3+
import { createHarmonix } from '../dist/index.mjs'
44
import 'dotenv/config'
55

6-
const initHarmonix = async () => {
7-
await createDevHarmonix({ rootDir: './playground' }, { cwd: './playground' })
6+
const init = async () => {
7+
await createHarmonix(
8+
{ rootDir: './playground' },
9+
{ cwd: './playground' },
10+
true
11+
)
812
}
913

10-
initHarmonix()
14+
init()

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"c12": "^1.10.0",
2626
"chokidar": "^3.6.0",
2727
"consola": "^3.2.3",
28+
"defu": "^6.1.4",
2829
"discord.js": "^14.15.2",
2930
"dotenv": "^16.4.5",
3031
"globby": "^14.0.1",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/harmonix.ts

Lines changed: 82 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,17 @@ import type { Harmonix, HarmonixConfig, HarmonixOptions } from './types'
4949
import { version } from '../package.json'
5050

5151
export const ctx = getContext<Harmonix>('harmonix')
52-
5352
export const useHarmonix = ctx.use
5453

55-
export const createHarmonix = async (
56-
config: HarmonixConfig = {},
57-
opts: LoadConfigOptions = {}
58-
) => {
59-
if (!process.env.DISCORD_CLIENT_TOKEN) {
60-
createError(
61-
'Client token is required. Please provide it in the environment variable DISCORD_CLIENT_TOKEN.'
62-
)
63-
}
64-
const options = await loadOptions(config, opts)
65-
const harmonix: Harmonix = {
66-
options: options as HarmonixOptions,
54+
const initHarmonix = async (
55+
config: HarmonixConfig,
56+
options: LoadConfigOptions
57+
): Promise<Harmonix> => {
58+
const opts = await loadOptions(config, options)
59+
60+
return {
61+
configFile: opts.configFile as string,
62+
options: opts.options as HarmonixOptions,
6763
events: new Collection(),
6864
commands: new Collection(),
6965
contextMenus: new Collection(),
@@ -72,36 +68,23 @@ export const createHarmonix = async (
7268
selectMenus: new Collection(),
7369
preconditions: new Collection()
7470
}
75-
76-
consola.log(colors.blue(`Harmonix ${colors.bold(version)}\n`))
77-
await loadHarmonix(harmonix, config, opts)
78-
79-
return harmonix
8071
}
8172

82-
export const createDevHarmonix = async (
83-
config: HarmonixConfig = {},
84-
opts: LoadConfigOptions = {}
73+
const watchReload = (
74+
harmonix: Harmonix,
75+
config: HarmonixConfig,
76+
opts: LoadConfigOptions
8577
) => {
86-
if (!process.env.DISCORD_CLIENT_TOKEN) {
87-
createError(
88-
'Client token is required. Please provide it in the environment variable DISCORD_CLIENT_TOKEN.'
89-
)
90-
}
91-
const options = await loadOptions(config, opts)
92-
const harmonix: Harmonix = {
93-
options: options as HarmonixOptions,
94-
events: new Collection(),
95-
commands: new Collection(),
96-
contextMenus: new Collection(),
97-
buttons: new Collection(),
98-
modals: new Collection(),
99-
selectMenus: new Collection(),
100-
preconditions: new Collection()
101-
}
102-
103-
consola.log(colors.blue(`Harmonix ${colors.bold(version)}\n`))
104-
const watcher = watch(harmonix.options.scanDirs, {
78+
const filesToWatch = [
79+
harmonix.options.dirs.commands,
80+
harmonix.options.dirs.events,
81+
harmonix.options.dirs.contextMenus,
82+
harmonix.options.dirs.buttons,
83+
harmonix.options.dirs.modals,
84+
harmonix.options.dirs.selectMenus,
85+
harmonix.options.dirs.preconditions
86+
].map((file) => resolve(harmonix.options.rootDir, file))
87+
const watcher = watch([...filesToWatch, harmonix.configFile], {
10588
ignored: harmonix.options.ignore,
10689
ignoreInitial: true
10790
})
@@ -122,8 +105,26 @@ export const createDevHarmonix = async (
122105
100
123106
)
124107

125-
await loadHarmonix(harmonix, config, opts)
126108
watcher.on('all', (event, path, stats) => reload(event, path, stats))
109+
}
110+
111+
export const createHarmonix = async (
112+
config: HarmonixConfig = {},
113+
opts: LoadConfigOptions = {},
114+
devMode: boolean = false
115+
) => {
116+
if (!process.env.DISCORD_CLIENT_TOKEN) {
117+
createError(
118+
'Client token is required. Please provide it in the environment variable DISCORD_CLIENT_TOKEN.'
119+
)
120+
}
121+
const harmonix = await initHarmonix(config, opts)
122+
123+
consola.log(colors.blue(`Harmonix ${colors.bold(version)}\n`))
124+
await loadHarmonix(harmonix, config, opts)
125+
if (devMode) {
126+
watchReload(harmonix, config, opts)
127+
}
127128

128129
return harmonix
129130
}
@@ -142,53 +143,54 @@ export const clearHarmonix = async (harmonix: Harmonix) => {
142143
export const loadHarmonix = async (
143144
harmonix: Harmonix,
144145
config: HarmonixConfig,
145-
opts: LoadConfigOptions
146+
options: LoadConfigOptions
146147
) => {
147-
const options = await loadOptions(config, opts)
148-
149-
harmonix.options = options as HarmonixOptions
150-
const scannedCommands = await scanCommands(harmonix)
151-
const _commands = [...(harmonix.options.commands || []), ...scannedCommands]
152-
const commands = _commands.map((cmd) => resolveCommand(cmd, harmonix.options))
153-
154-
const scannedEvents = await scanEvents(harmonix)
155-
const _events = [...(harmonix.options.events || []), ...scannedEvents]
156-
const events = _events.map((evt) => resolveEvent(evt, harmonix.options))
157-
158-
const scannedContextMenus = await scanContextMenus(harmonix)
159-
const _contextMenus = [
148+
const opts = await loadOptions(config, options)
149+
150+
harmonix.configFile = opts.configFile as string
151+
harmonix.options = opts.options as HarmonixOptions
152+
const [
153+
scannedEvents,
154+
scannedCommands,
155+
scannedContextMenus,
156+
scannedButtons,
157+
scannedModals,
158+
scannedSelectMenus,
159+
scannedPreconditions
160+
] = await Promise.all([
161+
scanEvents(harmonix),
162+
scanCommands(harmonix),
163+
scanContextMenus(harmonix),
164+
scanButtons(harmonix),
165+
scanModals(harmonix),
166+
scanSelectMenus(harmonix),
167+
scanPreconditions(harmonix)
168+
])
169+
const commands = [
170+
...(harmonix.options.commands || []),
171+
...scannedCommands
172+
].map((cmd) => resolveCommand(cmd, harmonix.options))
173+
const events = [...(harmonix.options.events || []), ...scannedEvents].map(
174+
(evt) => resolveEvent(evt, harmonix.options)
175+
)
176+
const contextMenus = [
160177
...(harmonix.options.contextMenus || []),
161178
...scannedContextMenus
162-
]
163-
const contextMenus = _contextMenus.map((ctm) =>
164-
resolveContextMenu(ctm, harmonix.options)
179+
].map((ctm) => resolveContextMenu(ctm, harmonix.options))
180+
const buttons = [...(harmonix.options.buttons || []), ...scannedButtons].map(
181+
(btn) => resolveButton(btn, harmonix.options)
165182
)
166-
167-
const scannedButtons = await scanButtons(harmonix)
168-
const _buttons = [...(harmonix.options.buttons || []), ...scannedButtons]
169-
const buttons = _buttons.map((btn) => resolveButton(btn, harmonix.options))
170-
171-
const scannedModals = await scanModals(harmonix)
172-
const _modals = [...(harmonix.options.modals || []), ...scannedModals]
173-
const modals = _modals.map((mdl) => resolveModal(mdl, harmonix.options))
174-
175-
const scannedSelectMenus = await scanSelectMenus(harmonix)
176-
const _selectMenus = [
183+
const modals = [...(harmonix.options.modals || []), ...scannedModals].map(
184+
(mdl) => resolveModal(mdl, harmonix.options)
185+
)
186+
const selectMenus = [
177187
...(harmonix.options.selectMenus || []),
178188
...scannedSelectMenus
179-
]
180-
const selectMenus = _selectMenus.map((slm) =>
181-
resolveSelectMenu(slm, harmonix.options)
182-
)
183-
184-
const scannedPreconditions = await scanPreconditions(harmonix)
185-
const _preconditions = [
189+
].map((slm) => resolveSelectMenu(slm, harmonix.options))
190+
const preconditions = [
186191
...(harmonix.options.preconditions || []),
187192
...scannedPreconditions
188-
]
189-
const preconditions = _preconditions.map((prc) =>
190-
resolvePrecondition(prc, harmonix.options)
191-
)
193+
].map((prc) => resolvePrecondition(prc, harmonix.options))
192194

193195
loadEvents(harmonix, events)
194196
loadCommands(harmonix, commands)

src/index.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
export * from './define'
22
export * from './getters'
33
export * from './uses'
4-
export {
5-
createHarmonix,
6-
createDevHarmonix,
7-
createError,
8-
useHarmonix
9-
} from './harmonix'
4+
export { createHarmonix, createError, useHarmonix } from './harmonix'

src/options.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { LoadConfigOptions, loadConfig } from 'c12'
22
import { resolve } from 'pathe'
33
import type { HarmonixConfig } from './types'
44
import { createError } from './harmonix'
5+
import defu from 'defu'
56

67
const HarmonixDefaults: HarmonixConfig = {
78
scanDirs: [],
@@ -16,7 +17,7 @@ export const loadOptions = async (
1617
configOverrides: HarmonixConfig = {},
1718
opts: LoadConfigOptions
1819
) => {
19-
const { config } = await loadConfig<HarmonixConfig>({
20+
const { config, configFile } = await loadConfig<HarmonixConfig>({
2021
name: 'harmonix',
2122
configFile: 'harmonix.config',
2223
dotenv: true,
@@ -41,6 +42,15 @@ export const loadOptions = async (
4142

4243
options.client = options.client || {}
4344
options.client.intents = intents
45+
options.dirs = defu(options.dirs, {
46+
commands: 'commands',
47+
events: 'events',
48+
contextMenus: 'context-menus',
49+
buttons: 'buttons',
50+
modals: 'modals',
51+
selectMenus: 'select-menus',
52+
preconditions: 'preconditions'
53+
})
4454

45-
return options
55+
return { options, configFile }
4656
}

src/scan.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,46 @@ import { Harmonix } from './types'
44

55
const GLOB_SCAN_PATTERN = '**/*.{js,ts}'
66

7-
export const scanCommands = async (harmonix: Harmonix) => {
8-
const files = await scanFiles(harmonix, 'commands')
7+
export const scanEvents = async (harmonix: Harmonix) => {
8+
const files = await Promise.all([
9+
scanFiles(harmonix, harmonix.options.dirs.events)
10+
]).then((r) => r.flat())
911

1012
return files.map((f) => f.fullPath)
1113
}
1214

13-
export const scanEvents = async (harmonix: Harmonix) => {
14-
const files = await Promise.all([
15-
scanFiles(harmonix, 'events'),
16-
scanFiles(harmonix, 'listeners')
17-
]).then((r) => r.flat())
15+
export const scanCommands = async (harmonix: Harmonix) => {
16+
const files = await scanFiles(harmonix, harmonix.options.dirs.commands)
1817

1918
return files.map((f) => f.fullPath)
2019
}
2120

2221
export const scanContextMenus = async (harmonix: Harmonix) => {
23-
const files = await scanFiles(harmonix, 'context-menus')
22+
const files = await scanFiles(harmonix, harmonix.options.dirs.contextMenus)
2423

2524
return files.map((f) => f.fullPath)
2625
}
2726

2827
export const scanButtons = async (harmonix: Harmonix) => {
29-
const files = await scanFiles(harmonix, 'buttons')
28+
const files = await scanFiles(harmonix, harmonix.options.dirs.buttons)
3029

3130
return files.map((f) => f.fullPath)
3231
}
3332

3433
export const scanModals = async (harmonix: Harmonix) => {
35-
const files = await scanFiles(harmonix, 'modals')
34+
const files = await scanFiles(harmonix, harmonix.options.dirs.modals)
3635

3736
return files.map((f) => f.fullPath)
3837
}
3938

4039
export const scanSelectMenus = async (harmonix: Harmonix) => {
41-
const files = await scanFiles(harmonix, 'select-menus')
40+
const files = await scanFiles(harmonix, harmonix.options.dirs.selectMenus)
4241

4342
return files.map((f) => f.fullPath)
4443
}
4544

4645
export const scanPreconditions = async (harmonix: Harmonix) => {
47-
const files = await scanFiles(harmonix, 'preconditions')
46+
const files = await scanFiles(harmonix, harmonix.options.dirs.preconditions)
4847

4948
return files.map((f) => f.fullPath)
5049
}

src/types/harmonix.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,24 @@ import type {
1414
HarmonixPreconditionInput
1515
} from './preconditions'
1616

17+
interface HarmonixDirs {
18+
events: string
19+
commands: string
20+
contextMenus: string
21+
buttons: string
22+
modals: string
23+
selectMenus: string
24+
preconditions: string
25+
}
26+
1727
export interface HarmonixOptions {
1828
rootDir: string
1929
srcDir: string
2030
scanDirs: string[]
31+
dirs: HarmonixDirs
2132
ignore: string[]
22-
commands: HarmonixCommandInput[]
2333
events: HarmonixEventInput[]
34+
commands: HarmonixCommandInput[]
2435
contextMenus: HarmonixContextMenuInput[]
2536
buttons: HarmonixButtonInput[]
2637
modals: HarmonixModalInput[]
@@ -41,6 +52,7 @@ export interface HarmonixConfig
4152
C12InputConfig<HarmonixConfig> {}
4253

4354
export interface Harmonix {
55+
configFile: string
4456
options: HarmonixOptions
4557
client?: Client
4658
events: Collection<string, HarmonixEvent>

0 commit comments

Comments
 (0)