UNPKG

every-plugin

Version:
268 lines (267 loc) 8.9 kB
import { Plugin } from "./plugin.mjs"; import { AnyContractRouter, AnySchema, InferSchemaInput, InferSchemaOutput } from "@orpc/contract"; import { Scope } from "effect"; import { Router, RouterClient } from "@orpc/server"; //#region src/types.d.ts /** * Registry bindings interface - populated via module augmentation * Only needed for remote-only plugin entries. * @example * ```typescript * declare module "every-plugin" { * interface RegisteredPlugins { * "my-plugin": typeof MyPlugin; * } * } * ``` */ interface RegisteredPlugins {} /** * Base type for any plugin instance. */ type AnyPlugin = Plugin<AnyContractRouter, AnySchema, AnySchema, AnySchema | undefined, any>; /** * Loaded plugin constructor with binding information */ type AnyPluginConstructor = { new (): AnyPlugin; binding: { contract: AnyContractRouter; variables: AnySchema; secrets: AnySchema; context: AnySchema | undefined; }; }; /** * Registry entry that supports both direct module imports and remote URLs */ type PluginRegistryEntry = { module: AnyPluginConstructor; remote?: string; version?: string; description?: string; } | { remote: string; version?: string; description?: string; }; /** * Extract plugin constructor type from registry entry */ type ExtractPluginType<E> = E extends { module: infer M; } ? M : never; /** * Infer registry types from plugin entries with module constructors */ type InferRegistryFromEntries<R extends Record<string, PluginRegistryEntry>> = { [K in keyof R]: R[K] extends { module: infer M; } ? M : K extends keyof RegisteredPlugins ? RegisteredPlugins[K] : never }; /** * Extract contract type from plugin binding */ type PluginContract<T> = T extends { binding: { contract: infer C extends AnyContractRouter; }; } ? C : never; /** * Extract variables type from plugin binding */ type PluginVariables<T> = T extends { binding: { variables: infer V extends AnySchema; }; } ? V : never; /** * Extract secrets type from plugin binding */ type PluginSecrets<T> = T extends { binding: { secrets: infer S extends AnySchema; }; } ? S : never; /** * Extract context schema type from plugin binding */ type PluginContext<T> = T extends { binding: { context: infer C extends AnySchema | undefined; }; } ? C : never; /** * Extract router type from plugin binding * Uses 'any' for context to support nested router compositions */ type PluginRouterType<T> = Router<PluginContract<T>, any>; /** * Extract client type from plugin binding */ type PluginClientType<T> = RouterClient<PluginRouterType<T>>; /** * Extract plugin type from registered plugins by key * @param K - The plugin key * @param R - The registry type (defaults to RegisteredPlugins for module augmentation pattern) */ type RegisteredPlugin<K extends keyof R, R = RegisteredPlugins> = R[K] extends { binding: infer B; } ? B extends { contract: infer C extends AnyContractRouter; variables: infer V extends AnySchema; secrets: infer S extends AnySchema; context: infer TRequestContext extends AnySchema | undefined; } ? Plugin<C, V, S, TRequestContext, any> : never : never; /** * Extract plugin constructor type from registry entry */ type PluginConstructor<K extends keyof R, R = RegisteredPlugins> = RegisteredPlugin<K, R>; /** * Extract context input type from plugin binding (for client creation) */ type PluginContextInput<T> = PluginContext<T> extends AnySchema ? InferSchemaInput<PluginContext<T>> : never; /** * Extract config input type from plugin binding */ type PluginConfigInput<T> = { variables: InferSchemaInput<PluginVariables<T>>; secrets: InferSchemaInput<PluginSecrets<T>>; }; /** * Extract deps context type from plugin instance (used for initialization) */ type ContextOf<T extends AnyPlugin> = T extends Plugin<AnyContractRouter, AnySchema, AnySchema, AnySchema | undefined, infer TDeps> ? TDeps : never; /** * Plugin metadata for remote loading */ type PluginMetadata = { readonly remoteUrl: string; readonly version?: string; readonly description?: string; }; /** * Runtime registry configuration supporting both module and remote entries */ type PluginRegistry = Record<string, PluginRegistryEntry>; /** * Legacy metadata-only registry (for backwards compatibility) */ type PluginMetadataRegistry = Record<string, PluginMetadata>; /** * Configuration for secrets injection. * Secrets are hydrated into plugin configs using template replacement. */ interface SecretsConfig { [key: string]: string; } /** * Loaded plugin */ interface LoadedPlugin<T extends AnyPlugin = AnyPlugin> { readonly ctor: new () => T; readonly metadata: PluginMetadata; } /** * Instantiated plugin */ interface PluginInstance<T extends AnyPlugin = AnyPlugin> { readonly plugin: T; readonly metadata: PluginMetadata; } /** * Fully initialized plugin ready for use */ interface InitializedPlugin<T extends AnyPlugin = AnyPlugin> { readonly plugin: T; readonly metadata: PluginMetadata; readonly config: { variables: InferSchemaOutput<T["configSchema"]["variables"]>; secrets: InferSchemaOutput<T["configSchema"]["secrets"]>; }; readonly context: ContextOf<T>; readonly scope: Scope.CloseableScope; } /** * Helper type to detect type errors when looking up RegisteredPlugins */ type VerifyPluginBinding<K extends keyof R, R = RegisteredPlugins> = R[K] extends { binding: infer B; } ? B extends { contract: AnyContractRouter; variables: AnySchema; secrets: AnySchema; context: AnySchema | undefined; } ? true : ` Plugin "${K & string}" is not properly registered. Ensure it extends plugin binding layout { contract, variables, secrets, context }.` : ` Plugin "${K & string}" is not properly registered. Missing binding property.`; /** * Result of runtime.usePlugin() call * @param K - The plugin key * @param R - The registry type (defaults to RegisteredPlugins for module augmentation pattern) */ type UsePluginResult<K extends keyof R, R = RegisteredPlugins> = VerifyPluginBinding<K, R> extends true ? { readonly createClient: (context?: PluginContextInput<R[K]>) => PluginClientType<R[K]>; readonly router: PluginRouterType<R[K]>; readonly metadata: PluginMetadata; readonly initialized: InitializedPlugin<RegisteredPlugin<K, R>>; } : VerifyPluginBinding<K, R>; /** * Runtime options */ interface RuntimeOptions { isolation?: "strict" | "shared" | "none"; memoryLimit?: string; concurrency?: number; resourceTimeout?: string; debug?: boolean; metrics?: boolean; } /** * Extract registry type from runtime instance or use type directly * This allows EveryPlugin.Infer to work with both: * - typeof runtime (extracts registry from PluginRuntime<R> via __registryType) * - Registry types directly */ type RegistryOf<T> = T extends { __registryType?: infer R; } ? R : T; /** * Namespace containing type utilities for working with plugin results. */ declare namespace EveryPlugin { /** * Extract plugin runtime instance type from registered plugins or runtime. * Provides full type safety for plugin clients, routers, and metadata. * * @example * ```ts * // From RegisteredPlugins (module augmentation) * type Plugin = EveryPlugin.Infer<"my-plugin">; * * // From runtime instance (when using module entries) * const runtime = createPluginRuntime({ registry: { "my-plugin": { module: MyPlugin } } }); * type Plugin = EveryPlugin.Infer<"my-plugin", typeof runtime>; * * // From explicit registry type * type Plugin = EveryPlugin.Infer<"my-plugin", MyRegistryType>; * ``` */ type Infer<K extends string, Source = RegisteredPlugins> = K extends keyof RegistryOf<Source> ? UsePluginResult<K, RegistryOf<Source>> : never; } /** * Plugin runtime configuration with support for both module and remote entries */ interface PluginRuntimeConfig<R extends Record<string, PluginRegistryEntry> = Record<string, PluginRegistryEntry>> { registry: R; secrets?: SecretsConfig; options?: RuntimeOptions; } /** * Legacy plugin runtime configuration (metadata-only registry) * @deprecated Use PluginRuntimeConfig with module/remote entries instead */ interface LegacyPluginRuntimeConfig { registry: PluginMetadataRegistry; secrets?: SecretsConfig; options?: RuntimeOptions; } //#endregion export { AnyPlugin, AnyPluginConstructor, ContextOf, EveryPlugin, ExtractPluginType, InferRegistryFromEntries, InitializedPlugin, LegacyPluginRuntimeConfig, LoadedPlugin, PluginClientType, PluginConfigInput, PluginConstructor, PluginContext, PluginContextInput, PluginContract, PluginInstance, PluginMetadata, PluginMetadataRegistry, PluginRegistry, PluginRegistryEntry, PluginRouterType, PluginRuntimeConfig, PluginSecrets, PluginVariables, RegisteredPlugin, RegisteredPlugins, RuntimeOptions, SecretsConfig, UsePluginResult }; //# sourceMappingURL=types.d.mts.map