/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { type NonEmptyReadonlyArray } from "effect/Array" import type * as Effect from "effect/Effect" import type * as S from "effect/Schema" import type * as Scope from "effect/Scope" import type * as Stream from "effect/Stream" import { type Rpc, RpcMiddleware } from "effect/unstable/rpc" import { type TypeId } from "effect/unstable/rpc/RpcMiddleware" import type * as Context from "../Context.js" import { type GetEffectContext, type RpcContextMap } from "./RpcContextMap.js" export type RpcMiddlewareV4 = RpcMiddleware.RpcMiddleware export type RpcOptionsOriginal = { readonly optional?: boolean readonly error?: S.Top readonly requiredForClient?: boolean } export type RpcDynamic = { key: Key settings: A } export type AnyDynamic = { dynamic: RpcDynamic } export type DependsOn = { readonly dependsOn: NonEmptyReadonlyArray | undefined } export interface RpcOptionsDynamic extends RpcOptionsOriginal { readonly dynamic: RpcDynamic readonly dependsOn?: NonEmptyReadonlyArray | undefined } export type Dynamic = Options extends RpcOptionsDynamic ? true : false export interface RpcMiddlewareDynamic extends RpcMiddleware.RpcMiddleware {} export interface TagClassAny extends RpcMiddleware.AnyService { readonly optional: boolean readonly provides: any readonly requires: any readonly error: S.Top readonly dynamic?: RpcDynamic | undefined readonly dependsOn?: NonEmptyReadonlyArray | undefined } export declare namespace TagClass { /** * @since 1.0.0 * @category models */ export type FailureSchema = Options extends { readonly error: S.Top; readonly optional?: false } ? Options["error"] // actually not, the Failure depends on Dynamic Middleware Configuration! // : Options extends { readonly dynamic: RpcDynamic } ? A["error"] : typeof S.Never /** * @since 1.0.0 * @category models */ export type Failure = Options extends { readonly error: S.Codec; readonly optional?: false } ? _A // actually not, the Failure depends on Dynamic Middleware Configuration! : Options extends { readonly dynamic: RpcDynamic } ? S.Schema.Type : never /** * @since 1.0.0 * @category models */ export type FailureContext = S.Codec.DecodingServices> /** * @since 1.0.0 * @category models */ export type FailureService = Optional extends true ? unknown : Failure /** * @since 1.0.0 * @category models */ export type Optional = Options extends { readonly optional: true } ? true : false /** * @since 1.0.0 * @category models */ export type RequiredForClient = Options extends { readonly requiredForClient: true } ? true : false /** * @since 1.0.0 * @category models */ export interface Base< Self, Name extends string, Options, Service, Config extends { requires?: any provides?: any } > extends Context.Service { new(_: never): Context.ServiceClass.Shape readonly [TypeId]: TypeId readonly optional: Optional readonly error: FailureSchema readonly "~ClientError": Options extends { readonly clientError: infer CE } ? CE : never readonly provides: "provides" extends keyof Config ? Config["provides"] : never readonly requires: "requires" extends keyof Config ? Config["requires"] : never readonly dynamic: Options extends RpcOptionsDynamic ? Options["dynamic"] : undefined readonly dependsOn: Options extends DependsOn ? Options["dependsOn"] : undefined readonly requiredForClient: RequiredForClient } } export interface TagClass< Self, Name extends string, Options, Config extends { requires?: any provides?: any } = { requires: never; provides: never } > extends TagClass.Base< Self, Name, Options, Options extends RpcOptionsDynamic ? RpcMiddlewareDynamic< TagClass.FailureService, "requires" extends keyof Config ? Config["requires"] : never, { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] } > : RpcMiddlewareV4< "provides" extends keyof Config ? Config["provides"] : never, TagClass.Failure, "requires" extends keyof Config ? Config["requires"] : never >, Config > {} export const Tag = < Self, Config extends { requires?: any provides?: any } = { requires: never; provides: never } >() => < const Name extends string, const Options extends RpcOptionsOriginal | RpcOptionsDynamic = {} >( id: Name, options?: Options ): TagClass => class extends RpcMiddleware.Service()(id, options as any) { static readonly requires: "requires" extends keyof Config ? Config["requires"] : never static readonly provides: "provides" extends keyof Config ? Config["provides"] : never static readonly dynamic = options && "dynamic" in options ? options.dynamic : undefined static readonly dependsOn = options && "dependsOn" in options ? options.dependsOn : undefined } as any // not needed if there's official support in Rpc.Rpc. export type AddMiddleware = R extends Rpc.Rpc< infer _Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware > ? & Rpc.Rpc< _Tag, _Payload, _Success, _Error, _Middleware | Middleware > & { readonly config: R extends { readonly config: infer _C } ? _C : never } : never // customized versions to handle dynamically eliminated context. export type HandlersContext = keyof Handlers extends infer K ? K extends keyof Handlers & string ? HandlerContext : never : never export type HandlerContext = [Rpc.IsStream] extends [true] ? Handler extends (...args: any) => | Stream.Stream | Rpc.Wrapper> | Effect.Effect< infer _A, infer _EX, infer _R > | Rpc.Wrapper< Effect.Effect< infer _A, infer _EX, infer _R > > ? Exclude, Scope.Scope> : never : Handler extends ( ...args: any ) => Effect.Effect | Rpc.Wrapper> ? ExcludeProvides<_R, Rpcs, K> : never // new export type ExtractDynamicallyProvides = R extends Rpc.Rpc ? _Middleware extends { readonly requestContextMap: infer _RC } ? _RC extends Record // ? GetEffectContext<_RC, { allowAnonymous: false }> ? R extends { readonly config: infer _C } ? GetEffectContext<_RC, _C> : GetEffectContext<_RC, {}> : never : never : never export type ExtractProvides = R extends Rpc.Rpc ? _Middleware extends { readonly provides: infer _P } ? [_P] extends [never] ? never : _P /*_P extends Context.Service ? _I : never */ : never : never export type ExcludeProvides = Exclude< Env, // customisation is down here. ExtractProvides | ExtractDynamicallyProvides >