import { AnyContractRouter, AnySchema, InferSchemaOutput } from "@orpc/contract";
import { Effect, Scope } from "effect";
import { Context as Context$1, Implementer, Router } from "@orpc/server";

//#region src/plugin.d.ts
type ContextOutput<T> = T extends AnySchema ? InferSchemaOutput<T> : Record<string, never>;
type PluginConfigFor<V extends AnySchema, S extends AnySchema, TRequestContext extends AnySchema | undefined> = {
  variables: V;
  secrets: S;
  context: TRequestContext;
};
type PluginInitializeInput<V extends AnySchema, S extends AnySchema> = {
  variables: InferSchemaOutput<V>;
  secrets: InferSchemaOutput<S>;
};
type PluginDefinition<V extends AnySchema, S extends AnySchema, TContract extends AnyContractRouter, TRequestContext extends AnySchema | undefined, TDeps extends Context$1, P extends Record<string, unknown>> = {
  variables: V;
  secrets: S;
  contract: TContract;
  context?: TRequestContext;
  initialize?: (config: PluginInitializeInput<V, S>, plugins: P) => Effect.Effect<TDeps, Error, Scope.Scope>;
  createRouter: (deps: TDeps, builder: Implementer<TContract, ContextOutput<TRequestContext>, ContextOutput<TRequestContext>>) => Router<TContract, any>;
  shutdown?: (deps: TDeps) => Effect.Effect<void, Error, never>;
};
/**
 * Loaded plugin with static binding property
 */
interface LoadedPluginWithBinding<TContract extends AnyContractRouter, TVariables extends AnySchema, TSecrets extends AnySchema, TRequestContext extends AnySchema | undefined, TDeps extends Context$1 = Record<never, never>> {
  new (): Plugin<TContract, TVariables, TSecrets, TRequestContext, TDeps>;
  binding: {
    contract: TContract;
    variables: TVariables;
    secrets: TSecrets;
    context: TRequestContext;
  };
}
/**
 * Plugin interface
 */
interface Plugin<TContract extends AnyContractRouter, TVariables extends AnySchema, TSecrets extends AnySchema, TRequestContext extends AnySchema | undefined, TDeps extends Context$1 = Record<never, never>> {
  readonly id: string;
  readonly contract: TContract;
  readonly configSchema: PluginConfigFor<TVariables, TSecrets, TRequestContext>;
  initialize(config: PluginInitializeInput<TVariables, TSecrets>, plugins: Record<string, unknown>): Effect.Effect<TDeps, unknown, Scope.Scope>;
  shutdown(): Effect.Effect<void, never>;
  /**
   * Creates the strongly-typed oRPC router for this plugin.
   * The router's procedure types are inferred directly from the contract.
   * @param deps The initialized plugin dependencies
   * @returns A router with procedures matching the plugin's contract
   */
  createRouter(deps: TDeps): Router<TContract, any>;
}
interface CreatePluginFn {
  <V extends AnySchema, S extends AnySchema, TContract extends AnyContractRouter, TRequestContext extends AnySchema | undefined = undefined, TDeps extends Context$1 = Record<never, never>, P extends Record<string, unknown> = Record<string, never>>(config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>): LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
  withPlugins: <P extends Record<string, unknown>>() => CreatePluginWithPlugins<P>;
}
declare const createPlugin: CreatePluginFn;
type CreatePluginWithPlugins<P extends Record<string, unknown>> = <V extends AnySchema, S extends AnySchema, TContract extends AnyContractRouter, TRequestContext extends AnySchema | undefined = undefined, TDeps extends Context$1 = Record<never, never>>(config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>) => LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;
declare function withPlugins<P extends Record<string, unknown>>(): CreatePluginWithPlugins<P>;
//#endregion
export { CreatePluginFn, CreatePluginWithPlugins, LoadedPluginWithBinding, Plugin, PluginConfigFor, createPlugin, withPlugins };
//# sourceMappingURL=plugin.d.mts.map