Guides

Source Registry

Register custom search sources and build identifiers for providers.

Use Source Registry to add custom search providers and build valid Lavalink identifiers for your search queries.

Register Custom Sources

Register new source aliases during app bootstrap.

register-sources.ts
import { ,  } from 'hoshimi';

.({
  : 'mysearch',
  : 'my-provider',
  : ., // the default: `mysearch:query`
});

.(
  { : 'mytts', : . }, // `mytts://query`
  { : 'rawquery', : . },      // the query, untouched
);

declare module 'hoshimi' {
  interface CustomizableSources {
    : 'my-provider';
    : 'mytts';
  }
}

Resolve & Validate

Check if a source is registered and retrieve its configuration.

resolve-sources.ts
import {  } from 'hoshimi';

const  = .('my-provider');
const  = .('mysearch');
const  = .();

.(, , );

Build Identifiers

Create properly formatted identifiers for different protocol types.

build-identifiers.ts
import {  } from 'hoshimi';

const  = .('mysearch', 'Daft Punk');
const  = .('mytts', 'hello world');
const  = .('rawquery', 'ytsearch:already-prefixed');

.(, , );

How a query becomes an identifier

search() runs every query through the registry before it reaches Lavalink:

  1. A full URL is passed through untouched.
  2. A source: or source:// prefix wins over the source option — scsearch:foo searches SoundCloud even if the default is YouTube.
  3. Otherwise the identifier is built from the source using its protocol.

An unregistered source throws an OptionError, so a typo fails at the call instead of returning nothing.

Best Practices

  • Register sources during application bootstrap.
  • Use resolve() before searching if the source can be user-provided.
  • Keep protocol choice consistent per source to maintain query format stability.
  • Use module augmentation to add custom sources to TypeScript's CustomizableSources interface.