Module helpers
Zumito Framework provides two utility functions to help build typed, configurable modules: createModuleEntry and getModuleConfig. These are exported from zumito-framework and used by all official modules.
createModuleEntry(metaUrl)
Section titled “createModuleEntry(metaUrl)”Creates a typed factory function that produces ModuleEntry objects for the modules array in zumito.config.ts. It auto-discovers the module name by walking up from the caller’s directory to find the nearest package.json.
Signature
Section titled “Signature”function createModuleEntry<T extends Record<string, any> = Record<string, any>>( metaUrl: string): ModuleEntryFactory<T>
// The returned factory function:type ModuleEntryFactory<T> = (config?: T) => ModuleEntryUsage in a module
Section titled “Usage in a module”Every official module calls createModuleEntry(import.meta.url) at the bottom of its main entry file and exports the result:
// index.ts (module entry point)import { Module, createModuleEntry } from 'zumito-framework';
export class MyModule extends Module { /* ... */ }
export interface MyModuleEntryConfig { option1?: boolean; option2?: number;}
export const myModule = createModuleEntry<MyModuleEntryConfig>(import.meta.url);Usage in a bot
Section titled “Usage in a bot”Users import the factory function and pass config inline:
import { myModule } from '@scope/my-module';
export default defineConfig({ modules: [ myModule({ option1: true, option2: 42, }) ]});How it works
Section titled “How it works”createModuleEntryreadsimport.meta.urlto find the caller’s file path.- It walks up directories (up to 10 levels) looking for the nearest
package.json. - It reads the
namefield frompackage.jsonas the module identifier. - Returns a function that, when called with optional config, produces a
{ name, path, config }object.
getModuleConfig(framework, metaUrl)
Section titled “getModuleConfig(framework, metaUrl)”Retrieves the runtime configuration for a module. This is useful inside module services that need access to the module’s config from zumito.config.ts.
Signature
Section titled “Signature”function getModuleConfig<T extends Record<string, any>>( framework: ZumitoFramework, metaUrl: string): TUsage in a service
Section titled “Usage in a service”import { ServiceContainer, getModuleConfig } from 'zumito-framework';
const framework = ServiceContainer.getService(ZumitoFramework) as ZumitoFramework;const config = getModuleConfig<{ option1?: boolean }>(framework, import.meta.url);
if (config.option1) { // do something}How it works
Section titled “How it works”- Same directory walk-up logic as
createModuleEntryto discover the module name fromimport.meta.url. - Looks up
framework.settings.modulesfor an entry matching the discovered module name. - Returns the
configobject from that entry, or{}if none found.
Auto-discovery logic
Section titled “Auto-discovery logic”Both functions share the same findPackageJson() algorithm:
- Start from the directory containing the caller’s file (derived from
import.meta.url). - Walk up directories looking for
package.json. - Return the first one found, or throw an error (for
createModuleEntry) or return{}(forgetModuleConfig).
This means module helpers work from any subdirectory — you can call createModuleEntry or getModuleConfig from services/, routes/, or any nested path, and they will still find the correct module name.
Why factory functions?
Section titled “Why factory functions?”- Type safety — Config objects are typed per-module, with autocomplete in editors.
- No global side effects — Config is scoped to the specific module entry, avoiding ordering issues with static
.configure()calls. - Discoverability — Users can
importthe factory function and immediately see what options are available. - Backwards compatible — Modules can still be loaded via the legacy
bundlesarray or as plain strings in themodulesarray.
Related
Section titled “Related”- Module lifecycle — Lifecycle hooks and dependency declaration.
- Creating a module — Official module architecture overview.