effect-orpc 0.0.7 → 0.0.9

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
@@ -1,6 +1,6 @@
1
1
  # effect-orpc
2
2
 
3
- A type-safe integration between [oRPC](https://orpc.dev/) and [Effect](https://effect.website/), enabling Effect-native procedures with full service injection support.
3
+ A type-safe integration between [oRPC](https://orpc.dev/) and [Effect](https://effect.website/), enabling Effect-native procedures with full service injection support, OpenTelemetry tracing support and typesafe Effect errors support.
4
4
 
5
5
  Inspired by [effect-trpc](https://github.com/mikearnaldi/effect-trpc).
6
6
 
@@ -23,7 +23,7 @@ pnpm add effect-orpc
23
23
  bun add effect-orpc
24
24
  ```
25
25
 
26
- ## Demo of the features
26
+ ## Demo
27
27
 
28
28
  ```ts
29
29
  import { os } from "@orpc/server";
@@ -51,7 +51,7 @@ const authedOs = os
51
51
  });
52
52
 
53
53
  // Define your services
54
- class UsersRepo extends Effect.Service<UsersRepo>()("UserService", {
54
+ class UsersRepo extends Effect.Service<UsersRepo>()("UsersRepo", {
55
55
  accessors: true,
56
56
  sync: () => ({
57
57
  get: (id: number) => users.find((u) => u.id === id),
@@ -59,13 +59,13 @@ class UsersRepo extends Effect.Service<UsersRepo>()("UserService", {
59
59
  }) {}
60
60
 
61
61
  // Special yieldable oRPC error class
62
- class UserNotFoundError extends ORPCTaggedError()("UserNotFoundError", {
62
+ class UserNotFoundError extends ORPCTaggedError("UserNotFoundError", {
63
63
  status: 404,
64
64
  }) {}
65
65
 
66
66
  // Create runtime with your services
67
67
  const runtime = ManagedRuntime.make(UsersRepo.Default);
68
- // Create Effect-aware oRPC builder from an other (optional) base oRPC builder
68
+ // Create Effect-aware oRPC builder from an other (optional) base oRPC builder and provide tagged errors
69
69
  const effectOs = makeEffectORPC(runtime, authedOs).errors({
70
70
  UserNotFoundError,
71
71
  });
@@ -170,27 +170,31 @@ const getUser = effectOs
170
170
  import { ORPCTaggedError } from "effect-orpc";
171
171
 
172
172
  // Basic tagged error - code defaults to 'USER_NOT_FOUND' (CONSTANT_CASE of tag)
173
- class UserNotFound extends ORPCTaggedError()("UserNotFound") {}
173
+ class UserNotFound extends ORPCTaggedError("UserNotFound") {}
174
174
 
175
175
  // With explicit code
176
- class NotFound extends ORPCTaggedError()("NotFound", "NOT_FOUND") {}
176
+ class NotFound extends ORPCTaggedError("NotFound", { code: "NOT_FOUND" }) {}
177
177
 
178
178
  // With default options (code defaults to 'VALIDATION_ERROR') (CONSTANT_CASE of tag)
179
- class ValidationError extends ORPCTaggedError()("ValidationError", {
179
+ class ValidationError extends ORPCTaggedError("ValidationError", {
180
180
  status: 400,
181
181
  message: "Validation failed",
182
182
  }) {}
183
183
 
184
- // With explicit code and options
185
- class Forbidden extends ORPCTaggedError()("Forbidden", "FORBIDDEN", {
184
+ // With all options
185
+ class ForbiddenError extends ORPCTaggedError("ForbiddenError", {
186
+ code: "FORBIDDEN",
186
187
  status: 403,
187
188
  message: "Access denied",
189
+ schema: z.object({
190
+ reason: z.string(),
191
+ }),
188
192
  }) {}
189
193
 
190
194
  // With typed data using Standard Schema
191
- class UserNotFoundWithData extends ORPCTaggedError(
192
- z.object({ userId: z.string() }),
193
- )("UserNotFoundWithData") {}
195
+ class UserNotFoundWithData extends ORPCTaggedError("UserNotFoundWithData", {
196
+ schema: z.object({ userId: z.string() }),
197
+ }) {}
194
198
  ```
195
199
 
196
200
  ## Traceable Spans
@@ -320,15 +324,16 @@ The result of calling `.effect()`. Extends standard oRPC `DecoratedProcedure` wi
320
324
  | `.callable(options?)` | Make procedure directly invocable |
321
325
  | `.actionable(options?)` | Make procedure compatible with server actions |
322
326
 
323
- ### `ORPCTaggedError(schema?)(tag, codeOrOptions?, defaultOptions?)`
327
+ ### `ORPCTaggedError(tag, options?)`
324
328
 
325
329
  Factory function to create Effect-native tagged error classes.
326
- If no code is provided, it defaults to CONSTANT_CASE of the tag (e.g., `UserNotFoundError` → `USER_NOT_FOUND_ERROR`).
327
330
 
328
- - `schema` - Optional Standard Schema for the error's data payload (e.g., `z.object({ userId: z.string() })`)
329
- - `tag` - Unique tag for discriminated unions (used by Effect's `catchTag`)
330
- - `codeOrOptions` - Either an ORPCErrorCode string or `{ status?, message? }` options
331
- - `defaultOptions` - Default `{ status?, message? }` when code is provided explicitly
331
+ The options is an optional object containing:
332
+
333
+ - `schema?` - Optional Standard Schema for the error's data payload (e.g., `z.object({ userId: z.string() })`)
334
+ - `code?` - Optional ORPCErrorCode, defaults to CONSTANT_CASE of the tag (e.g., `UserNotFoundError` → `USER_NOT_FOUND_ERROR`).
335
+ - `status?` - Sets the default status of the error
336
+ - `message` - Sets the default message of the error
332
337
 
333
338
  ## License
334
339
 
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  fallbackConfig,
14
14
  lazy as lazy2
15
15
  } from "@orpc/server";
16
- import { Cause, Effect, Exit } from "effect";
16
+ import { Cause as Cause2, Effect, Exit } from "effect";
17
17
 
18
18
  // src/effect-enhance-router.ts
19
19
  import {
@@ -48,6 +48,7 @@ import {
48
48
  ORPCError
49
49
  } from "@orpc/client";
50
50
  import { resolveMaybeOptionalOptions } from "@orpc/shared";
51
+ import "effect/Cause";
51
52
  import * as Data from "effect/Data";
52
53
  var ORPCErrorSymbol = /* @__PURE__ */ Symbol.for(
53
54
  "@orpc/effect/ORPCTaggedError"
@@ -61,68 +62,65 @@ function isORPCTaggedError(value) {
61
62
  function toConstantCase(str) {
62
63
  return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toUpperCase();
63
64
  }
64
- function ORPCTaggedError(schema) {
65
- const factory = (tag, codeOrOptions, defaultOptions) => {
66
- const isCodeProvided = typeof codeOrOptions === "string";
67
- const code = isCodeProvided ? codeOrOptions : toConstantCase(tag);
68
- const options = isCodeProvided ? defaultOptions : codeOrOptions;
69
- const defaultStatus = options?.status;
70
- const defaultMessage = options?.message;
71
- const BaseTaggedError = Data.TaggedError(tag);
72
- class ORPCTaggedErrorBase extends BaseTaggedError {
73
- static schema = schema;
74
- static _tag = tag;
75
- static code = code;
76
- [ORPCErrorSymbol];
77
- constructor(...rest) {
78
- const opts = resolveMaybeOptionalOptions(rest);
79
- const status = opts.status ?? defaultStatus;
80
- const inputMessage = opts.message ?? defaultMessage;
81
- if (status !== void 0 && !isORPCErrorStatus(status)) {
82
- throw new globalThis.Error(
83
- "[ORPCTaggedError] Invalid error status code."
84
- );
85
- }
86
- const finalStatus = fallbackORPCErrorStatus(code, status);
87
- const finalMessage = fallbackORPCErrorMessage(code, inputMessage);
88
- const data = opts.data;
89
- super({
90
- message: finalMessage,
91
- cause: opts.cause,
92
- code,
93
- status: finalStatus,
94
- data,
95
- defined: opts.defined ?? true
96
- });
97
- this[ORPCErrorSymbol] = new ORPCError(code, {
98
- status: finalStatus,
99
- message: finalMessage,
100
- data,
101
- defined: this.defined,
102
- cause: opts.cause
103
- });
65
+ function ORPCTaggedError(tag, props) {
66
+ const code = props?.code ?? toConstantCase(tag);
67
+ class ORPCTaggedErrorBase extends Data.TaggedError(tag) {
68
+ status;
69
+ defined;
70
+ data;
71
+ code = code;
72
+ schema = props?.schema;
73
+ [ORPCErrorSymbol];
74
+ constructor(...rest) {
75
+ super();
76
+ const opts = resolveMaybeOptionalOptions(rest);
77
+ const status = opts.status ?? props?.status;
78
+ if (status !== void 0 && !isORPCErrorStatus(status)) {
79
+ throw new globalThis.Error(
80
+ "[ORPCTaggedError] Invalid error status code."
81
+ );
104
82
  }
105
- /**
106
- * Converts this error to a plain ORPCError.
107
- * Useful when you need to return from an oRPC handler.
108
- */
109
- toORPCError() {
110
- return this[ORPCErrorSymbol];
111
- }
112
- toJSON() {
113
- return {
114
- _tag: this._tag,
115
- defined: this.defined,
116
- code: this.code,
83
+ this.status = fallbackORPCErrorStatus(code, status);
84
+ this.defined = opts.defined ?? true;
85
+ this.data = opts.data;
86
+ this.message = fallbackORPCErrorMessage(
87
+ this.code,
88
+ opts.message ?? props?.message
89
+ );
90
+ this.cause = opts.cause;
91
+ this[ORPCErrorSymbol] = new ORPCError(
92
+ this.code,
93
+ {
117
94
  status: this.status,
118
95
  message: this.message,
119
- data: this.data
120
- };
121
- }
96
+ data: this.data,
97
+ defined: this.defined,
98
+ cause: this.cause
99
+ }
100
+ );
122
101
  }
123
- return ORPCTaggedErrorBase;
124
- };
125
- return factory;
102
+ /**
103
+ * Converts this error to a plain ORPCError.
104
+ * Useful when you need to return from an oRPC handler.
105
+ */
106
+ toORPCError() {
107
+ return this[ORPCErrorSymbol];
108
+ }
109
+ toJSON() {
110
+ return {
111
+ _tag: this._tag,
112
+ defined: this[ORPCErrorSymbol].defined,
113
+ code: this[ORPCErrorSymbol].code,
114
+ status: this[ORPCErrorSymbol].status,
115
+ message: this[ORPCErrorSymbol].message,
116
+ data: this[ORPCErrorSymbol].data
117
+ };
118
+ }
119
+ }
120
+ return Object.assign(ORPCTaggedErrorBase, {
121
+ _tag: tag,
122
+ code
123
+ });
126
124
  }
127
125
  function toORPCError(error) {
128
126
  return error[ORPCErrorSymbol];
@@ -602,7 +600,7 @@ var EffectBuilder = class _EffectBuilder {
602
600
  signal: opts.signal
603
601
  });
604
602
  if (Exit.isFailure(exit)) {
605
- throw Cause.match(exit.cause, {
603
+ throw Cause2.match(exit.cause, {
606
604
  onDie(defect) {
607
605
  return new ORPCError2("INTERNAL_SERVER_ERROR", {
608
606
  cause: defect
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/effect-builder.ts","../src/effect-enhance-router.ts","../src/effect-procedure.ts","../src/tagged-error.ts"],"sourcesContent":["import type {\n AnySchema,\n ContractRouter,\n ErrorMap,\n HTTPPath,\n InferSchemaOutput,\n Meta,\n Route,\n Schema,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n BuilderConfig,\n BuilderDef,\n Context,\n Lazy,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ProcedureHandler,\n ProcedureHandlerOptions,\n Router,\n} from \"@orpc/server\";\nimport type { IntersectPick } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport {\n mergeMeta,\n mergePrefix,\n mergeRoute,\n mergeTags,\n ORPCError,\n} from \"@orpc/contract\";\nimport {\n addMiddleware,\n Builder,\n decorateMiddleware,\n fallbackConfig,\n lazy,\n} from \"@orpc/server\";\nimport { Cause, Effect, Exit } from \"effect\";\n\nimport type {\n EffectErrorConstructorMap,\n EffectErrorMap,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\nimport type {\n AnyBuilderLike,\n EffectBuilderDef,\n EffectErrorMapToErrorMap,\n EffectProcedureBuilderWithInput,\n EffectProcedureHandler,\n EffectRouterBuilder,\n EnhancedEffectRouter,\n InferBuilderCurrentContext,\n InferBuilderErrorMap,\n InferBuilderInitialContext,\n InferBuilderInputSchema,\n InferBuilderMeta,\n InferBuilderOutputSchema,\n} from \"./types\";\n\nimport { enhanceEffectRouter } from \"./effect-enhance-router\";\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 * 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 /**\n * This property holds the defined options and the effect-specific properties.\n */\n declare \"~effect\": EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n declare \"~orpc\": BuilderDef<\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\n >;\n\n constructor(\n def: EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n const { runtime, spanConfig, effectErrorMap, ...orpcDef } = def;\n this[\"~orpc\"] = orpcDef;\n this[\"~effect\"] = { runtime, spanConfig, effectErrorMap, ...orpcDef };\n }\n\n /**\n * Sets or overrides the config.\n *\n * @see {@link https://orpc.dev/docs/client/server-side#middlewares-order Middlewares Order Docs}\n * @see {@link https://orpc.dev/docs/best-practices/dedupe-middleware#configuration Dedupe Middleware Docs}\n */\n $config(\n config: BuilderConfig,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const inputValidationCount =\n this[\"~effect\"].inputValidationIndex -\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~effect\"].config.initialInputValidationIndex,\n );\n const outputValidationCount =\n this[\"~effect\"].outputValidationIndex -\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~effect\"].config.initialOutputValidationIndex,\n );\n\n return new EffectBuilder({\n ...this[\"~effect\"],\n config,\n dedupeLeadingMiddlewares: fallbackConfig(\n \"dedupeLeadingMiddlewares\",\n config.dedupeLeadingMiddlewares,\n ),\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n config.initialInputValidationIndex,\n ) + inputValidationCount,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n config.initialOutputValidationIndex,\n ) + outputValidationCount,\n });\n }\n\n /**\n * Set or override the initial context.\n *\n * @see {@link https://orpc.dev/docs/context Context Docs}\n */\n $context<U extends Context>(): EffectBuilder<\n U & Record<never, never>,\n U,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n /**\n * We need `& Record<never, never>` to deal with `has no properties in common with type` error\n */\n\n return new EffectBuilder({\n ...this[\"~effect\"],\n middlewares: [],\n inputValidationIndex: fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~effect\"].config.initialInputValidationIndex,\n ),\n outputValidationIndex: fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~effect\"].config.initialOutputValidationIndex,\n ),\n });\n }\n\n /**\n * Sets or overrides the initial meta.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n $meta<U extends Meta>(\n initialMeta: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n U & Record<never, never>,\n TRequirementsProvided,\n TRuntimeError\n > {\n /**\n * We need `& Record<never, never>` to deal with `has no properties in common with type` error\n */\n\n return new EffectBuilder({\n ...this[\"~effect\"],\n meta: initialMeta,\n });\n }\n\n /**\n * Sets or overrides the initial 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 initialRoute: 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[\"~effect\"],\n route: initialRoute,\n });\n }\n\n /**\n * Sets or overrides the initial input schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#initial-configuration Initial Procedure Configuration Docs}\n */\n $input<U extends AnySchema>(\n initialInputSchema?: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n U,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n inputSchema: initialInputSchema,\n });\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 const newEffectErrorMap: MergedEffectErrorMap<TEffectErrorMap, U> = {\n ...this[\"~effect\"].effectErrorMap,\n ...errors,\n };\n return new EffectBuilder({\n ...this[\"~effect\"],\n errorMap: effectErrorMapToErrorMap(newEffectErrorMap),\n effectErrorMap: newEffectErrorMap,\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 InferSchemaOutput<TInputSchema>,\n unknown,\n EffectErrorConstructorMap<TEffectErrorMap>,\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[\"~effect\"],\n middlewares: addMiddleware(this[\"~effect\"].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[\"~effect\"],\n meta: mergeMeta(this[\"~effect\"].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[\"~effect\"],\n route: mergeRoute(this[\"~effect\"].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 ): EffectProcedureBuilderWithInput<\n TInitialContext,\n TCurrentContext,\n USchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n inputSchema: schema,\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~effect\"].config.initialInputValidationIndex,\n ) + this[\"~effect\"].middlewares.length,\n // we cast to any because EffectProcedureBuilderWithInput is expecting\n // use() input type to be defined, and EffectBuilder types its use() input\n // to unknown to allow any middleware to be passed\n // ---\n // note: the original implentation of the builder also uses any for the same reason\n }) as any;\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[\"~effect\"],\n outputSchema: schema,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~effect\"].config.initialOutputValidationIndex,\n ) + this[\"~effect\"].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[\"~effect\"],\n spanConfig: {\n name: spanName,\n captureStackTrace: addSpanStackTrace(),\n },\n });\n }\n\n handler<UFuncOutput>(\n handler: ProcedureHandler<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n UFuncOutput,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\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 return new EffectDecoratedProcedure({\n ...this[\"~effect\"],\n handler,\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 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[\"~effect\"];\n // Capture stack trace at definition time for default tracing\n const defaultCaptureStackTrace = addSpanStackTrace();\n return new EffectDecoratedProcedure({\n ...this[\"~effect\"],\n handler: async (opts) => {\n const effectOpts: ProcedureHandlerOptions<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n EffectErrorConstructorMap<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(\n this[\"~effect\"].effectErrorMap,\n ),\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 * Prefixes all procedures in the router.\n * The provided prefix is post-appended to any existing router prefix.\n *\n * @note This option does not affect procedures that do not define a path in their route definition.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing#route-prefixes OpenAPI Route Prefixes Docs}\n */\n prefix(\n prefix: HTTPPath,\n ): EffectRouterBuilder<\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n prefix: mergePrefix(this[\"~effect\"].prefix, prefix),\n }) as any;\n }\n\n /**\n * Adds tags to all procedures in the router.\n * This helpful when you want to group procedures together in the OpenAPI specification.\n *\n * @see {@link https://orpc.dev/docs/openapi/openapi-specification#operation-metadata OpenAPI Operation Metadata Docs}\n */\n tag(\n ...tags: string[]\n ): EffectRouterBuilder<\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n tags: mergeTags(this[\"~effect\"].tags, tags),\n }) as any;\n }\n\n /**\n * Applies all of the previously defined options to the specified router.\n *\n * @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}\n */\n router<U extends Router<ContractRouter<TMeta>, TCurrentContext>>(\n router: U,\n ): EnhancedEffectRouter<\n U,\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap\n > {\n return enhanceEffectRouter(router, {\n ...this[\"~effect\"],\n }) as any; // Type instantiation is excessively deep and possibly infinite\n }\n\n /**\n * Create a lazy router\n * And applies all of the previously defined options to the specified router.\n *\n * @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}\n */\n lazy<U extends Router<ContractRouter<TMeta>, TCurrentContext>>(\n loader: () => Promise<{ default: U }>,\n ): EnhancedEffectRouter<\n Lazy<U>,\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap\n > {\n return enhanceEffectRouter(lazy(loader), {\n ...this[\"~effect\"],\n }) as any; // Type instantiation is excessively deep and possibly infinite\n }\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 TBuilder extends AnyBuilderLike<\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta\n >,\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: TBuilder,\n): EffectBuilder<\n InferBuilderInitialContext<TBuilder>,\n InferBuilderCurrentContext<TBuilder>,\n InferBuilderInputSchema<TBuilder>,\n InferBuilderOutputSchema<TBuilder>,\n InferBuilderErrorMap<TBuilder>,\n InferBuilderMeta<TBuilder>,\n TRequirementsProvided,\n TRuntimeError\n>;\n\nexport function makeEffectORPC<TRequirementsProvided, TRuntimeError>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder?: AnyBuilderLike,\n): EffectBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n TRequirementsProvided,\n TRuntimeError\n> {\n const resolvedBuilder = builder ?? emptyBuilder();\n return new EffectBuilder({\n ...resolvedBuilder[\"~orpc\"],\n errorMap: effectErrorMapToErrorMap(resolvedBuilder[\"~orpc\"].errorMap),\n effectErrorMap: resolvedBuilder[\"~orpc\"].errorMap,\n runtime,\n });\n}\n\nfunction emptyBuilder(): AnyBuilderLike {\n return new Builder({\n config: {},\n route: {},\n meta: {},\n errorMap: {},\n inputValidationIndex: fallbackConfig(\"initialInputValidationIndex\"),\n outputValidationIndex: fallbackConfig(\"initialOutputValidationIndex\"),\n middlewares: [],\n dedupeLeadingMiddlewares: true,\n });\n}\n","import type { ManagedRuntime } from \"effect/ManagedRuntime\";\n\nimport {\n enhanceRoute,\n mergePrefix,\n type EnhanceRouteOptions,\n} from \"@orpc/contract\";\nimport {\n createAccessibleLazyRouter,\n getLazyMeta,\n isLazy,\n isProcedure,\n lazy,\n mergeMiddlewares,\n unlazy,\n type AnyMiddleware,\n type AnyRouter,\n type Context,\n type Lazyable,\n} from \"@orpc/server\";\n\nimport type { EffectErrorMapToErrorMap, EnhancedEffectRouter } from \"./types\";\n\nimport { EffectProcedure } from \"./effect-procedure\";\nimport { effectErrorMapToErrorMap, type EffectErrorMap } from \"./tagged-error\";\n\ninterface EnhanceEffectRouterOptions<\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TRuntimeError,\n> extends EnhanceRouteOptions {\n middlewares: readonly AnyMiddleware[];\n errorMap: TEffectErrorMap;\n dedupeLeadingMiddlewares: boolean;\n runtime: ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n}\n\nexport function enhanceEffectRouter<\n T extends Lazyable<AnyRouter>,\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TRuntimeError,\n>(\n router: T,\n options: EnhanceEffectRouterOptions<\n TEffectErrorMap,\n TRequirementsProvided,\n TRuntimeError\n >,\n): EnhancedEffectRouter<T, TInitialContext, TCurrentContext, TEffectErrorMap> {\n if (isLazy(router)) {\n const laziedMeta = getLazyMeta(router);\n const enhancedPrefix = laziedMeta?.prefix\n ? mergePrefix(options.prefix, laziedMeta?.prefix)\n : options.prefix;\n\n const enhanced = lazy(\n async () => {\n const { default: unlaziedRouter } = await unlazy(router);\n const enhanced = enhanceEffectRouter(unlaziedRouter, options);\n return unlazy(enhanced);\n },\n {\n ...laziedMeta,\n prefix: enhancedPrefix,\n },\n );\n\n const accessible = createAccessibleLazyRouter(enhanced);\n\n return accessible as any;\n }\n\n if (isProcedure(router)) {\n const newMiddlewares = mergeMiddlewares(\n options.middlewares,\n router[\"~orpc\"].middlewares,\n { dedupeLeading: options.dedupeLeadingMiddlewares },\n );\n const newMiddlewareAdded =\n newMiddlewares.length - router[\"~orpc\"].middlewares.length;\n\n const effectErrorMap = {\n ...options.errorMap,\n ...router[\"~orpc\"].errorMap,\n };\n const errorMap: EffectErrorMapToErrorMap<typeof effectErrorMap> =\n effectErrorMapToErrorMap(effectErrorMap);\n const enhanced = new EffectProcedure({\n ...router[\"~orpc\"],\n route: enhanceRoute(router[\"~orpc\"].route, options),\n effectErrorMap,\n errorMap: errorMap as EffectErrorMapToErrorMap<typeof effectErrorMap>,\n middlewares: newMiddlewares,\n inputValidationIndex:\n router[\"~orpc\"].inputValidationIndex + newMiddlewareAdded,\n outputValidationIndex:\n router[\"~orpc\"].outputValidationIndex + newMiddlewareAdded,\n runtime: options.runtime,\n });\n\n return enhanced as any;\n }\n\n const enhanced = {} as Record<string, any>;\n\n for (const key in router) {\n enhanced[key] = enhanceEffectRouter(router[key]!, options);\n }\n\n return enhanced as any;\n}\n","import type { ClientContext } from \"@orpc/client\";\nimport type {\n AnySchema,\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 ProcedureActionableClient,\n ProcedureClient,\n ProcedureDef,\n} from \"@orpc/server\";\nimport type { IntersectPick, MaybeOptionalOptions } from \"@orpc/shared\";\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 {\n EffectErrorConstructorMap,\n EffectErrorMap,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\nimport type { EffectErrorMapToErrorMap, EffectProcedureDef } from \"./types\";\n\nimport { effectErrorMapToErrorMap } from \"./tagged-error\";\n\nexport class EffectProcedure<\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 EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\n> {\n /**\n * This property holds the defined options and the effect-specific properties.\n */\n declare \"~effect\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n /**\n * This property holds the defined options.\n */\n declare \"~orpc\": ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\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 this[\"~effect\"] = def;\n }\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 EffectProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n> {\n /**\n * This property holds the defined options and the effect-specific properties.\n */\n declare \"~effect\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n declare \"~orpc\": ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\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 this[\"~effect\"] = 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: MergedEffectErrorMap<TEffectErrorMap, U> = {\n ...this[\"~effect\"].effectErrorMap,\n ...errors,\n };\n return new EffectDecoratedProcedure({\n ...this[\"~effect\"],\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[\"~effect\"],\n meta: mergeMeta(this[\"~effect\"].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[\"~effect\"],\n route: mergeRoute(this[\"~effect\"].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 EffectErrorConstructorMap<TEffectErrorMap>,\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 EffectErrorConstructorMap<TEffectErrorMap>,\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[\"~effect\"],\n middlewares: addMiddleware(this[\"~effect\"].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 EffectErrorMapToErrorMap<TEffectErrorMap>,\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<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\n > {\n const client: ProcedureClient<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\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 EffectErrorMapToErrorMap<TEffectErrorMap>,\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<\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\n > {\n const action: ProcedureActionableClient<\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\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 {\n AnySchema,\n ErrorMap,\n ErrorMapItem,\n InferSchemaOutput,\n} from \"@orpc/contract\";\nimport type { ORPCErrorConstructorMap } from \"@orpc/server\";\nimport type { MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { Pipeable } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\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\nimport type { EffectErrorMapToErrorMap } from \"./types\";\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 TSchema extends AnySchema = AnySchema,\n>\n extends Cause.YieldableError, Pipeable.Pipeable {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly schema: TSchema;\n readonly data: InferSchemaOutput<TSchema>;\n readonly defined: boolean;\n readonly [ORPCErrorSymbol]: ORPCError<TCode, InferSchemaOutput<TSchema>>;\n\n toJSON(): ORPCErrorJSON<TCode, InferSchemaOutput<TSchema>> & { _tag: TTag };\n toORPCError(): ORPCError<TCode, InferSchemaOutput<TSchema>>;\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 TSchema extends AnySchema = AnySchema,\n> {\n readonly _tag: TTag;\n readonly code: TCode;\n new (\n ...args: MaybeOptionalOptions<\n ORPCTaggedErrorOptions<InferSchemaOutput<TSchema>>\n >\n ): ORPCTaggedErrorInstance<TTag, TCode, TSchema>;\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 TSchema>\n ? ORPCError<TCode, InferSchemaOutput<TSchema>>\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 (\n ...args: any[]\n ): ORPCTaggedErrorInstance<string, ORPCErrorCode, AnySchema>;\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, AnySchema> {\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 * Checks if a character is an uppercase letter (A-Z)\n */\ntype IsUpperLetter<C extends string> =\n C extends Uppercase<C>\n ? C extends Lowercase<C>\n ? false // Not a letter (number, special char)\n : true\n : false;\n\n/**\n * Checks if a character is a lowercase letter (a-z)\n */\ntype IsLowerLetter<C extends string> =\n C extends Lowercase<C>\n ? C extends Uppercase<C>\n ? false // Not a letter (number, special char)\n : true\n : false;\n\n/**\n * Converts PascalCase or camelCase to CONSTANT_CASE.\n * Handles consecutive uppercase letters correctly.\n *\n * @example\n * type T1 = ToConstantCase<\"ABCCode\">; // \"ABC_CODE\"\n * type T2 = ToConstantCase<\"UserCode\">; // \"USER_CODE\"\n * type T3 = ToConstantCase<\"XMLHttpRequest\">; // \"XML_HTTP_REQUEST\"\n */\ntype ToConstantCase<\n S extends string,\n Acc extends string = \"\",\n PrevChar extends string = \"\",\n InUpperSequence extends boolean = false,\n> = S extends `${infer Head}${infer Tail}`\n ? IsUpperLetter<Head> extends true\n ? Acc extends \"\"\n ? // First character - no underscore\n ToConstantCase<Tail, Head, Head, false>\n : PrevChar extends \"\"\n ? // Shouldn't happen, but handle gracefully\n ToConstantCase<Tail, Head, Head, false>\n : IsUpperLetter<PrevChar> extends true\n ? // We're in an uppercase sequence\n Tail extends `${infer Next}${infer _}`\n ? IsLowerLetter<Next> extends true\n ? // Next char is lowercase, so Head starts a new word - insert underscore\n ToConstantCase<Tail, `${Acc}_${Head}`, Head, false>\n : // Next char is uppercase or non-letter - continue sequence\n ToConstantCase<Tail, `${Acc}${Head}`, Head, true>\n : // Tail is empty - just append\n ToConstantCase<Tail, `${Acc}${Head}`, Head, true>\n : // Transition from lowercase to uppercase - insert underscore\n ToConstantCase<Tail, `${Acc}_${Head}`, Head, false>\n : IsLowerLetter<Head> extends true\n ? InUpperSequence extends true\n ? // End of uppercase sequence (2+) - insert underscore before lowercase\n ToConstantCase<Tail, `${Acc}_${Uppercase<Head>}`, Head, false>\n : // Single uppercase or no uppercase - no underscore\n ToConstantCase<Tail, `${Acc}${Uppercase<Head>}`, Head, false>\n : // Non-letter character - reset sequence\n ToConstantCase<Tail, `${Acc}${Head}`, Head, false>\n : Acc;\n\n/**\n * Converts a tag name to an error code in CONSTANT_CASE.\n */\nexport type TagToCode<TTag extends string> = ToConstantCase<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<TSchema extends AnySchema = AnySchema> {\n // Overload 1: tag only (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n ): ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TSchema>;\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 ): ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TSchema>;\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 ): ORPCTaggedErrorClass<TTag, TCode, TSchema>;\n}\n\nexport function ORPCTaggedError<TSchema extends AnySchema = AnySchema>(\n schema?: TSchema,\n) {\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, TSchema> => {\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, 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: InferSchemaOutput<TSchema>;\n defined: boolean;\n }) => Cause.YieldableError & {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: InferSchemaOutput<TSchema>;\n readonly defined: boolean;\n };\n\n class ORPCTaggedErrorBase extends BaseTaggedError {\n static readonly schema = schema;\n static readonly _tag = tag;\n static readonly code = code;\n\n readonly [ORPCErrorSymbol]: ORPCError<TCode, InferSchemaOutput<TSchema>>;\n\n constructor(\n ...rest: MaybeOptionalOptions<\n ORPCTaggedErrorOptions<InferSchemaOutput<TSchema>>\n >\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 const data = opts.data as InferSchemaOutput<TSchema>;\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,\n defined: opts.defined ?? true,\n });\n\n // Create the underlying ORPCError for interop\n this[ORPCErrorSymbol] = new ORPCError<\n TCode,\n InferSchemaOutput<TSchema>\n >(code, {\n status: finalStatus,\n message: finalMessage,\n data,\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, TSchema> {\n return this[ORPCErrorSymbol];\n }\n\n override toJSON(): ORPCErrorJSON<TCode, TSchema> & { _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<TSchema>;\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<\n TCode extends ORPCErrorCode,\n TSchema extends AnySchema = AnySchema,\n>(\n error: ORPCTaggedErrorInstance<string, TCode, TSchema>,\n): ORPCError<TCode, InferSchemaOutput<TSchema>> {\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\nexport type ORPCTaggedErrorClassToErrorMapItem<T> =\n T extends ORPCTaggedErrorClass<any, any, infer TData>\n ? {\n status?: number;\n message?: string;\n data?: TData;\n }\n : never;\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> = Omit<T1, keyof T2> & 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 * Constructor map for EffectErrorMap - provides typed error constructors for handlers.\n */\nexport type EffectErrorConstructorMap<T extends EffectErrorMap> =\n ORPCErrorConstructorMap<EffectErrorMapToErrorMap<T>>;\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): EffectErrorMapToErrorMap<T> {\n const result: ErrorMap = {};\n\n if (!errorMap) {\n return result as ErrorMap & EffectErrorMapToErrorMap<T>;\n }\n\n for (const [code, ClassOrErrorItem] of Object.entries(errorMap)) {\n if (!ClassOrErrorItem) {\n continue;\n }\n\n if (isORPCTaggedErrorClass(ClassOrErrorItem)) {\n const classInstance = new ClassOrErrorItem();\n // For tagged errors, we create a minimal entry\n // The actual validation will be handled by the tagged error class\n result[classInstance.code] = {\n status: classInstance.status,\n message: classInstance.message,\n data: classInstance.schema,\n };\n } else {\n result[code] = ClassOrErrorItem;\n }\n }\n\n return result as ErrorMap & EffectErrorMapToErrorMap<T>;\n}\n\nexport function mergeAnyErrorMaps<\n T1 extends EffectErrorMap,\n T2 extends EffectErrorMap,\n>(map1: T1, map2: T2): EffectErrorMapToErrorMap<T1 & T2> {\n return {\n ...map1,\n ...map2,\n } as EffectErrorMapToErrorMap<T1 & T2>;\n}\n"],"mappings":"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","names":["mergeMeta","mergePrefix","mergeRoute","ORPCError","addMiddleware","decorateMiddleware","lazy","enhanced","decorateMiddleware","addMiddleware","mergeMeta","mergeRoute","ORPCError","mergePrefix","lazy"]}
1
+ {"version":3,"sources":["../src/effect-builder.ts","../src/effect-enhance-router.ts","../src/effect-procedure.ts","../src/tagged-error.ts"],"sourcesContent":["import type {\n AnySchema,\n ContractRouter,\n ErrorMap,\n HTTPPath,\n InferSchemaOutput,\n Meta,\n Route,\n Schema,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n BuilderConfig,\n BuilderDef,\n Context,\n Lazy,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ProcedureHandler,\n ProcedureHandlerOptions,\n Router,\n} from \"@orpc/server\";\nimport type { IntersectPick } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport {\n mergeMeta,\n mergePrefix,\n mergeRoute,\n mergeTags,\n ORPCError,\n} from \"@orpc/contract\";\nimport {\n addMiddleware,\n Builder,\n decorateMiddleware,\n fallbackConfig,\n lazy,\n} from \"@orpc/server\";\nimport { Cause, Effect, Exit } from \"effect\";\n\nimport type {\n EffectErrorConstructorMap,\n EffectErrorMap,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\nimport type {\n AnyBuilderLike,\n EffectBuilderDef,\n EffectErrorMapToErrorMap,\n EffectProcedureBuilderWithInput,\n EffectProcedureHandler,\n EffectRouterBuilder,\n EnhancedEffectRouter,\n InferBuilderCurrentContext,\n InferBuilderErrorMap,\n InferBuilderInitialContext,\n InferBuilderInputSchema,\n InferBuilderMeta,\n InferBuilderOutputSchema,\n} from \"./types\";\n\nimport { enhanceEffectRouter } from \"./effect-enhance-router\";\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 * 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 /**\n * This property holds the defined options and the effect-specific properties.\n */\n declare \"~effect\": EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n declare \"~orpc\": BuilderDef<\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\n >;\n\n constructor(\n def: EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n const { runtime, spanConfig, effectErrorMap, ...orpcDef } = def;\n this[\"~orpc\"] = orpcDef;\n this[\"~effect\"] = { runtime, spanConfig, effectErrorMap, ...orpcDef };\n }\n\n /**\n * Sets or overrides the config.\n *\n * @see {@link https://orpc.dev/docs/client/server-side#middlewares-order Middlewares Order Docs}\n * @see {@link https://orpc.dev/docs/best-practices/dedupe-middleware#configuration Dedupe Middleware Docs}\n */\n $config(\n config: BuilderConfig,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const inputValidationCount =\n this[\"~effect\"].inputValidationIndex -\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~effect\"].config.initialInputValidationIndex,\n );\n const outputValidationCount =\n this[\"~effect\"].outputValidationIndex -\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~effect\"].config.initialOutputValidationIndex,\n );\n\n return new EffectBuilder({\n ...this[\"~effect\"],\n config,\n dedupeLeadingMiddlewares: fallbackConfig(\n \"dedupeLeadingMiddlewares\",\n config.dedupeLeadingMiddlewares,\n ),\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n config.initialInputValidationIndex,\n ) + inputValidationCount,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n config.initialOutputValidationIndex,\n ) + outputValidationCount,\n });\n }\n\n /**\n * Set or override the initial context.\n *\n * @see {@link https://orpc.dev/docs/context Context Docs}\n */\n $context<U extends Context>(): EffectBuilder<\n U & Record<never, never>,\n U,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n /**\n * We need `& Record<never, never>` to deal with `has no properties in common with type` error\n */\n\n return new EffectBuilder({\n ...this[\"~effect\"],\n middlewares: [],\n inputValidationIndex: fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~effect\"].config.initialInputValidationIndex,\n ),\n outputValidationIndex: fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~effect\"].config.initialOutputValidationIndex,\n ),\n });\n }\n\n /**\n * Sets or overrides the initial meta.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n $meta<U extends Meta>(\n initialMeta: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n U & Record<never, never>,\n TRequirementsProvided,\n TRuntimeError\n > {\n /**\n * We need `& Record<never, never>` to deal with `has no properties in common with type` error\n */\n\n return new EffectBuilder({\n ...this[\"~effect\"],\n meta: initialMeta,\n });\n }\n\n /**\n * Sets or overrides the initial 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 initialRoute: 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[\"~effect\"],\n route: initialRoute,\n });\n }\n\n /**\n * Sets or overrides the initial input schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#initial-configuration Initial Procedure Configuration Docs}\n */\n $input<U extends AnySchema>(\n initialInputSchema?: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n U,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n inputSchema: initialInputSchema,\n });\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 const newEffectErrorMap: MergedEffectErrorMap<TEffectErrorMap, U> = {\n ...this[\"~effect\"].effectErrorMap,\n ...errors,\n };\n return new EffectBuilder({\n ...this[\"~effect\"],\n errorMap: effectErrorMapToErrorMap(newEffectErrorMap),\n effectErrorMap: newEffectErrorMap,\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 InferSchemaOutput<TInputSchema>,\n unknown,\n EffectErrorConstructorMap<TEffectErrorMap>,\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[\"~effect\"],\n middlewares: addMiddleware(this[\"~effect\"].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[\"~effect\"],\n meta: mergeMeta(this[\"~effect\"].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[\"~effect\"],\n route: mergeRoute(this[\"~effect\"].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 ): EffectProcedureBuilderWithInput<\n TInitialContext,\n TCurrentContext,\n USchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n inputSchema: schema,\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~effect\"].config.initialInputValidationIndex,\n ) + this[\"~effect\"].middlewares.length,\n // we cast to any because EffectProcedureBuilderWithInput is expecting\n // use() input type to be defined, and EffectBuilder types its use() input\n // to unknown to allow any middleware to be passed\n // ---\n // note: the original implentation of the builder also uses any for the same reason\n }) as any;\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[\"~effect\"],\n outputSchema: schema,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~effect\"].config.initialOutputValidationIndex,\n ) + this[\"~effect\"].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[\"~effect\"],\n spanConfig: {\n name: spanName,\n captureStackTrace: addSpanStackTrace(),\n },\n });\n }\n\n handler<UFuncOutput>(\n handler: ProcedureHandler<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n UFuncOutput,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\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 return new EffectDecoratedProcedure({\n ...this[\"~effect\"],\n handler,\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 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[\"~effect\"];\n // Capture stack trace at definition time for default tracing\n const defaultCaptureStackTrace = addSpanStackTrace();\n return new EffectDecoratedProcedure({\n ...this[\"~effect\"],\n handler: async (opts) => {\n const effectOpts: ProcedureHandlerOptions<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n EffectErrorConstructorMap<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(\n this[\"~effect\"].effectErrorMap,\n ),\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 * Prefixes all procedures in the router.\n * The provided prefix is post-appended to any existing router prefix.\n *\n * @note This option does not affect procedures that do not define a path in their route definition.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing#route-prefixes OpenAPI Route Prefixes Docs}\n */\n prefix(\n prefix: HTTPPath,\n ): EffectRouterBuilder<\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n prefix: mergePrefix(this[\"~effect\"].prefix, prefix),\n }) as any;\n }\n\n /**\n * Adds tags to all procedures in the router.\n * This helpful when you want to group procedures together in the OpenAPI specification.\n *\n * @see {@link https://orpc.dev/docs/openapi/openapi-specification#operation-metadata OpenAPI Operation Metadata Docs}\n */\n tag(\n ...tags: string[]\n ): EffectRouterBuilder<\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~effect\"],\n tags: mergeTags(this[\"~effect\"].tags, tags),\n }) as any;\n }\n\n /**\n * Applies all of the previously defined options to the specified router.\n *\n * @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}\n */\n router<U extends Router<ContractRouter<TMeta>, TCurrentContext>>(\n router: U,\n ): EnhancedEffectRouter<\n U,\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap\n > {\n return enhanceEffectRouter(router, {\n ...this[\"~effect\"],\n }) as any; // Type instantiation is excessively deep and possibly infinite\n }\n\n /**\n * Create a lazy router\n * And applies all of the previously defined options to the specified router.\n *\n * @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}\n */\n lazy<U extends Router<ContractRouter<TMeta>, TCurrentContext>>(\n loader: () => Promise<{ default: U }>,\n ): EnhancedEffectRouter<\n Lazy<U>,\n TInitialContext,\n TCurrentContext,\n TEffectErrorMap\n > {\n return enhanceEffectRouter(lazy(loader), {\n ...this[\"~effect\"],\n }) as any; // Type instantiation is excessively deep and possibly infinite\n }\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 TBuilder extends AnyBuilderLike<\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta\n >,\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: TBuilder,\n): EffectBuilder<\n InferBuilderInitialContext<TBuilder>,\n InferBuilderCurrentContext<TBuilder>,\n InferBuilderInputSchema<TBuilder>,\n InferBuilderOutputSchema<TBuilder>,\n InferBuilderErrorMap<TBuilder>,\n InferBuilderMeta<TBuilder>,\n TRequirementsProvided,\n TRuntimeError\n>;\n\nexport function makeEffectORPC<TRequirementsProvided, TRuntimeError>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder?: AnyBuilderLike,\n): EffectBuilder<\n any,\n any,\n any,\n any,\n any,\n any,\n TRequirementsProvided,\n TRuntimeError\n> {\n const resolvedBuilder = builder ?? emptyBuilder();\n return new EffectBuilder({\n ...resolvedBuilder[\"~orpc\"],\n errorMap: effectErrorMapToErrorMap(resolvedBuilder[\"~orpc\"].errorMap),\n effectErrorMap: resolvedBuilder[\"~orpc\"].errorMap,\n runtime,\n });\n}\n\nfunction emptyBuilder(): AnyBuilderLike {\n return new Builder({\n config: {},\n route: {},\n meta: {},\n errorMap: {},\n inputValidationIndex: fallbackConfig(\"initialInputValidationIndex\"),\n outputValidationIndex: fallbackConfig(\"initialOutputValidationIndex\"),\n middlewares: [],\n dedupeLeadingMiddlewares: true,\n });\n}\n","import type { ManagedRuntime } from \"effect/ManagedRuntime\";\n\nimport {\n enhanceRoute,\n mergePrefix,\n type EnhanceRouteOptions,\n} from \"@orpc/contract\";\nimport {\n createAccessibleLazyRouter,\n getLazyMeta,\n isLazy,\n isProcedure,\n lazy,\n mergeMiddlewares,\n unlazy,\n type AnyMiddleware,\n type AnyRouter,\n type Context,\n type Lazyable,\n} from \"@orpc/server\";\n\nimport type { EffectErrorMapToErrorMap, EnhancedEffectRouter } from \"./types\";\n\nimport { EffectProcedure } from \"./effect-procedure\";\nimport { effectErrorMapToErrorMap, type EffectErrorMap } from \"./tagged-error\";\n\ninterface EnhanceEffectRouterOptions<\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TRuntimeError,\n> extends EnhanceRouteOptions {\n middlewares: readonly AnyMiddleware[];\n errorMap: TEffectErrorMap;\n dedupeLeadingMiddlewares: boolean;\n runtime: ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n}\n\nexport function enhanceEffectRouter<\n T extends Lazyable<AnyRouter>,\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TRuntimeError,\n>(\n router: T,\n options: EnhanceEffectRouterOptions<\n TEffectErrorMap,\n TRequirementsProvided,\n TRuntimeError\n >,\n): EnhancedEffectRouter<T, TInitialContext, TCurrentContext, TEffectErrorMap> {\n if (isLazy(router)) {\n const laziedMeta = getLazyMeta(router);\n const enhancedPrefix = laziedMeta?.prefix\n ? mergePrefix(options.prefix, laziedMeta?.prefix)\n : options.prefix;\n\n const enhanced = lazy(\n async () => {\n const { default: unlaziedRouter } = await unlazy(router);\n const enhanced = enhanceEffectRouter(unlaziedRouter, options);\n return unlazy(enhanced);\n },\n {\n ...laziedMeta,\n prefix: enhancedPrefix,\n },\n );\n\n const accessible = createAccessibleLazyRouter(enhanced);\n\n return accessible as any;\n }\n\n if (isProcedure(router)) {\n const newMiddlewares = mergeMiddlewares(\n options.middlewares,\n router[\"~orpc\"].middlewares,\n { dedupeLeading: options.dedupeLeadingMiddlewares },\n );\n const newMiddlewareAdded =\n newMiddlewares.length - router[\"~orpc\"].middlewares.length;\n\n const effectErrorMap = {\n ...options.errorMap,\n ...router[\"~orpc\"].errorMap,\n };\n const errorMap: EffectErrorMapToErrorMap<typeof effectErrorMap> =\n effectErrorMapToErrorMap(effectErrorMap);\n const enhanced = new EffectProcedure({\n ...router[\"~orpc\"],\n route: enhanceRoute(router[\"~orpc\"].route, options),\n effectErrorMap,\n errorMap: errorMap as EffectErrorMapToErrorMap<typeof effectErrorMap>,\n middlewares: newMiddlewares,\n inputValidationIndex:\n router[\"~orpc\"].inputValidationIndex + newMiddlewareAdded,\n outputValidationIndex:\n router[\"~orpc\"].outputValidationIndex + newMiddlewareAdded,\n runtime: options.runtime,\n });\n\n return enhanced as any;\n }\n\n const enhanced = {} as Record<string, any>;\n\n for (const key in router) {\n enhanced[key] = enhanceEffectRouter(router[key]!, options);\n }\n\n return enhanced as any;\n}\n","import type { ClientContext } from \"@orpc/client\";\nimport type {\n AnySchema,\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 ProcedureActionableClient,\n ProcedureClient,\n ProcedureDef,\n} from \"@orpc/server\";\nimport type { IntersectPick, MaybeOptionalOptions } from \"@orpc/shared\";\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 {\n EffectErrorConstructorMap,\n EffectErrorMap,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\nimport type { EffectErrorMapToErrorMap, EffectProcedureDef } from \"./types\";\n\nimport { effectErrorMapToErrorMap } from \"./tagged-error\";\n\nexport class EffectProcedure<\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 EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\n> {\n /**\n * This property holds the defined options and the effect-specific properties.\n */\n declare \"~effect\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n /**\n * This property holds the defined options.\n */\n declare \"~orpc\": ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\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 this[\"~effect\"] = def;\n }\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 EffectProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n> {\n /**\n * This property holds the defined options and the effect-specific properties.\n */\n declare \"~effect\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n declare \"~orpc\": ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>,\n TMeta\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 this[\"~effect\"] = 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: MergedEffectErrorMap<TEffectErrorMap, U> = {\n ...this[\"~effect\"].effectErrorMap,\n ...errors,\n };\n return new EffectDecoratedProcedure({\n ...this[\"~effect\"],\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[\"~effect\"],\n meta: mergeMeta(this[\"~effect\"].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[\"~effect\"],\n route: mergeRoute(this[\"~effect\"].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 EffectErrorConstructorMap<TEffectErrorMap>,\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 EffectErrorConstructorMap<TEffectErrorMap>,\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[\"~effect\"],\n middlewares: addMiddleware(this[\"~effect\"].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 EffectErrorMapToErrorMap<TEffectErrorMap>,\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<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\n > {\n const client: ProcedureClient<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\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 EffectErrorMapToErrorMap<TEffectErrorMap>,\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<\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\n > {\n const action: ProcedureActionableClient<\n TInputSchema,\n TOutputSchema,\n EffectErrorMapToErrorMap<TEffectErrorMap>\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 {\n AnySchema,\n ErrorMap,\n ErrorMapItem,\n InferSchemaOutput,\n} from \"@orpc/contract\";\nimport type { ORPCErrorConstructorMap } from \"@orpc/server\";\nimport type { MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { Pipeable } from \"effect\";\n\nimport {\n fallbackORPCErrorMessage,\n fallbackORPCErrorStatus,\n isORPCErrorStatus,\n ORPCError,\n} from \"@orpc/client\";\nimport { resolveMaybeOptionalOptions } from \"@orpc/shared\";\nimport * as Cause from \"effect/Cause\";\nimport * as Data from \"effect/Data\";\n\nimport type { EffectErrorMapToErrorMap } from \"./types\";\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 TSchema extends AnySchema = AnySchema,\n>\n extends Cause.YieldableError, Pipeable.Pipeable {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly schema: TSchema;\n readonly data: InferSchemaOutput<TSchema>;\n readonly defined: boolean;\n readonly [ORPCErrorSymbol]: ORPCError<TCode, InferSchemaOutput<TSchema>>;\n\n toJSON(): ORPCErrorJSON<TCode, InferSchemaOutput<TSchema>> & { _tag: TTag };\n toORPCError(): ORPCError<TCode, InferSchemaOutput<TSchema>>;\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 TSchema extends AnySchema = AnySchema,\n> {\n readonly _tag: TTag;\n readonly code: TCode;\n new (\n ...args: MaybeOptionalOptions<\n ORPCTaggedErrorOptions<InferSchemaOutput<TSchema>>\n >\n ): ORPCTaggedErrorInstance<TTag, TCode, TSchema>;\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 TSchema>\n ? ORPCError<TCode, InferSchemaOutput<TSchema>>\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 (\n ...args: any[]\n ): ORPCTaggedErrorInstance<string, ORPCErrorCode, AnySchema>;\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, AnySchema> {\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<T extends string>(str: T): ToConstantCase<T> {\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() as ToConstantCase<T>;\n}\n/**\n * Checks if a character is an uppercase letter (A-Z)\n */\ntype IsUpperLetter<C extends string> =\n C extends Uppercase<C>\n ? C extends Lowercase<C>\n ? false // Not a letter (number, special char)\n : true\n : false;\n\n/**\n * Checks if a character is a lowercase letter (a-z)\n */\ntype IsLowerLetter<C extends string> =\n C extends Lowercase<C>\n ? C extends Uppercase<C>\n ? false // Not a letter (number, special char)\n : true\n : false;\n\n/**\n * Converts PascalCase or camelCase to CONSTANT_CASE.\n * Handles consecutive uppercase letters correctly.\n *\n * @example\n * type T1 = ToConstantCase<\"ABCCode\">; // \"ABC_CODE\"\n * type T2 = ToConstantCase<\"UserCode\">; // \"USER_CODE\"\n * type T3 = ToConstantCase<\"XMLHttpRequest\">; // \"XML_HTTP_REQUEST\"\n */\ntype ToConstantCase<\n S extends string,\n Acc extends string = \"\",\n PrevChar extends string = \"\",\n InUpperSequence extends boolean = false,\n> = S extends `${infer Head}${infer Tail}`\n ? IsUpperLetter<Head> extends true\n ? Acc extends \"\"\n ? // First character - no underscore\n ToConstantCase<Tail, Head, Head, false>\n : PrevChar extends \"\"\n ? // Shouldn't happen, but handle gracefully\n ToConstantCase<Tail, Head, Head, false>\n : IsUpperLetter<PrevChar> extends true\n ? // We're in an uppercase sequence\n Tail extends `${infer Next}${infer _}`\n ? IsLowerLetter<Next> extends true\n ? // Next char is lowercase, so Head starts a new word - insert underscore\n ToConstantCase<Tail, `${Acc}_${Head}`, Head, false>\n : // Next char is uppercase or non-letter - continue sequence\n ToConstantCase<Tail, `${Acc}${Head}`, Head, true>\n : // Tail is empty - just append\n ToConstantCase<Tail, `${Acc}${Head}`, Head, true>\n : // Transition from lowercase to uppercase - insert underscore\n ToConstantCase<Tail, `${Acc}_${Head}`, Head, false>\n : IsLowerLetter<Head> extends true\n ? InUpperSequence extends true\n ? // End of uppercase sequence (2+) - insert underscore before lowercase\n ToConstantCase<Tail, `${Acc}_${Uppercase<Head>}`, Head, false>\n : // Single uppercase or no uppercase - no underscore\n ToConstantCase<Tail, `${Acc}${Uppercase<Head>}`, Head, false>\n : // Non-letter character - reset sequence\n ToConstantCase<Tail, `${Acc}${Head}`, Head, false>\n : Acc;\n\n/**\n * Converts a tag name to an error code in CONSTANT_CASE.\n */\nexport type TagToCode<TTag extends string> = ToConstantCase<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 */\nexport function ORPCTaggedError<\n TTag extends string,\n TSchema extends AnySchema = AnySchema,\n TCode extends ORPCErrorCode = ToConstantCase<TTag>,\n>(\n tag: TTag,\n props?: {\n schema?: TSchema;\n status?: number;\n message?: string;\n code?: TCode;\n },\n): ORPCTaggedErrorClass<TTag, TCode, TSchema> {\n const code: TCode = props?.code ?? (toConstantCase(tag) as any);\n class ORPCTaggedErrorBase\n extends Data.TaggedError(tag)\n implements ORPCTaggedErrorInstance<TTag, TCode, TSchema>\n {\n readonly status: number;\n readonly defined: boolean;\n readonly data: InferSchemaOutput<TSchema>;\n readonly code: TCode = code;\n readonly schema = props?.schema as TSchema;\n readonly [ORPCErrorSymbol]: ORPCError<TCode, InferSchemaOutput<TSchema>>;\n\n constructor(\n ...rest: MaybeOptionalOptions<\n ORPCTaggedErrorOptions<InferSchemaOutput<TSchema>>\n >\n ) {\n super();\n\n const opts = resolveMaybeOptionalOptions(rest);\n const status = opts.status ?? props?.status;\n\n if (status !== undefined && !isORPCErrorStatus(status)) {\n throw new globalThis.Error(\n \"[ORPCTaggedError] Invalid error status code.\",\n );\n }\n\n this.status = fallbackORPCErrorStatus(code, status);\n this.defined = opts.defined ?? true;\n this.data = opts.data as InferSchemaOutput<TSchema>;\n this.message = fallbackORPCErrorMessage(\n this.code,\n opts.message ?? props?.message,\n );\n this.cause = opts.cause;\n\n this[ORPCErrorSymbol] = new ORPCError<TCode, InferSchemaOutput<TSchema>>(\n this.code,\n {\n status: this.status,\n message: this.message,\n data: this.data,\n defined: this.defined,\n cause: this.cause,\n },\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, InferSchemaOutput<TSchema>> {\n return this[ORPCErrorSymbol];\n }\n\n override toJSON(): ORPCErrorJSON<TCode, InferSchemaOutput<TSchema>> & {\n _tag: TTag;\n } {\n return {\n _tag: this._tag,\n defined: this[ORPCErrorSymbol].defined,\n code: this[ORPCErrorSymbol].code,\n status: this[ORPCErrorSymbol].status,\n message: this[ORPCErrorSymbol].message,\n data: this[ORPCErrorSymbol].data,\n };\n }\n }\n\n return Object.assign(ORPCTaggedErrorBase, {\n _tag: tag,\n code,\n } as const);\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<\n TCode extends ORPCErrorCode,\n TSchema extends AnySchema = AnySchema,\n>(\n error: ORPCTaggedErrorInstance<string, TCode, TSchema>,\n): ORPCError<TCode, InferSchemaOutput<TSchema>> {\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\nexport type ORPCTaggedErrorClassToErrorMapItem<T> =\n T extends ORPCTaggedErrorClass<any, any, infer TData>\n ? {\n status?: number;\n message?: string;\n data?: TData;\n }\n : never;\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> = Omit<T1, keyof T2> & 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 * Constructor map for EffectErrorMap - provides typed error constructors for handlers.\n */\nexport type EffectErrorConstructorMap<T extends EffectErrorMap> =\n ORPCErrorConstructorMap<EffectErrorMapToErrorMap<T>>;\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): EffectErrorMapToErrorMap<T> {\n const result: ErrorMap = {};\n\n if (!errorMap) {\n return result as ErrorMap & EffectErrorMapToErrorMap<T>;\n }\n\n for (const [code, ClassOrErrorItem] of Object.entries(errorMap)) {\n if (!ClassOrErrorItem) {\n continue;\n }\n\n if (isORPCTaggedErrorClass(ClassOrErrorItem)) {\n const classInstance = new ClassOrErrorItem();\n result[classInstance.code] = {\n status: classInstance.status,\n message: classInstance.message,\n data: classInstance.schema,\n };\n } else {\n result[code] = ClassOrErrorItem;\n }\n }\n\n return result as ErrorMap & EffectErrorMapToErrorMap<T>;\n}\n\nexport function mergeAnyErrorMaps<\n T1 extends EffectErrorMap,\n T2 extends EffectErrorMap,\n>(map1: T1, map2: T2): EffectErrorMapToErrorMap<T1 & T2> {\n return {\n ...map1,\n ...map2,\n } as EffectErrorMapToErrorMap<T1 & T2>;\n}\n"],"mappings":"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","names":["mergeMeta","mergePrefix","mergeRoute","ORPCError","addMiddleware","decorateMiddleware","lazy","Cause","enhanced","decorateMiddleware","addMiddleware","mergeMeta","mergeRoute","Cause","ORPCError","mergePrefix","lazy"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-orpc",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "keywords": [
5
5
  "effect",
6
6
  "orpc",
@@ -12,7 +12,6 @@ import type {
12
12
  import type { ORPCErrorConstructorMap } from "@orpc/server";
13
13
  import type { MaybeOptionalOptions } from "@orpc/shared";
14
14
  import type { Pipeable } from "effect";
15
- import type * as Cause from "effect/Cause";
16
15
 
17
16
  import {
18
17
  fallbackORPCErrorMessage,
@@ -21,6 +20,7 @@ import {
21
20
  ORPCError,
22
21
  } from "@orpc/client";
23
22
  import { resolveMaybeOptionalOptions } from "@orpc/shared";
23
+ import * as Cause from "effect/Cause";
24
24
  import * as Data from "effect/Data";
25
25
 
26
26
  import type { EffectErrorMapToErrorMap } from "./types";
@@ -129,11 +129,11 @@ export function isORPCTaggedError(
129
129
  * Converts a PascalCase or camelCase string to CONSTANT_CASE.
130
130
  * e.g., "UserNotFoundError" -> "USER_NOT_FOUND_ERROR"
131
131
  */
132
- function toConstantCase(str: string): string {
132
+ function toConstantCase<T extends string>(str: T): ToConstantCase<T> {
133
133
  return str
134
134
  .replace(/([a-z])([A-Z])/g, "$1_$2")
135
135
  .replace(/([A-Z])([A-Z][a-z])/g, "$1_$2")
136
- .toUpperCase();
136
+ .toUpperCase() as ToConstantCase<T>;
137
137
  }
138
138
  /**
139
139
  * Checks if a character is an uppercase letter (A-Z)
@@ -247,137 +247,94 @@ export type TagToCode<TTag extends string> = ToConstantCase<TTag>;
247
247
  * ) {}
248
248
  * ```
249
249
  */
250
- /**
251
- * Return type for the factory function with overloads
252
- */
253
- interface ORPCTaggedErrorFactory<TSchema extends AnySchema = AnySchema> {
254
- // Overload 1: tag only (code defaults to CONSTANT_CASE of tag)
255
- <TTag extends string>(
256
- tag: TTag,
257
- ): ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TSchema>;
258
-
259
- // Overload 2: tag + options (code defaults to CONSTANT_CASE of tag)
260
- <TTag extends string>(
261
- tag: TTag,
262
- options: { status?: number; message?: string },
263
- ): ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TSchema>;
264
-
265
- // Overload 3: tag + explicit code
266
- <TTag extends string, TCode extends ORPCErrorCode>(
267
- tag: TTag,
268
- code: TCode,
269
- defaultOptions?: { status?: number; message?: string },
270
- ): ORPCTaggedErrorClass<TTag, TCode, TSchema>;
271
- }
272
-
273
- export function ORPCTaggedError<TSchema extends AnySchema = AnySchema>(
274
- schema?: TSchema,
275
- ) {
276
- const factory = <TTag extends string, TCode extends ORPCErrorCode>(
277
- tag: TTag,
278
- codeOrOptions?: TCode | { status?: number; message?: string },
279
- defaultOptions?: { status?: number; message?: string },
280
- ): ORPCTaggedErrorClass<TTag, TCode, TSchema> => {
281
- // Determine if second arg is code or options
282
- const isCodeProvided = typeof codeOrOptions === "string";
283
- const code = (
284
- isCodeProvided ? codeOrOptions : toConstantCase(tag)
285
- ) as TCode;
286
- const options = isCodeProvided ? defaultOptions : codeOrOptions;
287
-
288
- const defaultStatus = options?.status;
289
- const defaultMessage = options?.message;
290
-
291
- // Use Effect's TaggedError as the base - this handles all Effect internals
292
- // (YieldableError, type symbols, Symbol.iterator, pipe(), etc.)
293
- const BaseTaggedError = Data.TaggedError(tag) as unknown as new (args: {
294
- message?: string;
295
- cause?: unknown;
296
- code: TCode;
297
- status: number;
298
- data: InferSchemaOutput<TSchema>;
299
- defined: boolean;
300
- }) => Cause.YieldableError & {
301
- readonly _tag: TTag;
302
- readonly code: TCode;
303
- readonly status: number;
304
- readonly data: InferSchemaOutput<TSchema>;
305
- readonly defined: boolean;
306
- };
307
-
308
- class ORPCTaggedErrorBase extends BaseTaggedError {
309
- static readonly schema = schema;
310
- static readonly _tag = tag;
311
- static readonly code = code;
312
-
313
- readonly [ORPCErrorSymbol]: ORPCError<TCode, InferSchemaOutput<TSchema>>;
314
-
315
- constructor(
316
- ...rest: MaybeOptionalOptions<
317
- ORPCTaggedErrorOptions<InferSchemaOutput<TSchema>>
318
- >
319
- ) {
320
- const opts = resolveMaybeOptionalOptions(rest);
321
- const status = opts.status ?? defaultStatus;
322
- const inputMessage = opts.message ?? defaultMessage;
323
-
324
- if (status !== undefined && !isORPCErrorStatus(status)) {
325
- throw new globalThis.Error(
326
- "[ORPCTaggedError] Invalid error status code.",
327
- );
328
- }
329
-
330
- const finalStatus = fallbackORPCErrorStatus(code, status);
331
- const finalMessage = fallbackORPCErrorMessage(code, inputMessage);
332
-
333
- const data = opts.data as InferSchemaOutput<TSchema>;
334
- // Pass to Effect's TaggedError - it spreads these onto the instance
335
- super({
336
- message: finalMessage,
337
- cause: opts.cause,
338
- code,
339
- status: finalStatus,
340
- data,
341
- defined: opts.defined ?? true,
342
- });
343
-
344
- // Create the underlying ORPCError for interop
345
- this[ORPCErrorSymbol] = new ORPCError<
346
- TCode,
347
- InferSchemaOutput<TSchema>
348
- >(code, {
349
- status: finalStatus,
350
- message: finalMessage,
351
- data,
352
- defined: this.defined,
353
- cause: opts.cause,
354
- });
355
- }
356
-
357
- /**
358
- * Converts this error to a plain ORPCError.
359
- * Useful when you need to return from an oRPC handler.
360
- */
361
- toORPCError(): ORPCError<TCode, TSchema> {
362
- return this[ORPCErrorSymbol];
250
+ export function ORPCTaggedError<
251
+ TTag extends string,
252
+ TSchema extends AnySchema = AnySchema,
253
+ TCode extends ORPCErrorCode = ToConstantCase<TTag>,
254
+ >(
255
+ tag: TTag,
256
+ props?: {
257
+ schema?: TSchema;
258
+ status?: number;
259
+ message?: string;
260
+ code?: TCode;
261
+ },
262
+ ): ORPCTaggedErrorClass<TTag, TCode, TSchema> {
263
+ const code: TCode = props?.code ?? (toConstantCase(tag) as any);
264
+ class ORPCTaggedErrorBase
265
+ extends Data.TaggedError(tag)
266
+ implements ORPCTaggedErrorInstance<TTag, TCode, TSchema>
267
+ {
268
+ readonly status: number;
269
+ readonly defined: boolean;
270
+ readonly data: InferSchemaOutput<TSchema>;
271
+ readonly code: TCode = code;
272
+ readonly schema = props?.schema as TSchema;
273
+ readonly [ORPCErrorSymbol]: ORPCError<TCode, InferSchemaOutput<TSchema>>;
274
+
275
+ constructor(
276
+ ...rest: MaybeOptionalOptions<
277
+ ORPCTaggedErrorOptions<InferSchemaOutput<TSchema>>
278
+ >
279
+ ) {
280
+ super();
281
+
282
+ const opts = resolveMaybeOptionalOptions(rest);
283
+ const status = opts.status ?? props?.status;
284
+
285
+ if (status !== undefined && !isORPCErrorStatus(status)) {
286
+ throw new globalThis.Error(
287
+ "[ORPCTaggedError] Invalid error status code.",
288
+ );
363
289
  }
364
290
 
365
- override toJSON(): ORPCErrorJSON<TCode, TSchema> & { _tag: TTag } {
366
- return {
367
- _tag: this._tag,
368
- defined: this.defined,
369
- code: this.code,
291
+ this.status = fallbackORPCErrorStatus(code, status);
292
+ this.defined = opts.defined ?? true;
293
+ this.data = opts.data as InferSchemaOutput<TSchema>;
294
+ this.message = fallbackORPCErrorMessage(
295
+ this.code,
296
+ opts.message ?? props?.message,
297
+ );
298
+ this.cause = opts.cause;
299
+
300
+ this[ORPCErrorSymbol] = new ORPCError<TCode, InferSchemaOutput<TSchema>>(
301
+ this.code,
302
+ {
370
303
  status: this.status,
371
304
  message: this.message,
372
305
  data: this.data,
373
- };
374
- }
306
+ defined: this.defined,
307
+ cause: this.cause,
308
+ },
309
+ );
375
310
  }
376
311
 
377
- return ORPCTaggedErrorBase as any;
378
- };
312
+ /**
313
+ * Converts this error to a plain ORPCError.
314
+ * Useful when you need to return from an oRPC handler.
315
+ */
316
+ toORPCError(): ORPCError<TCode, InferSchemaOutput<TSchema>> {
317
+ return this[ORPCErrorSymbol];
318
+ }
319
+
320
+ override toJSON(): ORPCErrorJSON<TCode, InferSchemaOutput<TSchema>> & {
321
+ _tag: TTag;
322
+ } {
323
+ return {
324
+ _tag: this._tag,
325
+ defined: this[ORPCErrorSymbol].defined,
326
+ code: this[ORPCErrorSymbol].code,
327
+ status: this[ORPCErrorSymbol].status,
328
+ message: this[ORPCErrorSymbol].message,
329
+ data: this[ORPCErrorSymbol].data,
330
+ };
331
+ }
332
+ }
379
333
 
380
- return factory as ORPCTaggedErrorFactory<TSchema>;
334
+ return Object.assign(ORPCTaggedErrorBase, {
335
+ _tag: tag,
336
+ code,
337
+ } as const);
381
338
  }
382
339
 
383
340
  /**
@@ -545,8 +502,6 @@ export function effectErrorMapToErrorMap<T extends EffectErrorMap>(
545
502
 
546
503
  if (isORPCTaggedErrorClass(ClassOrErrorItem)) {
547
504
  const classInstance = new ClassOrErrorItem();
548
- // For tagged errors, we create a minimal entry
549
- // The actual validation will be handled by the tagged error class
550
505
  result[classInstance.code] = {
551
506
  status: classInstance.status,
552
507
  message: classInstance.message,
@@ -47,9 +47,9 @@ describe("effectBuilder", () => {
47
47
  });
48
48
 
49
49
  it(".errors", () => {
50
- class BadGatewayError extends ORPCTaggedError(
51
- z.object({ why: z.string() }),
52
- )("BadGatewayError") {}
50
+ class BadGatewayError extends ORPCTaggedError("BadGatewayError", {
51
+ schema: z.object({ why: z.string() }),
52
+ }) {}
53
53
  const errors = { BadGatewayError };
54
54
 
55
55
  const applied = builder.errors(errors);
@@ -18,17 +18,19 @@ import {
18
18
  ORPCTaggedError,
19
19
  } from "../tagged-error";
20
20
 
21
- class UserNotFoundError extends ORPCTaggedError(
22
- z.object({ userId: z.string() }),
23
- )("UserNotFoundError") {}
24
-
25
- class ValidationError extends ORPCTaggedError(
26
- z.object({ fields: z.array(z.string()) }),
27
- )("ValidationError", "BAD_REQUEST", { message: "Validation failed" }) {}
28
- class PermissionDenied extends ORPCTaggedError()(
29
- "PermissionDenied",
30
- "FORBIDDEN",
31
- ) {}
21
+ const userNotFoundSchema = z.object({ userId: z.string() });
22
+ class UserNotFoundError extends ORPCTaggedError("UserNotFoundError", {
23
+ schema: userNotFoundSchema,
24
+ }) {}
25
+
26
+ class ValidationError extends ORPCTaggedError("ValidationError", {
27
+ schema: z.object({ fields: z.array(z.string()) }),
28
+ code: "BAD_REQUEST",
29
+ message: "Validation failed",
30
+ }) {}
31
+ class PermissionDenied extends ORPCTaggedError("PermissionDenied", {
32
+ code: "FORBIDDEN",
33
+ }) {}
32
34
 
33
35
  describe("effectErrorMap types", () => {
34
36
  it("should accept both traditional and tagged error formats", () => {
@@ -159,7 +161,7 @@ describe("effectErrorMapToErrorMap", () => {
159
161
  message: "Bad request",
160
162
  });
161
163
  expect(errorMap.USER_NOT_FOUND_ERROR).toEqual({
162
- data: undefined,
164
+ data: userNotFoundSchema,
163
165
  message: "USER_NOT_FOUND_ERROR",
164
166
  status: 500,
165
167
  });
@@ -12,30 +12,35 @@ import {
12
12
  } from "../tagged-error";
13
13
 
14
14
  // Define test errors with explicit code
15
- class UserNotFoundError extends ORPCTaggedError()(
16
- "UserNotFoundError",
17
- "NOT_FOUND",
18
- ) {}
19
-
20
- class ValidationError extends ORPCTaggedError(
21
- z.object({ fields: z.array(z.string()) }),
22
- )("ValidationError", "BAD_REQUEST", { message: "Validation failed" }) {}
23
-
24
- class CustomStatusError extends ORPCTaggedError()(
25
- "CustomStatusError",
26
- "INTERNAL_SERVER_ERROR",
27
- { status: 503, message: "Service unavailable" },
28
- ) {}
15
+ class UserNotFoundError extends ORPCTaggedError("UserNotFoundError", {
16
+ code: "NOT_FOUND",
17
+ }) {}
18
+
19
+ class ValidationError extends ORPCTaggedError("ValidationError", {
20
+ schema: z.object({ fields: z.array(z.string()) }),
21
+ code: "BAD_REQUEST",
22
+ message: "Validation failed",
23
+ }) {}
24
+
25
+ class CustomStatusError extends ORPCTaggedError("CustomStatusError", {
26
+ code: "INTERNAL_SERVER_ERROR",
27
+ status: 503,
28
+ message: "Service unavailable",
29
+ }) {}
29
30
 
30
31
  // Define test errors with default code (derived from tag)
31
- class AutoCodeError extends ORPCTaggedError()("AutoCodeError") {}
32
+ class AutoCodeError extends ORPCTaggedError("AutoCodeError", {
33
+ code: "AUTO_CODE_ERROR",
34
+ }) {}
32
35
 
33
- class AutoCodeWithOptionsError extends ORPCTaggedError()(
36
+ class AutoCodeWithOptionsError extends ORPCTaggedError(
34
37
  "AutoCodeWithOptionsError",
35
38
  { message: "Auto code error message" },
36
39
  ) {}
37
40
 
38
- class MyCustomError extends ORPCTaggedError()("MyCustomError") {}
41
+ class MyCustomError extends ORPCTaggedError("MyCustomError", {
42
+ code: "MY_CUSTOM_ERROR",
43
+ }) {}
39
44
 
40
45
  describe("class ORPCTaggedError", () => {
41
46
  describe("basic functionality", () => {
@@ -295,32 +300,32 @@ describe("class ORPCTaggedError", () => {
295
300
  describe("TagToCode edge cases", () => {
296
301
  describe("runtime behavior", () => {
297
302
  it("should keep consecutive uppercase letters together", () => {
298
- class TESTError extends ORPCTaggedError()("TEST") {}
303
+ class TESTError extends ORPCTaggedError("TEST") {}
299
304
  expect(TESTError.code).toBe("TEST");
300
305
  });
301
306
 
302
307
  it("should handle single word tags", () => {
303
- class TestError extends ORPCTaggedError()("Test") {}
308
+ class TestError extends ORPCTaggedError("Test") {}
304
309
  expect(TestError.code).toBe("TEST");
305
310
  });
306
311
 
307
312
  it("should split between words correctly", () => {
308
- class TestTestError extends ORPCTaggedError()("TestTest") {}
313
+ class TestTestError extends ORPCTaggedError("TestTest") {}
309
314
  expect(TestTestError.code).toBe("TEST_TEST");
310
315
  });
311
316
 
312
317
  it("should handle tags with single uppercase followed by lowercase", () => {
313
- class UnauthorizedError extends ORPCTaggedError()(
318
+ class UnauthorizedError extends ORPCTaggedError(
314
319
  "UnauthorizedError",
315
320
  ) {}
316
321
  expect(UnauthorizedError.code).toBe("UNAUTHORIZED_ERROR");
317
322
  });
318
323
 
319
324
  it("should handle mixed case patterns", () => {
320
- class HTTPError extends ORPCTaggedError()("HTTPError") {}
325
+ class HTTPError extends ORPCTaggedError("HTTPError") {}
321
326
  expect(HTTPError.code).toBe("HTTP_ERROR");
322
327
 
323
- class XMLParserError extends ORPCTaggedError()("XMLParserError") {}
328
+ class XMLParserError extends ORPCTaggedError("XMLParserError") {}
324
329
  expect(XMLParserError.code).toBe("XML_PARSER_ERROR");
325
330
  });
326
331
  });