ItsMyStudio

Add Configuration

Understand what the validator class does, what the default YAML file does, and how ItsMyBot loads the final addon config.

Support

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:

config.ts
config.yml

The flow is:

  1. your addon ships a default file in resources/config.yml
  2. createConfig() ensures a runtime file exists in configs/MyAddon/config.yml
  3. the runtime file is validated with resources/config.ts
  4. 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: 60

This 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:

  1. look for configs/MyAddon/config.yml
  2. create it from build/addons/MyAddon/resources/config.yml if it does not exist
  3. validate the loaded data with AddonConfig
  4. 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:

category.ts
default.yml
support.yml

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.

On this page