import 'reflect-metadata'; import type { WireComponent } from './component.js'; import type { ComponentConstructor, ComponentDefinition, AdowireConfig } from './types.js'; /** * Discovers, registers, and instantiates adowire components. * * ## Name resolution * * Component names are derived from their file path relative to the components * root directory. Path segments are joined with dots and the file extension is * stripped: * * app/adowire/counter.ts → "counter" * app/adowire/posts/create.ts → "posts.create" * app/adowire/posts/index.ts → "posts.index" * * A component class can override auto-detected naming by setting a static * `componentName` property: * * ```ts * export default class MyCounter extends WireComponent { * static componentName = 'my-counter' * } * ``` * * ## Namespaces * * Additional component directories can be registered under a namespace prefix. * Components in a namespace are referenced as `namespace::component.name`: * * namespace "admin", path "app/adowire/admin" * app/adowire/admin/users.ts → "admin::users" * * Namespaces are configured in `config/adowire.ts` under `namespaces`. * * ## Usage * * ```ts * const registry = new ComponentRegistry(config) * await registry.discover() * * // Instantiate by name * const counter = await registry.make('counter') * * // Manual registration * registry.register('my-counter', MyCounter) * ``` */ export declare class ComponentRegistry { private readonly config; /** * All registered components keyed by their full name (including namespace * prefix if applicable), e.g. `"counter"`, `"posts.create"`, `"admin::users"`. */ private components; /** * Constructors for manually registered components. * Keyed by component name. */ private constructors; constructor(config: AdowireConfig); /** * Scan the configured component directories and register all found components. * * Auto-discovers from: * 1. The default `componentsPath` (default: `app/adowire`) * 2. Any namespace paths defined in `config.namespaces` * * This is called once at application boot by the service provider. * * @param appRoot Absolute path to the AdonisJS application root */ discover(appRoot: string): Promise; /** * Recursively scan a directory for component files. * * @param dir Current directory being scanned (absolute) * @param root Root of the component tree for this scan (absolute) * @param namespace Namespace prefix, or null for the default namespace */ private scanDirectory; /** * Import a component file and register the default export. * * @param filePath Absolute path to the component class file * @param root Root directory for name resolution * @param namespace Namespace prefix or null */ private registerFromFile; /** * Manually register a component class under the given name. * * This is the programmatic equivalent of file-based auto-discovery. * Manually registered components take precedence over auto-discovered ones * with the same name. * * ```ts * registry.register('counter', CounterComponent) * registry.register('admin::users', AdminUsersComponent) * ``` * * @param name The component name (dot-notation, with optional `namespace::` prefix) * @param Ctor The component constructor (class that extends WireComponent) */ register(name: string, Ctor: ComponentConstructor): void; /** * Create a fresh instance of the named component. * * @param name Component name (e.g. `"counter"`, `"posts.create"`, `"admin::users"`) * @returns A new, uninitialised `WireComponent` instance * @throws `ComponentNotFoundException` if the name is not registered */ make(name: string): InstanceType; /** * Return the `ComponentDefinition` for a registered component name. * Returns `undefined` if the component is not registered. */ get(name: string): ComponentDefinition | undefined; /** * Return `true` if a component with the given name is registered. */ has(name: string): boolean; /** * Return all registered component definitions as an array, sorted by name. */ all(): ComponentDefinition[]; /** * Return the total number of registered components. */ get size(): number; /** * Remove all registered components. Useful in tests. */ clear(): void; } /** * Derive a dot-notation component name from a file path. * * Examples (root = "/app/adowire", namespace = null): * /app/adowire/counter.ts → "counter" * /app/adowire/posts/create.ts → "posts.create" * /app/adowire/posts/index.ts → "posts.index" * * Examples (root = "/app/adowire/admin", namespace = "admin"): * /app/adowire/admin/users.ts → "admin::users" * /app/adowire/admin/roles/list.ts → "admin::roles.list" * * @param filePath Absolute path to the component file * @param root Absolute root directory for this namespace * @param namespace Namespace prefix (e.g. "admin"), or null for default */ export declare function resolveNameFromPath(filePath: string, root: string, namespace: string | null): string; /** * Convert a dot-notation component name to an Edge.js view path. * * Examples (prefix = "adowire"): * "counter" → "adowire/counter" * "posts.create" → "adowire/posts/create" * "admin::users" → "adowire/admin/users" * "admin::roles.list" → "adowire/admin/roles/list" * * @param name Dot-notation component name (with optional `namespace::` prefix) * @param prefix Edge view prefix (default: "adowire") */ export declare function nameToViewPath(name: string, prefix: string): string; /** * Thrown by `ComponentRegistry.make()` when the requested component name * has not been registered. */ export declare class ComponentNotFoundException extends Error { constructor(message: string); } export type { WireComponent };