Add Configuration
Understand what the validator class does, what the default YAML file does, and how ItsMyBot loads the final addon config.
Open this page after your addon class already exists.
Configuration in ItsMyBot becomes much easier once you separate three different things clearly.
The three parts of addon config
Prop
Type
That is the core mental model:
- the class describes the expected structure
- the default YAML provides the initial values
- the runtime config is the final editable file
How the files relate
For one config file, the structure usually looks like this:
The flow is:
- your addon ships a default file in
resources/config.yml createConfig()ensures a runtime file exists inconfigs/MyAddon/config.yml- the runtime file is validated with
resources/config.ts - your addon reads the validated result through
ConfigFile
Load one config file with createConfig()
Use createConfig() when the addon has one main config file.
import { Addon, ConfigFile } from '@itsmybot';
import AddonConfig from './resources/config.js';
interface Configs {
config: ConfigFile;
}
export default class MyAddon extends Addon {
configs = {} as Configs;
async load() {
this.configs.config = await this.createConfig('config.yml', AddonConfig);
}
}This is the normal first-addon pattern.
Write the validator class
Validator classes use class-validator.
import { IsDefined, IsString, IsBoolean, IsNumber } from 'class-validator';
export default class AddonConfig {
@IsDefined()
@IsString()
channel: string;
@IsBoolean()
enabled: boolean;
@IsNumber()
interval: number;
}Common rules:
Prop
Type
Write the default YAML file
The default YAML should match the validator class.
channel: "123456789012345678"
enabled: true
interval: 60This file is not just an example. It is the default file your addon ships with the bot.
What createConfig() actually does
When you call:
this.configs.config = await this.createConfig('config.yml', AddonConfig);ItsMyBot will:
- look for
configs/MyAddon/config.yml - create it from
build/addons/MyAddon/resources/config.ymlif it does not exist - validate the loaded data with
AddonConfig - return a
ConfigFile
That is why resources/config.ts and resources/config.yml belong together.
Read validated values back
Once loaded, use the ConfigFile getters instead of reading raw YAML yourself.
Prop
Type
Example:
const channel = this.configs.config.getString('channel');
const enabled = this.configs.config.getBool('enabled');When to use createConfigSection()
Use createConfigSection() only when your addon needs a folder of files with the same shape.
Example structure:
Use that when your addon has repeatable entries such as categories, templates, presets, or panels.
import { Collection } from 'discord.js';
import { Addon, ConfigFile } from '@itsmybot';
import CategoryConfig from './resources/category.js';
interface Configs {
categories: Collection<string, ConfigFile>;
}
export default class MyAddon extends Addon {
configs = {} as Configs;
async load() {
this.configs.categories = await this.createConfigSection('categories', CategoryConfig);
}
}Nested config
If your YAML contains nested objects, combine class-transformer with nested validation.
import { Type } from 'class-transformer';
import { IsDefined, IsString, ValidateNested } from 'class-validator';
class ChannelSettings {
@IsDefined()
@IsString()
id: string;
}
export default class AddonConfig {
@ValidateNested()
@Type(() => ChannelSettings)
channel: ChannelSettings;
}Keep this rule in mind
When config feels confusing, go back to the three-part model: validator class, default YAML, runtime config file.
That model explains almost every config-related addon question.