effect-orpc 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -114,80 +114,17 @@ const effectOs = makeEffectORPC(runtime)
114
114
 
115
115
  // ✅ This compiles - ProvidedService is in the runtime
116
116
  const works = effectOs.effect(function* () {
117
- const svc = yield* ProvidedService
118
- return yield* svc.doSomething()
117
+ const service = yield* ProvidedService
118
+ return yield* service.doSomething()
119
119
  })
120
120
 
121
121
  // ❌ This fails to compile - MissingService is not in the runtime
122
122
  const fails = effectOs.effect(function* () {
123
- const svc = yield* MissingService // Type error!
124
- return yield* svc.doSomething()
123
+ const service = yield* MissingService // Type error!
124
+ return yield* service.doSomething()
125
125
  })
126
126
  ```
127
127
 
128
- ## Using Services
129
-
130
- ```ts
131
- import { makeEffectORPC } from 'effect-orpc'
132
- import { Context, Effect, Layer, ManagedRuntime } from 'effect'
133
- import { z } from 'zod'
134
-
135
- // Define services
136
- class DatabaseService extends Context.Tag('DatabaseService')<
137
- DatabaseService,
138
- {
139
- query: <T>(sql: string) => Effect.Effect<T[]>
140
- execute: (sql: string) => Effect.Effect<void>
141
- }
142
- >() {}
143
-
144
- class CacheService extends Context.Tag('CacheService')<
145
- CacheService,
146
- {
147
- get: <T>(key: string) => Effect.Effect<T | undefined>
148
- set: <T>(key: string, value: T, ttl?: number) => Effect.Effect<void>
149
- }
150
- >() {}
151
-
152
- // Create layers
153
- const DatabaseServiceLive = Layer.succeed(DatabaseService, {
154
- query: sql => Effect.succeed([]),
155
- execute: sql => Effect.succeed(undefined),
156
- })
157
-
158
- const CacheServiceLive = Layer.succeed(CacheService, {
159
- get: key => Effect.succeed(undefined),
160
- set: (key, value, ttl) => Effect.succeed(undefined),
161
- })
162
-
163
- // Compose layers
164
- const AppLive = Layer.mergeAll(DatabaseServiceLive, CacheServiceLive)
165
-
166
- // Create runtime with all services
167
- const runtime = ManagedRuntime.make(AppLive)
168
- const effectOs = makeEffectORPC(runtime)
169
-
170
- // Use multiple services in a procedure
171
- const getUserWithCache = effectOs
172
- .input(z.object({ id: z.string() }))
173
- .effect(function* ({ input }) {
174
- const cache = yield* CacheService
175
- const db = yield* DatabaseService
176
-
177
- // Try cache first
178
- const cached = yield* cache.get<User>(`user:${input.id}`)
179
- if (cached)
180
- return cached
181
-
182
- // Fall back to database
183
- const [user] = yield* db.query<User>(`SELECT * FROM users WHERE id = '${input.id}'`)
184
- if (user) {
185
- yield* cache.set(`user:${input.id}`, user, 3600)
186
- }
187
- return user
188
- })
189
- ```
190
-
191
128
  ## Wrapping a Customized Builder
192
129
 
193
130
  You can pass a customized oRPC builder as the second argument to inherit middleware, errors, and configuration:
@@ -264,7 +201,7 @@ const createPost = effectOs
264
201
  const user = yield* userService.findById(input.authorId)
265
202
 
266
203
  if (!user) {
267
- throw errors.NOT_FOUND()
204
+ return yield Effect.Fail(errors.NOT_FOUND())
268
205
  }
269
206
 
270
207
  const postService = yield* PostService
@@ -339,7 +276,7 @@ const getUser = effectOs
339
276
 
340
277
  if (!user) {
341
278
  // Use oRPC's type-safe errors
342
- throw errors.NOT_FOUND({ id: input.id })
279
+ yield* Effect.fail(errors.NOT_FOUND({ id: input.id }))
343
280
  }
344
281
 
345
282
  return user
@@ -350,7 +287,7 @@ const getUser = effectOs
350
287
 
351
288
  `ORPCTaggedError` lets you create Effect-native error classes that integrate seamlessly with oRPC. These errors:
352
289
 
353
- - Can be yielded in Effect generators (`yield* new MyError()`)
290
+ - Can be yielded in Effect generators (`yield* new MyError()` or `yield* Effect.fail(errors.MyError)`)
354
291
  - Have all ORPCError properties (code, status, data, defined)
355
292
  - Can be used in `.errors()` maps for type-safe error handling
356
293
  - Automatically convert to ORPCError when thrown
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ function createEffectErrorConstructorMap(errors) {
117
117
  }
118
118
  const config = target[code];
119
119
  if (isORPCTaggedErrorClass(config)) {
120
- return config;
120
+ return (...opts) => new config(...opts);
121
121
  }
122
122
  return (...rest) => {
123
123
  const options = resolveMaybeOptionalOptions(rest);
@@ -415,10 +415,10 @@ var EffectBuilder = class _EffectBuilder {
415
415
  lastEventId: opts.lastEventId,
416
416
  errors: createEffectErrorConstructorMap(this["~orpc"].effectErrorMap)
417
417
  };
418
- const baseEffect = effectFn(effectOpts);
419
418
  const spanName = spanConfig?.name ?? opts.path.join(".");
420
419
  const captureStackTrace = spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;
421
- const tracedEffect = Effect.withSpan(baseEffect, spanName, {
420
+ const resolver = Effect.fnUntraced(effectFn);
421
+ const tracedEffect = Effect.withSpan(resolver(effectOpts), spanName, {
422
422
  captureStackTrace
423
423
  });
424
424
  const exit = await runtime.runPromiseExit(tracedEffect, {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/effect-builder.ts","../src/effect-procedure.ts","../src/tagged-error.ts"],"sourcesContent":["import type { ORPCErrorCode } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaOutput,\n Meta,\n Route,\n Schema,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n BuilderDef,\n Context,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureHandlerOptions,\n} from \"@orpc/server\";\nimport type { IntersectPick } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport {\n mergeErrorMap,\n mergeMeta,\n mergeRoute,\n ORPCError,\n} from \"@orpc/contract\";\nimport {\n addMiddleware,\n Builder,\n decorateMiddleware,\n fallbackConfig,\n} from \"@orpc/server\";\nimport { Cause, Effect, Exit } from \"effect\";\n\nimport type {\n EffectErrorConstructorMap,\n EffectErrorMap,\n EffectErrorMapToUnion,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\n\nimport { EffectDecoratedProcedure } from \"./effect-procedure\";\nimport {\n createEffectErrorConstructorMap,\n effectErrorMapToErrorMap,\n isORPCTaggedError,\n} from \"./tagged-error\";\n\n/**\n * Captures the stack trace at the call site for better error reporting in spans.\n * This is called at procedure definition time to capture where the procedure was defined.\n *\n * @returns A function that lazily extracts the relevant stack frame\n */\nexport function addSpanStackTrace(): () => string | undefined {\n const ErrorConstructor = Error as typeof Error & {\n stackTraceLimit?: number;\n };\n const limit = ErrorConstructor.stackTraceLimit;\n ErrorConstructor.stackTraceLimit = 3;\n // eslint-disable-next-line unicorn/error-message\n const traceError = new Error();\n ErrorConstructor.stackTraceLimit = limit;\n let cache: false | string = false;\n return () => {\n if (cache !== false) {\n return cache;\n }\n if (traceError.stack !== undefined) {\n const stack = traceError.stack.split(\"\\n\");\n if (stack[3] !== undefined) {\n cache = stack[3].trim();\n return cache;\n }\n }\n };\n}\n\n/**\n * Configuration for Effect span tracing.\n */\nexport interface EffectSpanConfig {\n /**\n * The name of the span for telemetry.\n */\n name: string;\n /**\n * Function to lazily capture the stack trace at definition time.\n */\n captureStackTrace: () => string | undefined;\n}\n\n/**\n * Options passed to the Effect procedure handler.\n */\nexport interface EffectProcedureHandlerOptions<\n TCurrentContext extends Context,\n TInput,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n> extends Omit<\n ProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n ORPCErrorConstructorMap<any>,\n TMeta\n >,\n \"errors\"\n> {\n errors: EffectErrorConstructorMap<TEffectErrorMap>;\n}\n\n/**\n * Handler type for Effect procedures.\n * The handler receives procedure options and returns an Effect.\n */\nexport type EffectProcedureHandler<\n TCurrentContext extends Context,\n TInput,\n THandlerOutput,\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TMeta extends Meta,\n> = (\n opt: EffectProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n TEffectErrorMap,\n TMeta\n >,\n) => Effect.Effect<\n THandlerOutput,\n EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,\n TRequirementsProvided\n>;\n\n/**\n * Extended builder definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectBuilderDef<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends BuilderDef<TInputSchema, TOutputSchema, ErrorMap, TMeta> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n /**\n * Optional span configuration for Effect tracing.\n */\n spanConfig?: EffectSpanConfig;\n /**\n * Effect-extended error map that supports both traditional errors and tagged errors.\n */\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * Effect-native procedure builder that wraps an oRPC Builder instance\n * and adds Effect-specific capabilities while preserving Effect error\n * and requirements types.\n */\nexport class EffectBuilder<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> {\n \"~orpc\": EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n this[\"~orpc\"] = def;\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * // Traditional format\n * builder.errors({ BAD_REQUEST: { status: 400, message: 'Bad request' } })\n *\n * // Tagged error class\n * builder.errors({ USER_NOT_FOUND: UserNotFoundError })\n *\n * // Mixed\n * builder.errors({\n * BAD_REQUEST: { status: 400 },\n * USER_NOT_FOUND: UserNotFoundError,\n * })\n * ```\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n errorMap: mergeErrorMap(\n this[\"~orpc\"].errorMap,\n effectErrorMapToErrorMap(errors),\n ),\n effectErrorMap: {\n ...this[\"~orpc\"].effectErrorMap,\n ...errors,\n },\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n unknown,\n unknown,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectBuilder<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectBuilder<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectBuilder({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Defines the input validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Input Validation Docs}\n */\n input<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n USchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n inputSchema: schema,\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~orpc\"].config.initialInputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Defines the output validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Output Validation Docs}\n */\n output<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n USchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n outputSchema: schema,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~orpc\"].config.initialOutputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Adds a traceable span to the procedure for telemetry.\n * The span name is used for Effect tracing via `Effect.withSpan`.\n * Stack trace is captured at the call site for better error reporting.\n *\n * @param spanName - The name of the span for telemetry (e.g., 'users.getUser')\n * @returns An EffectBuilder with span tracing configured\n *\n * @example\n * ```ts\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .traced('users.getUser')\n * .effect(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * ```\n */\n traced(\n spanName: string,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n spanConfig: {\n name: spanName,\n captureStackTrace: addSpanStackTrace(),\n },\n });\n }\n\n /**\n * Defines the handler of the procedure using an Effect.\n * The Effect is executed using the ManagedRuntime provided during builder creation.\n * The effect is automatically wrapped with `Effect.withSpan`.\n *\n * @see {@link https://orpc.dev/docs/procedure Procedure Docs}\n */\n effect<UFuncOutput>(\n effectFn: EffectProcedureHandler<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n UFuncOutput,\n TEffectErrorMap,\n TRequirementsProvided,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n Schema<UFuncOutput, UFuncOutput>,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const { runtime, spanConfig } = this[\"~orpc\"];\n // Capture stack trace at definition time for default tracing\n const defaultCaptureStackTrace = addSpanStackTrace();\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n handler: async (opts) => {\n const effectOpts: EffectProcedureHandlerOptions<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n TEffectErrorMap,\n TMeta\n > = {\n context: opts.context,\n input: opts.input,\n path: opts.path,\n procedure: opts.procedure,\n signal: opts.signal,\n lastEventId: opts.lastEventId,\n errors: createEffectErrorConstructorMap(this[\"~orpc\"].effectErrorMap),\n };\n const baseEffect = effectFn(effectOpts);\n const spanName = spanConfig?.name ?? opts.path.join(\".\");\n const captureStackTrace =\n spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;\n const tracedEffect = Effect.withSpan(baseEffect, spanName, {\n captureStackTrace,\n });\n const exit = await runtime.runPromiseExit(tracedEffect, {\n signal: opts.signal,\n });\n\n if (Exit.isFailure(exit)) {\n throw Cause.match(exit.cause, {\n onDie(defect) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: defect,\n });\n },\n onFail(error) {\n if (isORPCTaggedError(error)) {\n return error.toORPCError();\n }\n if (error instanceof ORPCError) {\n return error;\n }\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: error,\n });\n },\n onInterrupt(fiberId) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(`${fiberId} Interrupted`),\n });\n },\n onSequential(left) {\n return left;\n },\n onEmpty: new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(\"Unknown error\"),\n }),\n onParallel(left) {\n return left;\n },\n });\n }\n\n return exit.value;\n },\n });\n }\n}\n\n/**\n * Any oRPC builder-like object that has the `~orpc` definition property.\n * This includes Builder, BuilderWithMiddlewares, ProcedureBuilder, etc.\n */\nexport interface AnyBuilderLike<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n> {\n \"~orpc\": BuilderDef<TInputSchema, TOutputSchema, TErrorMap, TMeta>;\n}\n\n/**\n * Creates an Effect-aware procedure builder with the specified ManagedRuntime.\n * Uses the default `os` builder from `@orpc/server`.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @returns An EffectBuilder instance for creating Effect-native procedures\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * const runtime = ManagedRuntime.make(Layer.empty)\n * const effectOs = makeEffectORPC(runtime)\n *\n * const hello = effectOs.effect(() => Effect.succeed('Hello!'))\n * ```\n */\nexport function makeEffectORPC<TRequirementsProvided, TRuntimeError>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n): EffectBuilder<\n Context,\n Context,\n Schema<unknown, unknown>,\n Schema<unknown, unknown>,\n Record<never, never>,\n Record<never, never>,\n TRequirementsProvided,\n TRuntimeError\n>;\n\n/**\n * Creates an Effect-aware procedure builder by wrapping an existing oRPC Builder\n * with the specified ManagedRuntime.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @param builder - The oRPC Builder instance to wrap (e.g., a customized `os`)\n * @returns An EffectBuilder instance that extends the original builder with Effect support\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { os } from '@orpc/server'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * // Create a customized builder\n * const authedOs = os.use(authMiddleware)\n *\n * // Wrap it with Effect support\n * const runtime = ManagedRuntime.make(UserServiceLive)\n * const effectOs = makeEffectORPC(runtime, authedOs)\n *\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .effect(\n * Effect.fn(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * )\n * ```\n */\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n>;\n\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder?: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n> {\n const resolvedBuilder =\n builder ?? emptyBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta>();\n return new EffectBuilder({\n ...resolvedBuilder[\"~orpc\"],\n effectErrorMap: resolvedBuilder[\"~orpc\"].errorMap,\n runtime,\n });\n}\n\nfunction emptyBuilder<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n>() {\n return new Builder<\n Record<never, never>,\n Record<never, never>,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta\n >({\n config: {},\n route: {},\n meta: {} as TMeta,\n errorMap: {} as TErrorMap,\n inputValidationIndex: fallbackConfig(\"initialInputValidationIndex\"),\n outputValidationIndex: fallbackConfig(\"initialOutputValidationIndex\"),\n middlewares: [],\n dedupeLeadingMiddlewares: true,\n });\n}\n","import type { ClientContext } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaInput,\n InferSchemaOutput,\n Meta,\n Route,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n Context,\n CreateProcedureClientOptions,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureActionableClient,\n ProcedureClient,\n ProcedureDef,\n} from \"@orpc/server\";\nimport type { IntersectPick, MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport { mergeMeta, mergeRoute } from \"@orpc/contract\";\nimport {\n addMiddleware,\n createActionableClient,\n createProcedureClient,\n decorateMiddleware,\n Procedure,\n} from \"@orpc/server\";\n\nimport type { EffectErrorMap, MergedEffectErrorMap } from \"./tagged-error\";\n\nimport { effectErrorMapToErrorMap } from \"./tagged-error\";\n\n/**\n * Extended procedure definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectProcedureDef<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * An Effect-native decorated procedure that preserves Effect error and requirements types.\n *\n * This class extends Procedure with additional type parameters for Effect-specific\n * type information, allowing full type inference of Effect errors and requirements.\n */\nexport class EffectDecoratedProcedure<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends Procedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n declare \"~orpc\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n super(def);\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const newEffectErrorMap = { ...this[\"~orpc\"].effectErrorMap, ...errors };\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n effectErrorMap: newEffectErrorMap,\n errorMap: effectErrorMapToErrorMap(newEffectErrorMap),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n InferSchemaOutput<TInputSchema>,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInput,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n UInput,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n mapInput: MapInputMiddleware<InferSchemaOutput<TInputSchema>, UInput>,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectDecoratedProcedure<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Make this procedure callable (works like a function while still being a procedure).\n *\n * @see {@link https://orpc.dev/docs/client/server-side Server-side Client Docs}\n */\n callable<TClientContext extends ClientContext>(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n TClientContext\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureClient<TClientContext, TInputSchema, TOutputSchema, ErrorMap> {\n const client: ProcedureClient<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createProcedureClient(this, ...rest);\n\n return new Proxy(client, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n\n /**\n * Make this procedure compatible with server action.\n *\n * @see {@link https://orpc.dev/docs/server-action Server Action Docs}\n */\n actionable(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n Record<never, never>\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureActionableClient<TInputSchema, TOutputSchema, ErrorMap> {\n const action: ProcedureActionableClient<\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createActionableClient(createProcedureClient(this, ...rest));\n\n return new Proxy(action, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n}\n","import type {\n ORPCErrorCode,\n ORPCErrorJSON,\n ORPCErrorOptions,\n} from \"@orpc/client\";\nimport type { AnySchema, ErrorMap, ErrorMapItem } from \"@orpc/contract\";\nimport type { ORPCErrorConstructorMapItemOptions } from \"@orpc/server\";\nimport type { MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { Pipeable, Types } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\nimport type * as Effect from \"effect/Effect\";\n\nimport {\n fallbackORPCErrorMessage,\n fallbackORPCErrorStatus,\n isORPCErrorStatus,\n ORPCError,\n} from \"@orpc/client\";\nimport { resolveMaybeOptionalOptions } from \"@orpc/shared\";\nimport * as Data from \"effect/Data\";\n\n/**\n * Symbol to access the underlying ORPCError instance\n */\nexport const ORPCErrorSymbol: unique symbol = Symbol.for(\n \"@orpc/effect/ORPCTaggedError\",\n);\n\n/**\n * Instance type for ORPCTaggedError that combines YieldableError with ORPCError properties\n */\nexport interface ORPCTaggedErrorInstance<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n>\n extends Cause.YieldableError, Pipeable.Pipeable {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag };\n toORPCError(): ORPCError<TCode, TData>;\n commit(): Effect.Effect<never, this, never>;\n}\n\n/**\n * Options for creating an ORPCTaggedError\n */\nexport type ORPCTaggedErrorOptions<TData> = Omit<\n ORPCErrorOptions<TData>,\n \"defined\"\n> & { defined?: boolean };\n\n/**\n * Constructor type for ORPCTaggedError classes\n */\nexport interface ORPCTaggedErrorClass<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n> {\n readonly _tag: TTag;\n readonly code: TCode;\n new (\n ...args: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ): ORPCTaggedErrorInstance<TTag, TCode, TData>;\n}\n\n/**\n * Type helper to infer the ORPCError type from an ORPCTaggedError\n */\nexport type InferORPCError<T> =\n T extends ORPCTaggedErrorInstance<string, infer TCode, infer TData>\n ? ORPCError<TCode, TData>\n : never;\n\n/**\n * Any ORPCTaggedErrorClass\n */\nexport type AnyORPCTaggedErrorClass = ORPCTaggedErrorClass<\n string,\n ORPCErrorCode,\n any\n>;\n\n/**\n * Check if a value is an ORPCTaggedErrorClass (constructor)\n */\nexport function isORPCTaggedErrorClass(\n value: unknown,\n): value is AnyORPCTaggedErrorClass {\n return (\n typeof value === \"function\" &&\n \"_tag\" in value &&\n \"code\" in value &&\n typeof value._tag === \"string\" &&\n typeof value.code === \"string\"\n );\n}\n\n/**\n * Check if a value is an ORPCTaggedError instance\n */\nexport function isORPCTaggedError(\n value: unknown,\n): value is ORPCTaggedErrorInstance<string, ORPCErrorCode, unknown> {\n return (\n typeof value === \"object\" && value !== null && ORPCErrorSymbol in value\n );\n}\n\n/**\n * Converts a PascalCase or camelCase string to CONSTANT_CASE.\n * e.g., \"UserNotFoundError\" -> \"USER_NOT_FOUND_ERROR\"\n */\nfunction toConstantCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1_$2\")\n .replace(/([A-Z])([A-Z][a-z])/g, \"$1_$2\")\n .toUpperCase();\n}\n\n// Type-level conversion: split on capital letters and join with underscore\ntype SplitOnCapital<\n S extends string,\n Acc extends string = \"\",\n> = S extends `${infer Head}${infer Tail}`\n ? Head extends Uppercase<Head>\n ? Head extends Lowercase<Head>\n ? SplitOnCapital<Tail, `${Acc}${Head}`>\n : Acc extends \"\"\n ? SplitOnCapital<Tail, Head>\n : `${Acc}_${SplitOnCapital<Tail, Head>}`\n : SplitOnCapital<Tail, `${Acc}${Uppercase<Head>}`>\n : Acc;\n\n/**\n * Converts a tag name to an error code in CONSTANT_CASE.\n */\nexport type TagToCode<TTag extends string> = SplitOnCapital<TTag>;\n\n/**\n * Creates a tagged error class that combines Effect's YieldableError with ORPCError.\n *\n * This allows you to create errors that:\n * - Can be yielded in Effect generators (`yield* myError`)\n * - Have all ORPCError properties (code, status, data, defined)\n * - Can be converted to a plain ORPCError for oRPC handlers\n *\n * The returned factory function takes:\n * - `tag` - The unique tag for this error type (used for discriminated unions)\n * - `codeOrOptions` - Optional ORPC error code or options. If omitted, code defaults to CONSTANT_CASE of tag\n * - `defaultOptions` - Optional default options for status and message (when code is provided)\n *\n * @example\n * ```ts\n * import { ORPCTaggedError } from '@orpc/effect'\n * import { Effect } from 'effect'\n *\n * // Define a custom error (code defaults to 'USER_NOT_FOUND_ERROR')\n * class UserNotFoundError extends ORPCTaggedError<UserNotFoundError>()('UserNotFoundError') {}\n *\n * // With explicit code\n * class NotFoundError extends ORPCTaggedError<NotFoundError>()('NotFoundError', 'NOT_FOUND') {}\n *\n * // Use in an Effect\n * const getUser = (id: string) => Effect.gen(function* () {\n * const user = yield* findUser(id)\n * if (!user) {\n * return yield* new UserNotFoundError({ data: { userId: id } })\n * }\n * return user\n * })\n *\n * // With custom data type\n * class ValidationError extends ORPCTaggedError<ValidationError, { fields: string[] }>()('ValidationError', 'BAD_REQUEST') {}\n *\n * // With options only (code defaults to 'VALIDATION_ERROR')\n * class ValidationError2 extends ORPCTaggedError<ValidationError2, { fields: string[] }>()(\n * 'ValidationError2',\n * { message: 'Validation failed' }\n * ) {}\n * ```\n */\n/**\n * Return type for the factory function with overloads\n */\ninterface ORPCTaggedErrorFactory<Self, TData> {\n // Overload 1: tag only (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 2: tag + options (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n options: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, options) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 3: tag + explicit code\n <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n code: TCode,\n defaultOptions?: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, code) {}\\``\n : ORPCTaggedErrorClass<TTag, TCode, TData>;\n}\n\nexport function ORPCTaggedError<\n Self,\n TData = undefined,\n>(): ORPCTaggedErrorFactory<Self, TData> {\n const factory = <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n codeOrOptions?: TCode | { status?: number; message?: string },\n defaultOptions?: { status?: number; message?: string },\n ): ORPCTaggedErrorClass<TTag, TCode, TData> => {\n // Determine if second arg is code or options\n const isCodeProvided = typeof codeOrOptions === \"string\";\n const code = (\n isCodeProvided ? codeOrOptions : toConstantCase(tag)\n ) as TCode;\n const options = isCodeProvided ? defaultOptions : codeOrOptions;\n\n const defaultStatus = options?.status;\n const defaultMessage = options?.message;\n\n // Use Effect's TaggedError as the base - this handles all Effect internals\n // (YieldableError, type symbols, commit(), Symbol.iterator, pipe(), etc.)\n const BaseTaggedError = Data.TaggedError(tag) as unknown as new (args: {\n message?: string;\n cause?: unknown;\n code: TCode;\n status: number;\n data: TData;\n defined: boolean;\n }) => Cause.YieldableError & {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n };\n\n class ORPCTaggedErrorBase extends BaseTaggedError {\n static readonly _tag = tag;\n static readonly code = code;\n\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n constructor(\n ...rest: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ) {\n const opts = resolveMaybeOptionalOptions(rest);\n const status = opts.status ?? defaultStatus;\n const inputMessage = opts.message ?? defaultMessage;\n\n if (status !== undefined && !isORPCErrorStatus(status)) {\n throw new globalThis.Error(\n \"[ORPCTaggedError] Invalid error status code.\",\n );\n }\n\n const finalStatus = fallbackORPCErrorStatus(code, status);\n const finalMessage = fallbackORPCErrorMessage(code, inputMessage);\n\n // Pass to Effect's TaggedError - it spreads these onto the instance\n super({\n message: finalMessage,\n cause: opts.cause,\n code,\n status: finalStatus,\n data: opts.data as TData,\n defined: opts.defined ?? true,\n });\n\n // Create the underlying ORPCError for interop\n this[ORPCErrorSymbol] = new ORPCError(code, {\n status: finalStatus,\n message: finalMessage,\n data: opts.data as TData,\n defined: this.defined,\n cause: opts.cause,\n });\n }\n\n /**\n * Converts this error to a plain ORPCError.\n * Useful when you need to return from an oRPC handler.\n */\n toORPCError(): ORPCError<TCode, TData> {\n return this[ORPCErrorSymbol];\n }\n\n override toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag } {\n return {\n _tag: this._tag,\n defined: this.defined,\n code: this.code,\n status: this.status,\n message: this.message,\n data: this.data,\n };\n }\n }\n\n return ORPCTaggedErrorBase as any;\n };\n\n return factory as ORPCTaggedErrorFactory<Self, TData>;\n}\n\n/**\n * Converts an ORPCTaggedError to a plain ORPCError.\n * Useful in handlers that need to throw ORPCError.\n *\n * @example\n * ```ts\n * const handler = effectOs.effect(function* () {\n * const result = yield* someOperation.pipe(\n * Effect.catchTag('UserNotFoundError', (e) =>\n * Effect.fail(toORPCError(e))\n * )\n * )\n * return result\n * })\n * ```\n */\nexport function toORPCError<TCode extends ORPCErrorCode, TData>(\n error: ORPCTaggedErrorInstance<string, TCode, TData>,\n): ORPCError<TCode, TData> {\n return error[ORPCErrorSymbol];\n}\n\n// ============================================================================\n// Extended Error Map Types for Effect\n// ============================================================================\n\n/**\n * An item in the EffectErrorMap - can be either a traditional ErrorMapItem or an ORPCTaggedErrorClass\n */\nexport type EffectErrorMapItem =\n | ErrorMapItem<AnySchema>\n | AnyORPCTaggedErrorClass;\n\n/**\n * Extended error map that supports both traditional oRPC errors and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * const errorMap = {\n * // Traditional format\n * BAD_REQUEST: { status: 400, message: 'Bad request' },\n *\n * // Tagged error class reference\n * USER_NOT_FOUND: UserNotFoundError,\n * } satisfies EffectErrorMap\n * ```\n */\nexport type EffectErrorMap = {\n [key in ORPCErrorCode]?: EffectErrorMapItem;\n};\n\n/**\n * Merges two EffectErrorMaps, with the second map taking precedence.\n */\nexport type MergedEffectErrorMap<\n T1 extends EffectErrorMap,\n T2 extends EffectErrorMap,\n> = T1 & T2;\n\n/**\n * Extracts the instance type from an EffectErrorMapItem\n */\nexport type EffectErrorMapItemToInstance<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> = T extends AnyORPCTaggedErrorClass\n ? InstanceType<T>\n : T extends { data?: infer TData }\n ? ORPCError<TCode, TData>\n : ORPCError<TCode, unknown>;\n\n/**\n * Converts an EffectErrorMap to a union of error instances.\n */\nexport type EffectErrorMapToUnion<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorMapItemToInstance<K, T[K]>\n : never\n : never;\n}[keyof T];\n\n/**\n * Type for the error constructors available in Effect handlers.\n * For tagged errors, it's the class constructor itself.\n * For traditional errors, it's a function that creates ORPCError.\n */\nexport type EffectErrorConstructorMapItem<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> =\n T extends ORPCTaggedErrorClass<infer _TTag, TCode, infer TData>\n ? ORPCTaggedErrorClass<_TTag, TCode, TData>\n : T extends { data?: infer TData }\n ? (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<TData>\n >\n ) => ORPCError<TCode, TData>\n : (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<unknown>\n >\n ) => ORPCError<TCode, unknown>;\n\n/**\n * Constructor map for EffectErrorMap - provides typed error constructors for handlers.\n */\nexport type EffectErrorConstructorMap<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorConstructorMapItem<K, T[K]>\n : never\n : never;\n};\n\n/**\n * Creates an error constructor map from an EffectErrorMap.\n * Tagged error classes are passed through directly.\n * Traditional error items become ORPCError factory functions.\n */\nexport function createEffectErrorConstructorMap<T extends EffectErrorMap>(\n errors: T | undefined,\n): EffectErrorConstructorMap<T> {\n const target = errors ?? ({} as T);\n const proxy = new Proxy(target, {\n get(proxyTarget, code) {\n if (typeof code !== \"string\") {\n return Reflect.get(proxyTarget, code);\n }\n\n const config = target[code];\n\n // If it's a tagged error class, return it directly\n if (isORPCTaggedErrorClass(config)) {\n return config;\n }\n\n // Otherwise, create a factory function for ORPCError\n return (\n ...rest: MaybeOptionalOptions<\n Omit<ORPCErrorOptions<unknown>, \"defined\" | \"status\">\n >\n ) => {\n const options = resolveMaybeOptionalOptions(rest);\n return new ORPCError(code, {\n defined: Boolean(config),\n status: config?.status,\n message: options.message ?? config?.message,\n data: options.data,\n cause: options.cause,\n });\n };\n },\n });\n\n return proxy as EffectErrorConstructorMap<T>;\n}\n\n/**\n * Converts an EffectErrorMap to a standard oRPC ErrorMap for interop.\n * Tagged error classes are converted to their equivalent ErrorMapItem format.\n */\nexport function effectErrorMapToErrorMap<T extends EffectErrorMap>(\n errorMap: T | undefined,\n): ErrorMap {\n const result: ErrorMap = {};\n\n if (!errorMap) {\n return result;\n }\n\n for (const [code, ClassOrErrorItem] of Object.entries(errorMap)) {\n if (!ClassOrErrorItem) {\n continue;\n }\n\n if (isORPCTaggedErrorClass(ClassOrErrorItem)) {\n const error = new ClassOrErrorItem().toORPCError();\n\n // For tagged errors, we create a minimal entry\n // The actual validation will be handled by the tagged error class\n result[code] = {\n status: error.status,\n message: error.message,\n data: error.data,\n };\n } else {\n result[code] = ClassOrErrorItem;\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["mergeMeta","mergeRoute","ORPCError","addMiddleware","decorateMiddleware","decorateMiddleware","addMiddleware","mergeMeta","mergeRoute","ORPCError"]}
1
+ {"version":3,"sources":["../src/effect-builder.ts","../src/effect-procedure.ts","../src/tagged-error.ts"],"sourcesContent":["import type { ORPCErrorCode } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaOutput,\n Meta,\n Route,\n Schema,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n BuilderDef,\n Context,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureHandlerOptions,\n} from \"@orpc/server\";\nimport type { IntersectPick } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\nimport type { YieldWrap } from \"effect/Utils\";\n\nimport {\n mergeErrorMap,\n mergeMeta,\n mergeRoute,\n ORPCError,\n} from \"@orpc/contract\";\nimport {\n addMiddleware,\n Builder,\n decorateMiddleware,\n fallbackConfig,\n} from \"@orpc/server\";\nimport { Cause, Effect, Exit } from \"effect\";\n\nimport type {\n EffectErrorConstructorMap,\n EffectErrorMap,\n EffectErrorMapToUnion,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\n\nimport { EffectDecoratedProcedure } from \"./effect-procedure\";\nimport {\n createEffectErrorConstructorMap,\n effectErrorMapToErrorMap,\n isORPCTaggedError,\n} from \"./tagged-error\";\n\n/**\n * Captures the stack trace at the call site for better error reporting in spans.\n * This is called at procedure definition time to capture where the procedure was defined.\n *\n * @returns A function that lazily extracts the relevant stack frame\n */\nexport function addSpanStackTrace(): () => string | undefined {\n const ErrorConstructor = Error as typeof Error & {\n stackTraceLimit?: number;\n };\n const limit = ErrorConstructor.stackTraceLimit;\n ErrorConstructor.stackTraceLimit = 3;\n const traceError = new Error();\n ErrorConstructor.stackTraceLimit = limit;\n let cache: false | string = false;\n return () => {\n if (cache !== false) {\n return cache;\n }\n if (traceError.stack !== undefined) {\n const stack = traceError.stack.split(\"\\n\");\n if (stack[3] !== undefined) {\n cache = stack[3].trim();\n return cache;\n }\n }\n };\n}\n\n/**\n * Configuration for Effect span tracing.\n */\nexport interface EffectSpanConfig {\n /**\n * The name of the span for telemetry.\n */\n name: string;\n /**\n * Function to lazily capture the stack trace at definition time.\n */\n captureStackTrace: () => string | undefined;\n}\n\n/**\n * Options passed to the Effect procedure handler.\n */\nexport interface EffectProcedureHandlerOptions<\n TCurrentContext extends Context,\n TInput,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n> extends Omit<\n ProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n ORPCErrorConstructorMap<any>,\n TMeta\n >,\n \"errors\"\n> {\n errors: EffectErrorConstructorMap<TEffectErrorMap>;\n}\n\n/**\n * Handler type for Effect procedures.\n * The handler receives procedure options and returns an Effect.\n */\nexport type EffectProcedureHandler<\n TCurrentContext extends Context,\n TInput,\n THandlerOutput,\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TMeta extends Meta,\n> = (\n opt: EffectProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n TEffectErrorMap,\n TMeta\n >,\n) => Generator<\n YieldWrap<\n Effect.Effect<\n any,\n | EffectErrorMapToUnion<TEffectErrorMap>\n | ORPCError<ORPCErrorCode, unknown>,\n TRequirementsProvided\n >\n >,\n THandlerOutput,\n never\n>;\n\n/**\n * Extended builder definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectBuilderDef<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends BuilderDef<TInputSchema, TOutputSchema, ErrorMap, TMeta> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n /**\n * Optional span configuration for Effect tracing.\n */\n spanConfig?: EffectSpanConfig;\n /**\n * Effect-extended error map that supports both traditional errors and tagged errors.\n */\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * Effect-native procedure builder that wraps an oRPC Builder instance\n * and adds Effect-specific capabilities while preserving Effect error\n * and requirements types.\n */\nexport class EffectBuilder<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> {\n \"~orpc\": EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n this[\"~orpc\"] = def;\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * // Traditional format\n * builder.errors({ BAD_REQUEST: { status: 400, message: 'Bad request' } })\n *\n * // Tagged error class\n * builder.errors({ USER_NOT_FOUND: UserNotFoundError })\n *\n * // Mixed\n * builder.errors({\n * BAD_REQUEST: { status: 400 },\n * USER_NOT_FOUND: UserNotFoundError,\n * })\n * ```\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n errorMap: mergeErrorMap(\n this[\"~orpc\"].errorMap,\n effectErrorMapToErrorMap(errors),\n ),\n effectErrorMap: {\n ...this[\"~orpc\"].effectErrorMap,\n ...errors,\n },\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n unknown,\n unknown,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectBuilder<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectBuilder<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectBuilder({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Defines the input validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Input Validation Docs}\n */\n input<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n USchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n inputSchema: schema,\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~orpc\"].config.initialInputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Defines the output validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Output Validation Docs}\n */\n output<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n USchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n outputSchema: schema,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~orpc\"].config.initialOutputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Adds a traceable span to the procedure for telemetry.\n * The span name is used for Effect tracing via `Effect.withSpan`.\n * Stack trace is captured at the call site for better error reporting.\n *\n * @param spanName - The name of the span for telemetry (e.g., 'users.getUser')\n * @returns An EffectBuilder with span tracing configured\n *\n * @example\n * ```ts\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .traced('users.getUser')\n * .effect(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * ```\n */\n traced(\n spanName: string,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n spanConfig: {\n name: spanName,\n captureStackTrace: addSpanStackTrace(),\n },\n });\n }\n\n /**\n * Defines the handler of the procedure using an Effect.\n * The Effect is executed using the ManagedRuntime provided during builder creation.\n * The effect is automatically wrapped with `Effect.withSpan`.\n *\n * @see {@link https://orpc.dev/docs/procedure Procedure Docs}\n */\n effect<UFuncOutput>(\n effectFn: EffectProcedureHandler<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n UFuncOutput,\n TEffectErrorMap,\n TRequirementsProvided,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n Schema<UFuncOutput, UFuncOutput>,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const { runtime, spanConfig } = this[\"~orpc\"];\n // Capture stack trace at definition time for default tracing\n const defaultCaptureStackTrace = addSpanStackTrace();\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n handler: async (opts) => {\n const effectOpts: EffectProcedureHandlerOptions<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n TEffectErrorMap,\n TMeta\n > = {\n context: opts.context,\n input: opts.input,\n path: opts.path,\n procedure: opts.procedure,\n signal: opts.signal,\n lastEventId: opts.lastEventId,\n errors: createEffectErrorConstructorMap(this[\"~orpc\"].effectErrorMap),\n };\n const spanName = spanConfig?.name ?? opts.path.join(\".\");\n const captureStackTrace =\n spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;\n const resolver = Effect.fnUntraced(effectFn);\n const tracedEffect = Effect.withSpan(resolver(effectOpts), spanName, {\n captureStackTrace,\n });\n const exit = await runtime.runPromiseExit(tracedEffect, {\n signal: opts.signal,\n });\n\n if (Exit.isFailure(exit)) {\n throw Cause.match(exit.cause, {\n onDie(defect) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: defect,\n });\n },\n onFail(error) {\n if (isORPCTaggedError(error)) {\n return error.toORPCError();\n }\n if (error instanceof ORPCError) {\n return error;\n }\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: error,\n });\n },\n onInterrupt(fiberId) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(`${fiberId} Interrupted`),\n });\n },\n onSequential(left) {\n return left;\n },\n onEmpty: new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(\"Unknown error\"),\n }),\n onParallel(left) {\n return left;\n },\n });\n }\n\n return exit.value;\n },\n });\n }\n}\n\n/**\n * Any oRPC builder-like object that has the `~orpc` definition property.\n * This includes Builder, BuilderWithMiddlewares, ProcedureBuilder, etc.\n */\nexport interface AnyBuilderLike<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n> {\n \"~orpc\": BuilderDef<TInputSchema, TOutputSchema, TErrorMap, TMeta>;\n}\n\n/**\n * Creates an Effect-aware procedure builder with the specified ManagedRuntime.\n * Uses the default `os` builder from `@orpc/server`.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @returns An EffectBuilder instance for creating Effect-native procedures\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * const runtime = ManagedRuntime.make(Layer.empty)\n * const effectOs = makeEffectORPC(runtime)\n *\n * const hello = effectOs.effect(() => Effect.succeed('Hello!'))\n * ```\n */\nexport function makeEffectORPC<TRequirementsProvided, TRuntimeError>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n): EffectBuilder<\n Context,\n Context,\n Schema<unknown, unknown>,\n Schema<unknown, unknown>,\n Record<never, never>,\n Record<never, never>,\n TRequirementsProvided,\n TRuntimeError\n>;\n\n/**\n * Creates an Effect-aware procedure builder by wrapping an existing oRPC Builder\n * with the specified ManagedRuntime.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @param builder - The oRPC Builder instance to wrap (e.g., a customized `os`)\n * @returns An EffectBuilder instance that extends the original builder with Effect support\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { os } from '@orpc/server'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * // Create a customized builder\n * const authedOs = os.use(authMiddleware)\n *\n * // Wrap it with Effect support\n * const runtime = ManagedRuntime.make(UserServiceLive)\n * const effectOs = makeEffectORPC(runtime, authedOs)\n *\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .effect(\n * Effect.fn(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * )\n * ```\n */\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n>;\n\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder?: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n> {\n const resolvedBuilder =\n builder ?? emptyBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta>();\n return new EffectBuilder({\n ...resolvedBuilder[\"~orpc\"],\n effectErrorMap: resolvedBuilder[\"~orpc\"].errorMap,\n runtime,\n });\n}\n\nfunction emptyBuilder<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n>() {\n return new Builder<\n Record<never, never>,\n Record<never, never>,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta\n >({\n config: {},\n route: {},\n meta: {} as TMeta,\n errorMap: {} as TErrorMap,\n inputValidationIndex: fallbackConfig(\"initialInputValidationIndex\"),\n outputValidationIndex: fallbackConfig(\"initialOutputValidationIndex\"),\n middlewares: [],\n dedupeLeadingMiddlewares: true,\n });\n}\n","import type { ClientContext } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaInput,\n InferSchemaOutput,\n Meta,\n Route,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n Context,\n CreateProcedureClientOptions,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureActionableClient,\n ProcedureClient,\n ProcedureDef,\n} from \"@orpc/server\";\nimport type { IntersectPick, MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport { mergeMeta, mergeRoute } from \"@orpc/contract\";\nimport {\n addMiddleware,\n createActionableClient,\n createProcedureClient,\n decorateMiddleware,\n Procedure,\n} from \"@orpc/server\";\n\nimport type { EffectErrorMap, MergedEffectErrorMap } from \"./tagged-error\";\n\nimport { effectErrorMapToErrorMap } from \"./tagged-error\";\n\n/**\n * Extended procedure definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectProcedureDef<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * An Effect-native decorated procedure that preserves Effect error and requirements types.\n *\n * This class extends Procedure with additional type parameters for Effect-specific\n * type information, allowing full type inference of Effect errors and requirements.\n */\nexport class EffectDecoratedProcedure<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends Procedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n declare \"~orpc\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n super(def);\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const newEffectErrorMap = { ...this[\"~orpc\"].effectErrorMap, ...errors };\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n effectErrorMap: newEffectErrorMap,\n errorMap: effectErrorMapToErrorMap(newEffectErrorMap),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n InferSchemaOutput<TInputSchema>,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInput,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n UInput,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n mapInput: MapInputMiddleware<InferSchemaOutput<TInputSchema>, UInput>,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectDecoratedProcedure<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Make this procedure callable (works like a function while still being a procedure).\n *\n * @see {@link https://orpc.dev/docs/client/server-side Server-side Client Docs}\n */\n callable<TClientContext extends ClientContext>(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n TClientContext\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureClient<TClientContext, TInputSchema, TOutputSchema, ErrorMap> {\n const client: ProcedureClient<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createProcedureClient(this, ...rest);\n\n return new Proxy(client, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n\n /**\n * Make this procedure compatible with server action.\n *\n * @see {@link https://orpc.dev/docs/server-action Server Action Docs}\n */\n actionable(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n Record<never, never>\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureActionableClient<TInputSchema, TOutputSchema, ErrorMap> {\n const action: ProcedureActionableClient<\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createActionableClient(createProcedureClient(this, ...rest));\n\n return new Proxy(action, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n}\n","import type {\n ORPCErrorCode,\n ORPCErrorJSON,\n ORPCErrorOptions,\n} from \"@orpc/client\";\nimport type { AnySchema, ErrorMap, ErrorMapItem } from \"@orpc/contract\";\nimport type { ORPCErrorConstructorMapItemOptions } from \"@orpc/server\";\nimport type { MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { Pipeable, Types } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\nimport type * as Effect from \"effect/Effect\";\n\nimport {\n fallbackORPCErrorMessage,\n fallbackORPCErrorStatus,\n isORPCErrorStatus,\n ORPCError,\n} from \"@orpc/client\";\nimport { resolveMaybeOptionalOptions } from \"@orpc/shared\";\nimport * as Data from \"effect/Data\";\n\n/**\n * Symbol to access the underlying ORPCError instance\n */\nexport const ORPCErrorSymbol: unique symbol = Symbol.for(\n \"@orpc/effect/ORPCTaggedError\",\n);\n\n/**\n * Instance type for ORPCTaggedError that combines YieldableError with ORPCError properties\n */\nexport interface ORPCTaggedErrorInstance<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n>\n extends Cause.YieldableError, Pipeable.Pipeable {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag };\n toORPCError(): ORPCError<TCode, TData>;\n commit(): Effect.Effect<never, this, never>;\n}\n\n/**\n * Options for creating an ORPCTaggedError\n */\nexport type ORPCTaggedErrorOptions<TData> = Omit<\n ORPCErrorOptions<TData>,\n \"defined\"\n> & { defined?: boolean };\n\n/**\n * Constructor type for ORPCTaggedError classes\n */\nexport interface ORPCTaggedErrorClass<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n> {\n readonly _tag: TTag;\n readonly code: TCode;\n new (\n ...args: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ): ORPCTaggedErrorInstance<TTag, TCode, TData>;\n}\n\n/**\n * Type helper to infer the ORPCError type from an ORPCTaggedError\n */\nexport type InferORPCError<T> =\n T extends ORPCTaggedErrorInstance<string, infer TCode, infer TData>\n ? ORPCError<TCode, TData>\n : never;\n\n/**\n * Any ORPCTaggedErrorClass\n * Uses `...args: any[]` for the constructor to accept any tagged error class,\n * regardless of whether TData requires options to be provided.\n */\nexport type AnyORPCTaggedErrorClass = {\n readonly _tag: string;\n readonly code: ORPCErrorCode;\n new (...args: any[]): ORPCTaggedErrorInstance<string, ORPCErrorCode, any>;\n};\n\n/**\n * Check if a value is an ORPCTaggedErrorClass (constructor)\n */\nexport function isORPCTaggedErrorClass(\n value: unknown,\n): value is AnyORPCTaggedErrorClass {\n return (\n typeof value === \"function\" &&\n \"_tag\" in value &&\n \"code\" in value &&\n typeof value._tag === \"string\" &&\n typeof value.code === \"string\"\n );\n}\n\n/**\n * Check if a value is an ORPCTaggedError instance\n */\nexport function isORPCTaggedError(\n value: unknown,\n): value is ORPCTaggedErrorInstance<string, ORPCErrorCode, unknown> {\n return (\n typeof value === \"object\" && value !== null && ORPCErrorSymbol in value\n );\n}\n\n/**\n * Converts a PascalCase or camelCase string to CONSTANT_CASE.\n * e.g., \"UserNotFoundError\" -> \"USER_NOT_FOUND_ERROR\"\n */\nfunction toConstantCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1_$2\")\n .replace(/([A-Z])([A-Z][a-z])/g, \"$1_$2\")\n .toUpperCase();\n}\n\n// Type-level conversion: split on capital letters and join with underscore\ntype SplitOnCapital<\n S extends string,\n Acc extends string = \"\",\n> = S extends `${infer Head}${infer Tail}`\n ? Head extends Uppercase<Head>\n ? Head extends Lowercase<Head>\n ? SplitOnCapital<Tail, `${Acc}${Head}`>\n : Acc extends \"\"\n ? SplitOnCapital<Tail, Head>\n : `${Acc}_${SplitOnCapital<Tail, Head>}`\n : SplitOnCapital<Tail, `${Acc}${Uppercase<Head>}`>\n : Acc;\n\n/**\n * Converts a tag name to an error code in CONSTANT_CASE.\n */\nexport type TagToCode<TTag extends string> = SplitOnCapital<TTag>;\n\n/**\n * Creates a tagged error class that combines Effect's YieldableError with ORPCError.\n *\n * This allows you to create errors that:\n * - Can be yielded in Effect generators (`yield* myError`)\n * - Have all ORPCError properties (code, status, data, defined)\n * - Can be converted to a plain ORPCError for oRPC handlers\n *\n * The returned factory function takes:\n * - `tag` - The unique tag for this error type (used for discriminated unions)\n * - `codeOrOptions` - Optional ORPC error code or options. If omitted, code defaults to CONSTANT_CASE of tag\n * - `defaultOptions` - Optional default options for status and message (when code is provided)\n *\n * @example\n * ```ts\n * import { ORPCTaggedError } from '@orpc/effect'\n * import { Effect } from 'effect'\n *\n * // Define a custom error (code defaults to 'USER_NOT_FOUND_ERROR')\n * class UserNotFoundError extends ORPCTaggedError<UserNotFoundError>()('UserNotFoundError') {}\n *\n * // With explicit code\n * class NotFoundError extends ORPCTaggedError<NotFoundError>()('NotFoundError', 'NOT_FOUND') {}\n *\n * // Use in an Effect\n * const getUser = (id: string) => Effect.gen(function* () {\n * const user = yield* findUser(id)\n * if (!user) {\n * return yield* new UserNotFoundError({ data: { userId: id } })\n * }\n * return user\n * })\n *\n * // With custom data type\n * class ValidationError extends ORPCTaggedError<ValidationError, { fields: string[] }>()('ValidationError', 'BAD_REQUEST') {}\n *\n * // With options only (code defaults to 'VALIDATION_ERROR')\n * class ValidationError2 extends ORPCTaggedError<ValidationError2, { fields: string[] }>()(\n * 'ValidationError2',\n * { message: 'Validation failed' }\n * ) {}\n * ```\n */\n/**\n * Return type for the factory function with overloads\n */\ninterface ORPCTaggedErrorFactory<Self, TData> {\n // Overload 1: tag only (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 2: tag + options (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n options: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, options) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 3: tag + explicit code\n <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n code: TCode,\n defaultOptions?: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, code) {}\\``\n : ORPCTaggedErrorClass<TTag, TCode, TData>;\n}\n\nexport function ORPCTaggedError<\n Self,\n TData = undefined,\n>(): ORPCTaggedErrorFactory<Self, TData> {\n const factory = <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n codeOrOptions?: TCode | { status?: number; message?: string },\n defaultOptions?: { status?: number; message?: string },\n ): ORPCTaggedErrorClass<TTag, TCode, TData> => {\n // Determine if second arg is code or options\n const isCodeProvided = typeof codeOrOptions === \"string\";\n const code = (\n isCodeProvided ? codeOrOptions : toConstantCase(tag)\n ) as TCode;\n const options = isCodeProvided ? defaultOptions : codeOrOptions;\n\n const defaultStatus = options?.status;\n const defaultMessage = options?.message;\n\n // Use Effect's TaggedError as the base - this handles all Effect internals\n // (YieldableError, type symbols, commit(), Symbol.iterator, pipe(), etc.)\n const BaseTaggedError = Data.TaggedError(tag) as unknown as new (args: {\n message?: string;\n cause?: unknown;\n code: TCode;\n status: number;\n data: TData;\n defined: boolean;\n }) => Cause.YieldableError & {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n };\n\n class ORPCTaggedErrorBase extends BaseTaggedError {\n static readonly _tag = tag;\n static readonly code = code;\n\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n constructor(\n ...rest: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ) {\n const opts = resolveMaybeOptionalOptions(rest);\n const status = opts.status ?? defaultStatus;\n const inputMessage = opts.message ?? defaultMessage;\n\n if (status !== undefined && !isORPCErrorStatus(status)) {\n throw new globalThis.Error(\n \"[ORPCTaggedError] Invalid error status code.\",\n );\n }\n\n const finalStatus = fallbackORPCErrorStatus(code, status);\n const finalMessage = fallbackORPCErrorMessage(code, inputMessage);\n\n // Pass to Effect's TaggedError - it spreads these onto the instance\n super({\n message: finalMessage,\n cause: opts.cause,\n code,\n status: finalStatus,\n data: opts.data as TData,\n defined: opts.defined ?? true,\n });\n\n // Create the underlying ORPCError for interop\n this[ORPCErrorSymbol] = new ORPCError(code, {\n status: finalStatus,\n message: finalMessage,\n data: opts.data as TData,\n defined: this.defined,\n cause: opts.cause,\n });\n }\n\n /**\n * Converts this error to a plain ORPCError.\n * Useful when you need to return from an oRPC handler.\n */\n toORPCError(): ORPCError<TCode, TData> {\n return this[ORPCErrorSymbol];\n }\n\n override toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag } {\n return {\n _tag: this._tag,\n defined: this.defined,\n code: this.code,\n status: this.status,\n message: this.message,\n data: this.data,\n };\n }\n }\n\n return ORPCTaggedErrorBase as any;\n };\n\n return factory as ORPCTaggedErrorFactory<Self, TData>;\n}\n\n/**\n * Converts an ORPCTaggedError to a plain ORPCError.\n * Useful in handlers that need to throw ORPCError.\n *\n * @example\n * ```ts\n * const handler = effectOs.effect(function* () {\n * const result = yield* someOperation.pipe(\n * Effect.catchTag('UserNotFoundError', (e) =>\n * Effect.fail(toORPCError(e))\n * )\n * )\n * return result\n * })\n * ```\n */\nexport function toORPCError<TCode extends ORPCErrorCode, TData>(\n error: ORPCTaggedErrorInstance<string, TCode, TData>,\n): ORPCError<TCode, TData> {\n return error[ORPCErrorSymbol];\n}\n\n// ============================================================================\n// Extended Error Map Types for Effect\n// ============================================================================\n\n/**\n * An item in the EffectErrorMap - can be either a traditional ErrorMapItem or an ORPCTaggedErrorClass\n */\nexport type EffectErrorMapItem =\n | ErrorMapItem<AnySchema>\n | AnyORPCTaggedErrorClass;\n\n/**\n * Extended error map that supports both traditional oRPC errors and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * const errorMap = {\n * // Traditional format\n * BAD_REQUEST: { status: 400, message: 'Bad request' },\n *\n * // Tagged error class reference\n * USER_NOT_FOUND: UserNotFoundError,\n * } satisfies EffectErrorMap\n * ```\n */\nexport type EffectErrorMap = {\n [key in ORPCErrorCode]?: EffectErrorMapItem;\n};\n\n/**\n * Merges two EffectErrorMaps, with the second map taking precedence.\n */\nexport type MergedEffectErrorMap<\n T1 extends EffectErrorMap,\n T2 extends EffectErrorMap,\n> = T1 & T2;\n\n/**\n * Extracts the instance type from an EffectErrorMapItem\n */\nexport type EffectErrorMapItemToInstance<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> = T extends AnyORPCTaggedErrorClass\n ? InstanceType<T>\n : T extends { data?: infer TData }\n ? ORPCError<TCode, TData>\n : ORPCError<TCode, unknown>;\n\n/**\n * Converts an EffectErrorMap to a union of error instances.\n */\nexport type EffectErrorMapToUnion<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorMapItemToInstance<K, T[K]>\n : never\n : never;\n}[keyof T];\n\n/**\n * Type for the error constructors available in Effect handlers.\n * For tagged errors, it's the class constructor itself.\n * For traditional errors, it's a function that creates ORPCError.\n */\nexport type EffectErrorConstructorMapItem<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> =\n T extends ORPCTaggedErrorClass<infer _TTag, TCode, infer TData>\n ? (\n ...args: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ) => ORPCTaggedErrorInstance<_TTag, TCode, TData>\n : T extends { data?: infer TData }\n ? (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<TData>\n >\n ) => ORPCError<TCode, TData>\n : (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<unknown>\n >\n ) => ORPCError<TCode, unknown>;\n\n/**\n * Constructor map for EffectErrorMap - provides typed error constructors for handlers.\n */\nexport type EffectErrorConstructorMap<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorConstructorMapItem<K, T[K]>\n : never\n : never;\n};\n\n/**\n * Creates an error constructor map from an EffectErrorMap.\n * Tagged error classes are passed through directly.\n * Traditional error items become ORPCError factory functions.\n */\nexport function createEffectErrorConstructorMap<T extends EffectErrorMap>(\n errors: T | undefined,\n): EffectErrorConstructorMap<T> {\n const target = errors ?? ({} as T);\n const proxy = new Proxy(target, {\n get(proxyTarget, code) {\n if (typeof code !== \"string\") {\n return Reflect.get(proxyTarget, code);\n }\n\n const config = target[code];\n\n // If it's a tagged error class, create a class constructor function\n if (isORPCTaggedErrorClass(config)) {\n return (\n ...opts: MaybeOptionalOptions<ORPCTaggedErrorOptions<unknown>>\n ) => new config(...opts);\n }\n\n // Otherwise, create a factory function for ORPCError\n return (\n ...rest: MaybeOptionalOptions<\n Omit<ORPCErrorOptions<unknown>, \"defined\" | \"status\">\n >\n ) => {\n const options = resolveMaybeOptionalOptions(rest);\n return new ORPCError(code, {\n defined: Boolean(config),\n status: config?.status,\n message: options.message ?? config?.message,\n data: options.data,\n cause: options.cause,\n });\n };\n },\n });\n\n return proxy as EffectErrorConstructorMap<T>;\n}\n\n/**\n * Converts an EffectErrorMap to a standard oRPC ErrorMap for interop.\n * Tagged error classes are converted to their equivalent ErrorMapItem format.\n */\nexport function effectErrorMapToErrorMap<T extends EffectErrorMap>(\n errorMap: T | undefined,\n): ErrorMap {\n const result: ErrorMap = {};\n\n if (!errorMap) {\n return result;\n }\n\n for (const [code, ClassOrErrorItem] of Object.entries(errorMap)) {\n if (!ClassOrErrorItem) {\n continue;\n }\n\n if (isORPCTaggedErrorClass(ClassOrErrorItem)) {\n const error = new ClassOrErrorItem().toORPCError();\n\n // For tagged errors, we create a minimal entry\n // The actual validation will be handled by the tagged error class\n result[code] = {\n status: error.status,\n message: error.message,\n data: error.data,\n };\n } else {\n result[code] = ClassOrErrorItem;\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["mergeMeta","mergeRoute","ORPCError","addMiddleware","decorateMiddleware","decorateMiddleware","addMiddleware","mergeMeta","mergeRoute","ORPCError"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-orpc",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "keywords": [
5
5
  "effect",
6
6
  "orpc",
@@ -80,12 +80,14 @@ export type InferORPCError<T> =
80
80
 
81
81
  /**
82
82
  * Any ORPCTaggedErrorClass
83
+ * Uses `...args: any[]` for the constructor to accept any tagged error class,
84
+ * regardless of whether TData requires options to be provided.
83
85
  */
84
- export type AnyORPCTaggedErrorClass = ORPCTaggedErrorClass<
85
- string,
86
- ORPCErrorCode,
87
- any
88
- >;
86
+ export type AnyORPCTaggedErrorClass = {
87
+ readonly _tag: string;
88
+ readonly code: ORPCErrorCode;
89
+ new (...args: any[]): ORPCTaggedErrorInstance<string, ORPCErrorCode, any>;
90
+ };
89
91
 
90
92
  /**
91
93
  * Check if a value is an ORPCTaggedErrorClass (constructor)
@@ -411,7 +413,9 @@ export type EffectErrorConstructorMapItem<
411
413
  T extends EffectErrorMapItem,
412
414
  > =
413
415
  T extends ORPCTaggedErrorClass<infer _TTag, TCode, infer TData>
414
- ? ORPCTaggedErrorClass<_TTag, TCode, TData>
416
+ ? (
417
+ ...args: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>
418
+ ) => ORPCTaggedErrorInstance<_TTag, TCode, TData>
415
419
  : T extends { data?: infer TData }
416
420
  ? (
417
421
  ...args: MaybeOptionalOptions<
@@ -96,8 +96,11 @@ describe("createEffectErrorConstructorMap", () => {
96
96
 
97
97
  const constructorMap = createEffectErrorConstructorMap(errorMap);
98
98
 
99
- expect(constructorMap.USER_NOT_FOUND_ERROR).toBe(UserNotFoundError);
100
- expect(constructorMap.FORBIDDEN).toBe(PermissionDenied);
99
+ const userNotFoundError = constructorMap.USER_NOT_FOUND_ERROR();
100
+ expect(userNotFoundError).toBeInstanceOf(UserNotFoundError);
101
+
102
+ const forbiddenError = constructorMap.FORBIDDEN();
103
+ expect(forbiddenError).toBeInstanceOf(PermissionDenied);
101
104
  });
102
105
 
103
106
  it("should create ORPCError factory for traditional items", () => {
@@ -135,7 +138,7 @@ describe("createEffectErrorConstructorMap", () => {
135
138
  expect(badRequestError.message).toBe("Invalid input");
136
139
 
137
140
  // Tagged error class is passed through
138
- const userNotFoundError = new constructorMap.USER_NOT_FOUND_ERROR();
141
+ const userNotFoundError = constructorMap.USER_NOT_FOUND_ERROR();
139
142
  expect(isORPCTaggedError(userNotFoundError)).toBe(true);
140
143
  expect(userNotFoundError._tag).toBe("UserNotFoundError");
141
144
  });
@@ -253,7 +256,7 @@ describe("effectBuilder with EffectErrorMap", () => {
253
256
  // oxlint-disable-next-line require-yield
254
257
  .effect(function* ({ input, errors }) {
255
258
  if (input.id === "not-found") {
256
- return yield* Effect.fail(new errors.USER_NOT_FOUND_ERROR());
259
+ return yield* Effect.fail(errors.USER_NOT_FOUND_ERROR());
257
260
  }
258
261
  return yield* Effect.succeed({ id: input.id, name: "Test User" });
259
262
  });