{"version":3,"file":"plugin.cjs","names":["Effect","extractFromFiberFailure","ORPCError"],"sources":["../src/plugin.ts"],"sourcesContent":["import type { AnyContractRouter, AnySchema, InferSchemaOutput } from \"@orpc/contract\";\nimport { ORPCError } from \"@orpc/contract\";\nimport type { Context, Implementer, Router } from \"@orpc/server\";\nimport { implement, onError } from \"@orpc/server\";\nimport { Effect, type Scope } from \"effect\";\nimport { extractFromFiberFailure, formatORPCError } from \"./runtime/errors\";\n\ntype ContextOutput<T> = T extends AnySchema ? InferSchemaOutput<T> : Record<string, never>;\n\nexport type PluginConfigFor<\n  V extends AnySchema,\n  S extends AnySchema,\n  TRequestContext extends AnySchema | undefined,\n> = {\n  variables: V;\n  secrets: S;\n  context: TRequestContext;\n};\n\ntype PluginInitializeInput<V extends AnySchema, S extends AnySchema> = {\n  variables: InferSchemaOutput<V>;\n  secrets: InferSchemaOutput<S>;\n};\n\ntype PluginDefinition<\n  V extends AnySchema,\n  S extends AnySchema,\n  TContract extends AnyContractRouter,\n  TRequestContext extends AnySchema | undefined,\n  TDeps extends Context,\n  P extends Record<string, unknown>,\n> = {\n  variables: V;\n  secrets: S;\n  contract: TContract;\n  context?: TRequestContext;\n  initialize?: (\n    config: PluginInitializeInput<V, S>,\n    plugins: P,\n  ) => Effect.Effect<TDeps, Error, Scope.Scope>;\n  createRouter: (\n    deps: TDeps,\n    builder: Implementer<TContract, ContextOutput<TRequestContext>, ContextOutput<TRequestContext>>,\n  ) => Router<TContract, any>;\n  shutdown?: (deps: TDeps) => Effect.Effect<void, Error, never>;\n};\n\n/**\n * Loaded plugin with static binding property\n */\nexport interface LoadedPluginWithBinding<\n  TContract extends AnyContractRouter,\n  TVariables extends AnySchema,\n  TSecrets extends AnySchema,\n  TRequestContext extends AnySchema | undefined,\n  TDeps extends Context = Record<never, never>,\n> {\n  new (): Plugin<TContract, TVariables, TSecrets, TRequestContext, TDeps>;\n  binding: {\n    contract: TContract;\n    variables: TVariables;\n    secrets: TSecrets;\n    context: TRequestContext;\n  };\n}\n\n/**\n * Plugin interface\n */\nexport interface Plugin<\n  TContract extends AnyContractRouter,\n  TVariables extends AnySchema,\n  TSecrets extends AnySchema,\n  TRequestContext extends AnySchema | undefined,\n  TDeps extends Context = Record<never, never>,\n> {\n  readonly id: string;\n  readonly contract: TContract;\n  readonly configSchema: PluginConfigFor<TVariables, TSecrets, TRequestContext>;\n\n  initialize(\n    config: PluginInitializeInput<TVariables, TSecrets>,\n    plugins: Record<string, unknown>,\n  ): Effect.Effect<TDeps, unknown, Scope.Scope>;\n\n  shutdown(): Effect.Effect<void, never>;\n\n  /**\n   * Creates the strongly-typed oRPC router for this plugin.\n   * The router's procedure types are inferred directly from the contract.\n   * @param deps The initialized plugin dependencies\n   * @returns A router with procedures matching the plugin's contract\n   */\n  createRouter(deps: TDeps): Router<TContract, any>;\n}\n\nexport interface CreatePluginFn {\n  <\n    V extends AnySchema,\n    S extends AnySchema,\n    TContract extends AnyContractRouter,\n    TRequestContext extends AnySchema | undefined = undefined,\n    TDeps extends Context = Record<never, never>,\n    P extends Record<string, unknown> = Record<string, never>,\n  >(\n    config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,\n  ): LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;\n\n  withPlugins: <P extends Record<string, unknown>>() => CreatePluginWithPlugins<P>;\n}\n\nexport const createPlugin: CreatePluginFn = function createPlugin<\n  V extends AnySchema,\n  S extends AnySchema,\n  TContract extends AnyContractRouter,\n  TRequestContext extends AnySchema | undefined = undefined,\n  TDeps extends Context = Record<never, never>,\n  P extends Record<string, unknown> = Record<string, never>,\n>(config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>) {\n  const configSchema: PluginConfigFor<V, S, TRequestContext> = {\n    variables: config.variables,\n    secrets: config.secrets,\n    context: config.context as TRequestContext,\n  };\n\n  class CreatedPlugin implements Plugin<TContract, V, S, TRequestContext, TDeps> {\n    /** set during instantiation - registry key */\n    id!: string;\n    readonly contract = config.contract;\n    readonly configSchema = configSchema;\n\n    private _deps: TDeps | null = null;\n\n    initialize(\n      pluginConfig: PluginInitializeInput<V, S>,\n      plugins: Record<string, unknown> = {},\n    ): Effect.Effect<TDeps, unknown, Scope.Scope> {\n      const init = config.initialize ?? (() => Effect.succeed({} as TDeps));\n\n      return init(pluginConfig, plugins as P).pipe(\n        Effect.tap((deps) =>\n          Effect.sync(() => {\n            this._deps = deps;\n          }),\n        ),\n        Effect.map(() => this._deps as TDeps),\n        Effect.mapError((error) => error as unknown),\n      );\n    }\n\n    shutdown(): Effect.Effect<void, never> {\n      const self = this;\n      return Effect.gen(function* () {\n        if (config.shutdown && self._deps) {\n          yield* config\n            .shutdown(self._deps)\n            .pipe(\n              Effect.catchAll((error) =>\n                Effect.logWarning(`Plugin shutdown hook failed for ${self.id}`, error),\n              ),\n            );\n        }\n        self._deps = null;\n      });\n    }\n\n    createRouter(deps: TDeps): Router<TContract, any> {\n      const base = implement(config.contract).$context<ContextOutput<TRequestContext>>();\n      const errorMiddleware = onError((error: unknown) => {\n        const unwrapped = extractFromFiberFailure(error);\n\n        if (unwrapped !== error && unwrapped instanceof ORPCError) {\n          throw unwrapped;\n        }\n\n        formatORPCError(error);\n        throw error;\n      }) as any;\n\n      const builder = (base as any).use(errorMiddleware);\n      const router = config.createRouter(deps, builder as any);\n      return router as Router<TContract, any>;\n    }\n  }\n\n  const PluginConstructor = CreatedPlugin as unknown as {\n    new (): Plugin<TContract, V, S, TRequestContext, TDeps>;\n    binding: {\n      contract: TContract;\n      variables: V;\n      secrets: S;\n      context: TRequestContext;\n    };\n  };\n\n  PluginConstructor.binding = {\n    contract: config.contract,\n    variables: config.variables,\n    secrets: config.secrets,\n    context: config.context as TRequestContext,\n  };\n\n  return PluginConstructor as LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;\n};\n\nexport type CreatePluginWithPlugins<P extends Record<string, unknown>> = <\n  V extends AnySchema,\n  S extends AnySchema,\n  TContract extends AnyContractRouter,\n  TRequestContext extends AnySchema | undefined = undefined,\n  TDeps extends Context = Record<never, never>,\n>(\n  config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,\n) => LoadedPluginWithBinding<TContract, V, S, TRequestContext, TDeps>;\n\nexport function withPlugins<P extends Record<string, unknown>>(): CreatePluginWithPlugins<P> {\n  return <\n    V extends AnySchema,\n    S extends AnySchema,\n    TContract extends AnyContractRouter,\n    TRequestContext extends AnySchema | undefined = undefined,\n    TDeps extends Context = Record<never, never>,\n  >(\n    config: PluginDefinition<V, S, TContract, TRequestContext, TDeps, P>,\n  ) => createPlugin<V, S, TContract, TRequestContext, TDeps, P>(config as any);\n}\n\ncreatePlugin.withPlugins = withPlugins;\n"],"mappings":";;;;;;;AA+GA,MAAa,eAA+B,SAAS,aAOnD,QAAsE;CACtE,MAAM,eAAuD;EAC3D,WAAW,OAAO;EAClB,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB;CAED,MAAM,cAAyE;;EAE7E;EACA,AAAS,WAAW,OAAO;EAC3B,AAAS,eAAe;EAExB,AAAQ,QAAsB;EAE9B,WACE,cACA,UAAmC,EAAE,EACO;AAG5C,WAFa,OAAO,qBAAqBA,cAAO,QAAQ,EAAE,CAAU,GAExD,cAAc,QAAa,CAAC,KACtCA,cAAO,KAAK,SACVA,cAAO,WAAW;AAChB,SAAK,QAAQ;KACb,CACH,EACDA,cAAO,UAAU,KAAK,MAAe,EACrCA,cAAO,UAAU,UAAU,MAAiB,CAC7C;;EAGH,WAAuC;GACrC,MAAM,OAAO;AACb,UAAOA,cAAO,IAAI,aAAa;AAC7B,QAAI,OAAO,YAAY,KAAK,MAC1B,QAAO,OACJ,SAAS,KAAK,MAAM,CACpB,KACCA,cAAO,UAAU,UACfA,cAAO,WAAW,mCAAmC,KAAK,MAAM,MAAM,CACvE,CACF;AAEL,SAAK,QAAQ;KACb;;EAGJ,aAAa,MAAqC;GAChD,MAAM,mCAAiB,OAAO,SAAS,CAAC,UAA0C;GAClF,MAAM,6CAA2B,UAAmB;IAClD,MAAM,YAAYC,uCAAwB,MAAM;AAEhD,QAAI,cAAc,SAAS,qBAAqBC,yBAC9C,OAAM;AAGR,mCAAgB,MAAM;AACtB,UAAM;KACN;GAEF,MAAM,UAAW,KAAa,IAAI,gBAAgB;AAElD,UADe,OAAO,aAAa,MAAM,QAC5B;;;CAIjB,MAAM,oBAAoB;AAU1B,mBAAkB,UAAU;EAC1B,UAAU,OAAO;EACjB,WAAW,OAAO;EAClB,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB;AAED,QAAO;;AAaT,SAAgB,cAA6E;AAC3F,SAOE,WACG,aAAyD,OAAc;;AAG9E,aAAa,cAAc"}