import { Loader } from "./loaders/index.js";
import { PathKeys, PropType } from "./types.js";
export interface StoreOptions {
    name?: string;
    loaders?: Loader[];
    loadersByEnvironment?: Record<string, Loader[]>;
}
type Config = object;
/**
 * Holds the configuration object.
 *
 * @example
 * ```
 * const store = new Store();
 * ```
 *
 * @public
 */
export declare class Store<TConfig extends Config = Record<string, unknown>> {
    #private;
    readonly options: Required<Pick<StoreOptions, "name">>;
    private config;
    constructor(options?: StoreOptions);
    /**
     * @internal
     */
    get name(): string;
    /**
     * @internal
     */
    private get environment();
    /**
     * The primary way to retrieve values from the {@link Store | Store}.
     * Can traverse through `Group` as well.
     *
     * @param accessor - the path to the desired value within the store.
     *
     * @example
     * ```
     * const store = new Store();
     *
     * const value = store.get("path.to.my.thing");
     * ```
     *
     * @public
     */
    get<P extends PathKeys<TConfig>>(accessor: P): PropType<TConfig, P>;
    /**
     * If the given accessor is not present on the store or the returned value is `null`,
     * an error will be thrown.
     *
     * {@link Store.get}
     */
    getOrThrow<P extends PathKeys<TConfig>>(accessor: P): PropType<TConfig, P>;
    /**
     * Manually set a value to the `Store`.
     * In most circumstances, you should not need to use this directly.
     *
     * @param accessor - the path to the desired value within the store.
     * @param value - the value to set at `accessor`
     *
     * @public
     */
    set(accessor: string, value: unknown): TConfig;
    /**
     * Register a `Loader` to this `Store`. Use {@link Store.init} to initialize all of the Store's
     * registered loaders.
     *
     * @param loader - Any `Loader` subclass
     *
     * @public
     */
    registerLoader(loader: Loader): this;
    /**
     * Registers multiple loaders at once.
     */
    registerLoaders(...loaders: Loader[]): this;
    /**
     *
     * @param loadersByEnvironment - An object composed of keys representing the
     * environment mapping to any loaders that should be registered. Will determine the
     * environment based on the value of `NODE_KONFIG_ENV` first (if set), `NODE_ENV` second (if set)
     * and default to "development"
     *
     * @example
     * ```
     * store.registerLoadersByEnvironment({
     *   development: [new FileLoader()],
     *   staging: [new VaultLoader()],
     *   production: [new VaultLoader()],
     * });
     *```
  
     * @public
     */
    registerLoadersByEnvironment(loadersByEnvironment: Record<string, Loader[]>): this;
    /**
     * Given a config, will recursively merge all of its properties onto this instance's config.
     * If a Group (ie `Store`) is encountered, it will correctly merge those properties onto that Group.
     *
     * @param config - The config to merge with this instance's config
     *
     * @public
     */
    assign(config: TConfig): this;
    /**
     * Used to initialize the `Store` and process all registered `Loaders` and groups within.
     *
     * @public
     */
    init(): Promise<void>;
    /**
     * Serialize the Store's configuration object. This will traverse all groups as well.
     *
     * @public
     */
    toJSON(): Record<string, unknown>;
    /**
     * Get or set a sub-`Store` (group). Once a group has been created, you can register loaders
     * specfic to that group. Calling `Store#init` on the parent `Store` will also initialize all the groups
     * registered to that `Store` instance.
     *
     * @param name - The name of the group. This name is also how you access the group after creation.
     * @param options - Any options to pass to the underlying store. Note that options will be **ignored**
     * on subsequent calls once the group has been initialized.
     *
     * @example
     * ```
     * const store = new Store();
     *
     * store.registerLoader(new Loader());
     *
     * const group = store.group("myGroup");
     *
     * group.registerLoader(new Loader());
     *
     * // Options can be passed to the store when creating a group
     * store.group("database", {
     *   loaders: [new Loader()]
     * })
     *
     * await store.init();
     * ```
     *
     * @public
     */
    group(name: string, options?: StoreOptions): Store;
}
export {};
//# sourceMappingURL=store.d.ts.map