effect-orpc 0.0.3 → 0.0.4
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/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/effect-builder.ts +13 -5
- package/src/tests/effect-builder.test.ts +58 -40
- package/src/tests/effect-error-map.test.ts +14 -6
package/dist/index.js
CHANGED
|
@@ -415,10 +415,10 @@ var EffectBuilder = class _EffectBuilder {
|
|
|
415
415
|
lastEventId: opts.lastEventId,
|
|
416
416
|
errors: createEffectErrorConstructorMap(this["~orpc"].effectErrorMap)
|
|
417
417
|
};
|
|
418
|
-
const baseEffect = effectFn(effectOpts);
|
|
419
418
|
const spanName = spanConfig?.name ?? opts.path.join(".");
|
|
420
419
|
const captureStackTrace = spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;
|
|
421
|
-
const
|
|
420
|
+
const resolver = Effect.fnUntraced(effectFn);
|
|
421
|
+
const tracedEffect = Effect.withSpan(resolver(effectOpts), spanName, {
|
|
422
422
|
captureStackTrace
|
|
423
423
|
});
|
|
424
424
|
const exit = await runtime.runPromiseExit(tracedEffect, {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/effect-builder.ts","../src/effect-procedure.ts","../src/tagged-error.ts"],"sourcesContent":["import type { ORPCErrorCode } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaOutput,\n Meta,\n Route,\n Schema,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n BuilderDef,\n Context,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureHandlerOptions,\n} from \"@orpc/server\";\nimport type { IntersectPick } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport {\n mergeErrorMap,\n mergeMeta,\n mergeRoute,\n ORPCError,\n} from \"@orpc/contract\";\nimport {\n addMiddleware,\n Builder,\n decorateMiddleware,\n fallbackConfig,\n} from \"@orpc/server\";\nimport { Cause, Effect, Exit } from \"effect\";\n\nimport type {\n EffectErrorConstructorMap,\n EffectErrorMap,\n EffectErrorMapToUnion,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\n\nimport { EffectDecoratedProcedure } from \"./effect-procedure\";\nimport {\n createEffectErrorConstructorMap,\n effectErrorMapToErrorMap,\n isORPCTaggedError,\n} from \"./tagged-error\";\n\n/**\n * Captures the stack trace at the call site for better error reporting in spans.\n * This is called at procedure definition time to capture where the procedure was defined.\n *\n * @returns A function that lazily extracts the relevant stack frame\n */\nexport function addSpanStackTrace(): () => string | undefined {\n const ErrorConstructor = Error as typeof Error & {\n stackTraceLimit?: number;\n };\n const limit = ErrorConstructor.stackTraceLimit;\n ErrorConstructor.stackTraceLimit = 3;\n const traceError = new Error();\n ErrorConstructor.stackTraceLimit = limit;\n let cache: false | string = false;\n return () => {\n if (cache !== false) {\n return cache;\n }\n if (traceError.stack !== undefined) {\n const stack = traceError.stack.split(\"\\n\");\n if (stack[3] !== undefined) {\n cache = stack[3].trim();\n return cache;\n }\n }\n };\n}\n\n/**\n * Configuration for Effect span tracing.\n */\nexport interface EffectSpanConfig {\n /**\n * The name of the span for telemetry.\n */\n name: string;\n /**\n * Function to lazily capture the stack trace at definition time.\n */\n captureStackTrace: () => string | undefined;\n}\n\n/**\n * Options passed to the Effect procedure handler.\n */\nexport interface EffectProcedureHandlerOptions<\n TCurrentContext extends Context,\n TInput,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n> extends Omit<\n ProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n ORPCErrorConstructorMap<any>,\n TMeta\n >,\n \"errors\"\n> {\n errors: EffectErrorConstructorMap<TEffectErrorMap>;\n}\n\n/**\n * Handler type for Effect procedures.\n * The handler receives procedure options and returns an Effect.\n */\nexport type EffectProcedureHandler<\n TCurrentContext extends Context,\n TInput,\n THandlerOutput,\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TMeta extends Meta,\n> = (\n opt: EffectProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n TEffectErrorMap,\n TMeta\n >,\n) => Effect.Effect<\n THandlerOutput,\n EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,\n TRequirementsProvided\n>;\n\n/**\n * Extended builder definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectBuilderDef<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends BuilderDef<TInputSchema, TOutputSchema, ErrorMap, TMeta> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n /**\n * Optional span configuration for Effect tracing.\n */\n spanConfig?: EffectSpanConfig;\n /**\n * Effect-extended error map that supports both traditional errors and tagged errors.\n */\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * Effect-native procedure builder that wraps an oRPC Builder instance\n * and adds Effect-specific capabilities while preserving Effect error\n * and requirements types.\n */\nexport class EffectBuilder<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> {\n \"~orpc\": EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n this[\"~orpc\"] = def;\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * // Traditional format\n * builder.errors({ BAD_REQUEST: { status: 400, message: 'Bad request' } })\n *\n * // Tagged error class\n * builder.errors({ USER_NOT_FOUND: UserNotFoundError })\n *\n * // Mixed\n * builder.errors({\n * BAD_REQUEST: { status: 400 },\n * USER_NOT_FOUND: UserNotFoundError,\n * })\n * ```\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n errorMap: mergeErrorMap(\n this[\"~orpc\"].errorMap,\n effectErrorMapToErrorMap(errors),\n ),\n effectErrorMap: {\n ...this[\"~orpc\"].effectErrorMap,\n ...errors,\n },\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n unknown,\n unknown,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectBuilder<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectBuilder<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectBuilder({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Defines the input validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Input Validation Docs}\n */\n input<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n USchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n inputSchema: schema,\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~orpc\"].config.initialInputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Defines the output validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Output Validation Docs}\n */\n output<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n USchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n outputSchema: schema,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~orpc\"].config.initialOutputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Adds a traceable span to the procedure for telemetry.\n * The span name is used for Effect tracing via `Effect.withSpan`.\n * Stack trace is captured at the call site for better error reporting.\n *\n * @param spanName - The name of the span for telemetry (e.g., 'users.getUser')\n * @returns An EffectBuilder with span tracing configured\n *\n * @example\n * ```ts\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .traced('users.getUser')\n * .effect(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * ```\n */\n traced(\n spanName: string,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n spanConfig: {\n name: spanName,\n captureStackTrace: addSpanStackTrace(),\n },\n });\n }\n\n /**\n * Defines the handler of the procedure using an Effect.\n * The Effect is executed using the ManagedRuntime provided during builder creation.\n * The effect is automatically wrapped with `Effect.withSpan`.\n *\n * @see {@link https://orpc.dev/docs/procedure Procedure Docs}\n */\n effect<UFuncOutput>(\n effectFn: EffectProcedureHandler<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n UFuncOutput,\n TEffectErrorMap,\n TRequirementsProvided,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n Schema<UFuncOutput, UFuncOutput>,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const { runtime, spanConfig } = this[\"~orpc\"];\n // Capture stack trace at definition time for default tracing\n const defaultCaptureStackTrace = addSpanStackTrace();\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n handler: async (opts) => {\n const effectOpts: EffectProcedureHandlerOptions<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n TEffectErrorMap,\n TMeta\n > = {\n context: opts.context,\n input: opts.input,\n path: opts.path,\n procedure: opts.procedure,\n signal: opts.signal,\n lastEventId: opts.lastEventId,\n errors: createEffectErrorConstructorMap(this[\"~orpc\"].effectErrorMap),\n };\n const baseEffect = effectFn(effectOpts);\n const spanName = spanConfig?.name ?? opts.path.join(\".\");\n const captureStackTrace =\n spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;\n const tracedEffect = Effect.withSpan(baseEffect, spanName, {\n captureStackTrace,\n });\n const exit = await runtime.runPromiseExit(tracedEffect, {\n signal: opts.signal,\n });\n\n if (Exit.isFailure(exit)) {\n throw Cause.match(exit.cause, {\n onDie(defect) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: defect,\n });\n },\n onFail(error) {\n if (isORPCTaggedError(error)) {\n return error.toORPCError();\n }\n if (error instanceof ORPCError) {\n return error;\n }\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: error,\n });\n },\n onInterrupt(fiberId) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(`${fiberId} Interrupted`),\n });\n },\n onSequential(left) {\n return left;\n },\n onEmpty: new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(\"Unknown error\"),\n }),\n onParallel(left) {\n return left;\n },\n });\n }\n\n return exit.value;\n },\n });\n }\n}\n\n/**\n * Any oRPC builder-like object that has the `~orpc` definition property.\n * This includes Builder, BuilderWithMiddlewares, ProcedureBuilder, etc.\n */\nexport interface AnyBuilderLike<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n> {\n \"~orpc\": BuilderDef<TInputSchema, TOutputSchema, TErrorMap, TMeta>;\n}\n\n/**\n * Creates an Effect-aware procedure builder with the specified ManagedRuntime.\n * Uses the default `os` builder from `@orpc/server`.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @returns An EffectBuilder instance for creating Effect-native procedures\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * const runtime = ManagedRuntime.make(Layer.empty)\n * const effectOs = makeEffectORPC(runtime)\n *\n * const hello = effectOs.effect(() => Effect.succeed('Hello!'))\n * ```\n */\nexport function makeEffectORPC<TRequirementsProvided, TRuntimeError>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n): EffectBuilder<\n Context,\n Context,\n Schema<unknown, unknown>,\n Schema<unknown, unknown>,\n Record<never, never>,\n Record<never, never>,\n TRequirementsProvided,\n TRuntimeError\n>;\n\n/**\n * Creates an Effect-aware procedure builder by wrapping an existing oRPC Builder\n * with the specified ManagedRuntime.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @param builder - The oRPC Builder instance to wrap (e.g., a customized `os`)\n * @returns An EffectBuilder instance that extends the original builder with Effect support\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { os } from '@orpc/server'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * // Create a customized builder\n * const authedOs = os.use(authMiddleware)\n *\n * // Wrap it with Effect support\n * const runtime = ManagedRuntime.make(UserServiceLive)\n * const effectOs = makeEffectORPC(runtime, authedOs)\n *\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .effect(\n * Effect.fn(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * )\n * ```\n */\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n>;\n\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder?: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n> {\n const resolvedBuilder =\n builder ?? emptyBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta>();\n return new EffectBuilder({\n ...resolvedBuilder[\"~orpc\"],\n effectErrorMap: resolvedBuilder[\"~orpc\"].errorMap,\n runtime,\n });\n}\n\nfunction emptyBuilder<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n>() {\n return new Builder<\n Record<never, never>,\n Record<never, never>,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta\n >({\n config: {},\n route: {},\n meta: {} as TMeta,\n errorMap: {} as TErrorMap,\n inputValidationIndex: fallbackConfig(\"initialInputValidationIndex\"),\n outputValidationIndex: fallbackConfig(\"initialOutputValidationIndex\"),\n middlewares: [],\n dedupeLeadingMiddlewares: true,\n });\n}\n","import type { ClientContext } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaInput,\n InferSchemaOutput,\n Meta,\n Route,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n Context,\n CreateProcedureClientOptions,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureActionableClient,\n ProcedureClient,\n ProcedureDef,\n} from \"@orpc/server\";\nimport type { IntersectPick, MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport { mergeMeta, mergeRoute } from \"@orpc/contract\";\nimport {\n addMiddleware,\n createActionableClient,\n createProcedureClient,\n decorateMiddleware,\n Procedure,\n} from \"@orpc/server\";\n\nimport type { EffectErrorMap, MergedEffectErrorMap } from \"./tagged-error\";\n\nimport { effectErrorMapToErrorMap } from \"./tagged-error\";\n\n/**\n * Extended procedure definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectProcedureDef<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * An Effect-native decorated procedure that preserves Effect error and requirements types.\n *\n * This class extends Procedure with additional type parameters for Effect-specific\n * type information, allowing full type inference of Effect errors and requirements.\n */\nexport class EffectDecoratedProcedure<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends Procedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n declare \"~orpc\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n super(def);\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const newEffectErrorMap = { ...this[\"~orpc\"].effectErrorMap, ...errors };\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n effectErrorMap: newEffectErrorMap,\n errorMap: effectErrorMapToErrorMap(newEffectErrorMap),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n InferSchemaOutput<TInputSchema>,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInput,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n UInput,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n mapInput: MapInputMiddleware<InferSchemaOutput<TInputSchema>, UInput>,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectDecoratedProcedure<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Make this procedure callable (works like a function while still being a procedure).\n *\n * @see {@link https://orpc.dev/docs/client/server-side Server-side Client Docs}\n */\n callable<TClientContext extends ClientContext>(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n TClientContext\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureClient<TClientContext, TInputSchema, TOutputSchema, ErrorMap> {\n const client: ProcedureClient<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createProcedureClient(this, ...rest);\n\n return new Proxy(client, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n\n /**\n * Make this procedure compatible with server action.\n *\n * @see {@link https://orpc.dev/docs/server-action Server Action Docs}\n */\n actionable(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n Record<never, never>\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureActionableClient<TInputSchema, TOutputSchema, ErrorMap> {\n const action: ProcedureActionableClient<\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createActionableClient(createProcedureClient(this, ...rest));\n\n return new Proxy(action, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n}\n","import type {\n ORPCErrorCode,\n ORPCErrorJSON,\n ORPCErrorOptions,\n} from \"@orpc/client\";\nimport type { AnySchema, ErrorMap, ErrorMapItem } from \"@orpc/contract\";\nimport type { ORPCErrorConstructorMapItemOptions } from \"@orpc/server\";\nimport type { MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { Pipeable, Types } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\nimport type * as Effect from \"effect/Effect\";\n\nimport {\n fallbackORPCErrorMessage,\n fallbackORPCErrorStatus,\n isORPCErrorStatus,\n ORPCError,\n} from \"@orpc/client\";\nimport { resolveMaybeOptionalOptions } from \"@orpc/shared\";\nimport * as Data from \"effect/Data\";\n\n/**\n * Symbol to access the underlying ORPCError instance\n */\nexport const ORPCErrorSymbol: unique symbol = Symbol.for(\n \"@orpc/effect/ORPCTaggedError\",\n);\n\n/**\n * Instance type for ORPCTaggedError that combines YieldableError with ORPCError properties\n */\nexport interface ORPCTaggedErrorInstance<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n>\n extends Cause.YieldableError, Pipeable.Pipeable {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag };\n toORPCError(): ORPCError<TCode, TData>;\n commit(): Effect.Effect<never, this, never>;\n}\n\n/**\n * Options for creating an ORPCTaggedError\n */\nexport type ORPCTaggedErrorOptions<TData> = Omit<\n ORPCErrorOptions<TData>,\n \"defined\"\n> & { defined?: boolean };\n\n/**\n * Constructor type for ORPCTaggedError classes\n */\nexport interface ORPCTaggedErrorClass<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n> {\n readonly _tag: TTag;\n readonly code: TCode;\n new (\n ...args: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ): ORPCTaggedErrorInstance<TTag, TCode, TData>;\n}\n\n/**\n * Type helper to infer the ORPCError type from an ORPCTaggedError\n */\nexport type InferORPCError<T> =\n T extends ORPCTaggedErrorInstance<string, infer TCode, infer TData>\n ? ORPCError<TCode, TData>\n : never;\n\n/**\n * Any ORPCTaggedErrorClass\n */\nexport type AnyORPCTaggedErrorClass = ORPCTaggedErrorClass<\n string,\n ORPCErrorCode,\n any\n>;\n\n/**\n * Check if a value is an ORPCTaggedErrorClass (constructor)\n */\nexport function isORPCTaggedErrorClass(\n value: unknown,\n): value is AnyORPCTaggedErrorClass {\n return (\n typeof value === \"function\" &&\n \"_tag\" in value &&\n \"code\" in value &&\n typeof value._tag === \"string\" &&\n typeof value.code === \"string\"\n );\n}\n\n/**\n * Check if a value is an ORPCTaggedError instance\n */\nexport function isORPCTaggedError(\n value: unknown,\n): value is ORPCTaggedErrorInstance<string, ORPCErrorCode, unknown> {\n return (\n typeof value === \"object\" && value !== null && ORPCErrorSymbol in value\n );\n}\n\n/**\n * Converts a PascalCase or camelCase string to CONSTANT_CASE.\n * e.g., \"UserNotFoundError\" -> \"USER_NOT_FOUND_ERROR\"\n */\nfunction toConstantCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1_$2\")\n .replace(/([A-Z])([A-Z][a-z])/g, \"$1_$2\")\n .toUpperCase();\n}\n\n// Type-level conversion: split on capital letters and join with underscore\ntype SplitOnCapital<\n S extends string,\n Acc extends string = \"\",\n> = S extends `${infer Head}${infer Tail}`\n ? Head extends Uppercase<Head>\n ? Head extends Lowercase<Head>\n ? SplitOnCapital<Tail, `${Acc}${Head}`>\n : Acc extends \"\"\n ? SplitOnCapital<Tail, Head>\n : `${Acc}_${SplitOnCapital<Tail, Head>}`\n : SplitOnCapital<Tail, `${Acc}${Uppercase<Head>}`>\n : Acc;\n\n/**\n * Converts a tag name to an error code in CONSTANT_CASE.\n */\nexport type TagToCode<TTag extends string> = SplitOnCapital<TTag>;\n\n/**\n * Creates a tagged error class that combines Effect's YieldableError with ORPCError.\n *\n * This allows you to create errors that:\n * - Can be yielded in Effect generators (`yield* myError`)\n * - Have all ORPCError properties (code, status, data, defined)\n * - Can be converted to a plain ORPCError for oRPC handlers\n *\n * The returned factory function takes:\n * - `tag` - The unique tag for this error type (used for discriminated unions)\n * - `codeOrOptions` - Optional ORPC error code or options. If omitted, code defaults to CONSTANT_CASE of tag\n * - `defaultOptions` - Optional default options for status and message (when code is provided)\n *\n * @example\n * ```ts\n * import { ORPCTaggedError } from '@orpc/effect'\n * import { Effect } from 'effect'\n *\n * // Define a custom error (code defaults to 'USER_NOT_FOUND_ERROR')\n * class UserNotFoundError extends ORPCTaggedError<UserNotFoundError>()('UserNotFoundError') {}\n *\n * // With explicit code\n * class NotFoundError extends ORPCTaggedError<NotFoundError>()('NotFoundError', 'NOT_FOUND') {}\n *\n * // Use in an Effect\n * const getUser = (id: string) => Effect.gen(function* () {\n * const user = yield* findUser(id)\n * if (!user) {\n * return yield* new UserNotFoundError({ data: { userId: id } })\n * }\n * return user\n * })\n *\n * // With custom data type\n * class ValidationError extends ORPCTaggedError<ValidationError, { fields: string[] }>()('ValidationError', 'BAD_REQUEST') {}\n *\n * // With options only (code defaults to 'VALIDATION_ERROR')\n * class ValidationError2 extends ORPCTaggedError<ValidationError2, { fields: string[] }>()(\n * 'ValidationError2',\n * { message: 'Validation failed' }\n * ) {}\n * ```\n */\n/**\n * Return type for the factory function with overloads\n */\ninterface ORPCTaggedErrorFactory<Self, TData> {\n // Overload 1: tag only (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 2: tag + options (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n options: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, options) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 3: tag + explicit code\n <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n code: TCode,\n defaultOptions?: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, code) {}\\``\n : ORPCTaggedErrorClass<TTag, TCode, TData>;\n}\n\nexport function ORPCTaggedError<\n Self,\n TData = undefined,\n>(): ORPCTaggedErrorFactory<Self, TData> {\n const factory = <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n codeOrOptions?: TCode | { status?: number; message?: string },\n defaultOptions?: { status?: number; message?: string },\n ): ORPCTaggedErrorClass<TTag, TCode, TData> => {\n // Determine if second arg is code or options\n const isCodeProvided = typeof codeOrOptions === \"string\";\n const code = (\n isCodeProvided ? codeOrOptions : toConstantCase(tag)\n ) as TCode;\n const options = isCodeProvided ? defaultOptions : codeOrOptions;\n\n const defaultStatus = options?.status;\n const defaultMessage = options?.message;\n\n // Use Effect's TaggedError as the base - this handles all Effect internals\n // (YieldableError, type symbols, commit(), Symbol.iterator, pipe(), etc.)\n const BaseTaggedError = Data.TaggedError(tag) as unknown as new (args: {\n message?: string;\n cause?: unknown;\n code: TCode;\n status: number;\n data: TData;\n defined: boolean;\n }) => Cause.YieldableError & {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n };\n\n class ORPCTaggedErrorBase extends BaseTaggedError {\n static readonly _tag = tag;\n static readonly code = code;\n\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n constructor(\n ...rest: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ) {\n const opts = resolveMaybeOptionalOptions(rest);\n const status = opts.status ?? defaultStatus;\n const inputMessage = opts.message ?? defaultMessage;\n\n if (status !== undefined && !isORPCErrorStatus(status)) {\n throw new globalThis.Error(\n \"[ORPCTaggedError] Invalid error status code.\",\n );\n }\n\n const finalStatus = fallbackORPCErrorStatus(code, status);\n const finalMessage = fallbackORPCErrorMessage(code, inputMessage);\n\n // Pass to Effect's TaggedError - it spreads these onto the instance\n super({\n message: finalMessage,\n cause: opts.cause,\n code,\n status: finalStatus,\n data: opts.data as TData,\n defined: opts.defined ?? true,\n });\n\n // Create the underlying ORPCError for interop\n this[ORPCErrorSymbol] = new ORPCError(code, {\n status: finalStatus,\n message: finalMessage,\n data: opts.data as TData,\n defined: this.defined,\n cause: opts.cause,\n });\n }\n\n /**\n * Converts this error to a plain ORPCError.\n * Useful when you need to return from an oRPC handler.\n */\n toORPCError(): ORPCError<TCode, TData> {\n return this[ORPCErrorSymbol];\n }\n\n override toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag } {\n return {\n _tag: this._tag,\n defined: this.defined,\n code: this.code,\n status: this.status,\n message: this.message,\n data: this.data,\n };\n }\n }\n\n return ORPCTaggedErrorBase as any;\n };\n\n return factory as ORPCTaggedErrorFactory<Self, TData>;\n}\n\n/**\n * Converts an ORPCTaggedError to a plain ORPCError.\n * Useful in handlers that need to throw ORPCError.\n *\n * @example\n * ```ts\n * const handler = effectOs.effect(function* () {\n * const result = yield* someOperation.pipe(\n * Effect.catchTag('UserNotFoundError', (e) =>\n * Effect.fail(toORPCError(e))\n * )\n * )\n * return result\n * })\n * ```\n */\nexport function toORPCError<TCode extends ORPCErrorCode, TData>(\n error: ORPCTaggedErrorInstance<string, TCode, TData>,\n): ORPCError<TCode, TData> {\n return error[ORPCErrorSymbol];\n}\n\n// ============================================================================\n// Extended Error Map Types for Effect\n// ============================================================================\n\n/**\n * An item in the EffectErrorMap - can be either a traditional ErrorMapItem or an ORPCTaggedErrorClass\n */\nexport type EffectErrorMapItem =\n | ErrorMapItem<AnySchema>\n | AnyORPCTaggedErrorClass;\n\n/**\n * Extended error map that supports both traditional oRPC errors and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * const errorMap = {\n * // Traditional format\n * BAD_REQUEST: { status: 400, message: 'Bad request' },\n *\n * // Tagged error class reference\n * USER_NOT_FOUND: UserNotFoundError,\n * } satisfies EffectErrorMap\n * ```\n */\nexport type EffectErrorMap = {\n [key in ORPCErrorCode]?: EffectErrorMapItem;\n};\n\n/**\n * Merges two EffectErrorMaps, with the second map taking precedence.\n */\nexport type MergedEffectErrorMap<\n T1 extends EffectErrorMap,\n T2 extends EffectErrorMap,\n> = T1 & T2;\n\n/**\n * Extracts the instance type from an EffectErrorMapItem\n */\nexport type EffectErrorMapItemToInstance<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> = T extends AnyORPCTaggedErrorClass\n ? InstanceType<T>\n : T extends { data?: infer TData }\n ? ORPCError<TCode, TData>\n : ORPCError<TCode, unknown>;\n\n/**\n * Converts an EffectErrorMap to a union of error instances.\n */\nexport type EffectErrorMapToUnion<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorMapItemToInstance<K, T[K]>\n : never\n : never;\n}[keyof T];\n\n/**\n * Type for the error constructors available in Effect handlers.\n * For tagged errors, it's the class constructor itself.\n * For traditional errors, it's a function that creates ORPCError.\n */\nexport type EffectErrorConstructorMapItem<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> =\n T extends ORPCTaggedErrorClass<infer _TTag, TCode, infer TData>\n ? ORPCTaggedErrorClass<_TTag, TCode, TData>\n : T extends { data?: infer TData }\n ? (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<TData>\n >\n ) => ORPCError<TCode, TData>\n : (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<unknown>\n >\n ) => ORPCError<TCode, unknown>;\n\n/**\n * Constructor map for EffectErrorMap - provides typed error constructors for handlers.\n */\nexport type EffectErrorConstructorMap<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorConstructorMapItem<K, T[K]>\n : never\n : never;\n};\n\n/**\n * Creates an error constructor map from an EffectErrorMap.\n * Tagged error classes are passed through directly.\n * Traditional error items become ORPCError factory functions.\n */\nexport function createEffectErrorConstructorMap<T extends EffectErrorMap>(\n errors: T | undefined,\n): EffectErrorConstructorMap<T> {\n const target = errors ?? ({} as T);\n const proxy = new Proxy(target, {\n get(proxyTarget, code) {\n if (typeof code !== \"string\") {\n return Reflect.get(proxyTarget, code);\n }\n\n const config = target[code];\n\n // If it's a tagged error class, return it directly\n if (isORPCTaggedErrorClass(config)) {\n return config;\n }\n\n // Otherwise, create a factory function for ORPCError\n return (\n ...rest: MaybeOptionalOptions<\n Omit<ORPCErrorOptions<unknown>, \"defined\" | \"status\">\n >\n ) => {\n const options = resolveMaybeOptionalOptions(rest);\n return new ORPCError(code, {\n defined: Boolean(config),\n status: config?.status,\n message: options.message ?? config?.message,\n data: options.data,\n cause: options.cause,\n });\n };\n },\n });\n\n return proxy as EffectErrorConstructorMap<T>;\n}\n\n/**\n * Converts an EffectErrorMap to a standard oRPC ErrorMap for interop.\n * Tagged error classes are converted to their equivalent ErrorMapItem format.\n */\nexport function effectErrorMapToErrorMap<T extends EffectErrorMap>(\n errorMap: T | undefined,\n): ErrorMap {\n const result: ErrorMap = {};\n\n if (!errorMap) {\n return result;\n }\n\n for (const [code, ClassOrErrorItem] of Object.entries(errorMap)) {\n if (!ClassOrErrorItem) {\n continue;\n }\n\n if (isORPCTaggedErrorClass(ClassOrErrorItem)) {\n const error = new ClassOrErrorItem().toORPCError();\n\n // For tagged errors, we create a minimal entry\n // The actual validation will be handled by the tagged error class\n result[code] = {\n status: error.status,\n message: error.message,\n data: error.data,\n };\n } else {\n result[code] = ClassOrErrorItem;\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["mergeMeta","mergeRoute","ORPCError","addMiddleware","decorateMiddleware","decorateMiddleware","addMiddleware","mergeMeta","mergeRoute","ORPCError"]}
|
|
1
|
+
{"version":3,"sources":["../src/effect-builder.ts","../src/effect-procedure.ts","../src/tagged-error.ts"],"sourcesContent":["import type { ORPCErrorCode } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaOutput,\n Meta,\n Route,\n Schema,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n BuilderDef,\n Context,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureHandlerOptions,\n} from \"@orpc/server\";\nimport type { IntersectPick } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\nimport type { YieldWrap } from \"effect/Utils\";\n\nimport {\n mergeErrorMap,\n mergeMeta,\n mergeRoute,\n ORPCError,\n} from \"@orpc/contract\";\nimport {\n addMiddleware,\n Builder,\n decorateMiddleware,\n fallbackConfig,\n} from \"@orpc/server\";\nimport { Cause, Effect, Exit } from \"effect\";\n\nimport type {\n EffectErrorConstructorMap,\n EffectErrorMap,\n EffectErrorMapToUnion,\n MergedEffectErrorMap,\n} from \"./tagged-error\";\n\nimport { EffectDecoratedProcedure } from \"./effect-procedure\";\nimport {\n createEffectErrorConstructorMap,\n effectErrorMapToErrorMap,\n isORPCTaggedError,\n} from \"./tagged-error\";\n\n/**\n * Captures the stack trace at the call site for better error reporting in spans.\n * This is called at procedure definition time to capture where the procedure was defined.\n *\n * @returns A function that lazily extracts the relevant stack frame\n */\nexport function addSpanStackTrace(): () => string | undefined {\n const ErrorConstructor = Error as typeof Error & {\n stackTraceLimit?: number;\n };\n const limit = ErrorConstructor.stackTraceLimit;\n ErrorConstructor.stackTraceLimit = 3;\n const traceError = new Error();\n ErrorConstructor.stackTraceLimit = limit;\n let cache: false | string = false;\n return () => {\n if (cache !== false) {\n return cache;\n }\n if (traceError.stack !== undefined) {\n const stack = traceError.stack.split(\"\\n\");\n if (stack[3] !== undefined) {\n cache = stack[3].trim();\n return cache;\n }\n }\n };\n}\n\n/**\n * Configuration for Effect span tracing.\n */\nexport interface EffectSpanConfig {\n /**\n * The name of the span for telemetry.\n */\n name: string;\n /**\n * Function to lazily capture the stack trace at definition time.\n */\n captureStackTrace: () => string | undefined;\n}\n\n/**\n * Options passed to the Effect procedure handler.\n */\nexport interface EffectProcedureHandlerOptions<\n TCurrentContext extends Context,\n TInput,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n> extends Omit<\n ProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n ORPCErrorConstructorMap<any>,\n TMeta\n >,\n \"errors\"\n> {\n errors: EffectErrorConstructorMap<TEffectErrorMap>;\n}\n\n/**\n * Handler type for Effect procedures.\n * The handler receives procedure options and returns an Effect.\n */\nexport type EffectProcedureHandler<\n TCurrentContext extends Context,\n TInput,\n THandlerOutput,\n TEffectErrorMap extends EffectErrorMap,\n TRequirementsProvided,\n TMeta extends Meta,\n> = (\n opt: EffectProcedureHandlerOptions<\n TCurrentContext,\n TInput,\n TEffectErrorMap,\n TMeta\n >,\n) => Generator<\n YieldWrap<\n Effect.Effect<\n any,\n | EffectErrorMapToUnion<TEffectErrorMap>\n | ORPCError<ORPCErrorCode, unknown>,\n TRequirementsProvided\n >\n >,\n THandlerOutput,\n never\n>;\n\n/**\n * Extended builder definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectBuilderDef<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends BuilderDef<TInputSchema, TOutputSchema, ErrorMap, TMeta> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n /**\n * Optional span configuration for Effect tracing.\n */\n spanConfig?: EffectSpanConfig;\n /**\n * Effect-extended error map that supports both traditional errors and tagged errors.\n */\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * Effect-native procedure builder that wraps an oRPC Builder instance\n * and adds Effect-specific capabilities while preserving Effect error\n * and requirements types.\n */\nexport class EffectBuilder<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> {\n \"~orpc\": EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectBuilderDef<\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n this[\"~orpc\"] = def;\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * // Traditional format\n * builder.errors({ BAD_REQUEST: { status: 400, message: 'Bad request' } })\n *\n * // Tagged error class\n * builder.errors({ USER_NOT_FOUND: UserNotFoundError })\n *\n * // Mixed\n * builder.errors({\n * BAD_REQUEST: { status: 400 },\n * USER_NOT_FOUND: UserNotFoundError,\n * })\n * ```\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n errorMap: mergeErrorMap(\n this[\"~orpc\"].errorMap,\n effectErrorMapToErrorMap(errors),\n ),\n effectErrorMap: {\n ...this[\"~orpc\"].effectErrorMap,\n ...errors,\n },\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n unknown,\n unknown,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectBuilder<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectBuilder<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectBuilder({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Defines the input validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Input Validation Docs}\n */\n input<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n USchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n inputSchema: schema,\n inputValidationIndex:\n fallbackConfig(\n \"initialInputValidationIndex\",\n this[\"~orpc\"].config.initialInputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Defines the output validation schema.\n *\n * @see {@link https://orpc.dev/docs/procedure#input-output-validation Output Validation Docs}\n */\n output<USchema extends AnySchema>(\n schema: USchema,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n USchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n outputSchema: schema,\n outputValidationIndex:\n fallbackConfig(\n \"initialOutputValidationIndex\",\n this[\"~orpc\"].config.initialOutputValidationIndex,\n ) + this[\"~orpc\"].middlewares.length,\n });\n }\n\n /**\n * Adds a traceable span to the procedure for telemetry.\n * The span name is used for Effect tracing via `Effect.withSpan`.\n * Stack trace is captured at the call site for better error reporting.\n *\n * @param spanName - The name of the span for telemetry (e.g., 'users.getUser')\n * @returns An EffectBuilder with span tracing configured\n *\n * @example\n * ```ts\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .traced('users.getUser')\n * .effect(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * ```\n */\n traced(\n spanName: string,\n ): EffectBuilder<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectBuilder({\n ...this[\"~orpc\"],\n spanConfig: {\n name: spanName,\n captureStackTrace: addSpanStackTrace(),\n },\n });\n }\n\n /**\n * Defines the handler of the procedure using an Effect.\n * The Effect is executed using the ManagedRuntime provided during builder creation.\n * The effect is automatically wrapped with `Effect.withSpan`.\n *\n * @see {@link https://orpc.dev/docs/procedure Procedure Docs}\n */\n effect<UFuncOutput>(\n effectFn: EffectProcedureHandler<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n UFuncOutput,\n TEffectErrorMap,\n TRequirementsProvided,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n Schema<UFuncOutput, UFuncOutput>,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const { runtime, spanConfig } = this[\"~orpc\"];\n // Capture stack trace at definition time for default tracing\n const defaultCaptureStackTrace = addSpanStackTrace();\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n handler: async (opts) => {\n const effectOpts: EffectProcedureHandlerOptions<\n TCurrentContext,\n InferSchemaOutput<TInputSchema>,\n TEffectErrorMap,\n TMeta\n > = {\n context: opts.context,\n input: opts.input,\n path: opts.path,\n procedure: opts.procedure,\n signal: opts.signal,\n lastEventId: opts.lastEventId,\n errors: createEffectErrorConstructorMap(this[\"~orpc\"].effectErrorMap),\n };\n const spanName = spanConfig?.name ?? opts.path.join(\".\");\n const captureStackTrace =\n spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;\n const resolver = Effect.fnUntraced(effectFn);\n const tracedEffect = Effect.withSpan(resolver(effectOpts), spanName, {\n captureStackTrace,\n });\n const exit = await runtime.runPromiseExit(tracedEffect, {\n signal: opts.signal,\n });\n\n if (Exit.isFailure(exit)) {\n throw Cause.match(exit.cause, {\n onDie(defect) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: defect,\n });\n },\n onFail(error) {\n if (isORPCTaggedError(error)) {\n return error.toORPCError();\n }\n if (error instanceof ORPCError) {\n return error;\n }\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: error,\n });\n },\n onInterrupt(fiberId) {\n return new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(`${fiberId} Interrupted`),\n });\n },\n onSequential(left) {\n return left;\n },\n onEmpty: new ORPCError(\"INTERNAL_SERVER_ERROR\", {\n cause: new Error(\"Unknown error\"),\n }),\n onParallel(left) {\n return left;\n },\n });\n }\n\n return exit.value;\n },\n });\n }\n}\n\n/**\n * Any oRPC builder-like object that has the `~orpc` definition property.\n * This includes Builder, BuilderWithMiddlewares, ProcedureBuilder, etc.\n */\nexport interface AnyBuilderLike<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n> {\n \"~orpc\": BuilderDef<TInputSchema, TOutputSchema, TErrorMap, TMeta>;\n}\n\n/**\n * Creates an Effect-aware procedure builder with the specified ManagedRuntime.\n * Uses the default `os` builder from `@orpc/server`.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @returns An EffectBuilder instance for creating Effect-native procedures\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * const runtime = ManagedRuntime.make(Layer.empty)\n * const effectOs = makeEffectORPC(runtime)\n *\n * const hello = effectOs.effect(() => Effect.succeed('Hello!'))\n * ```\n */\nexport function makeEffectORPC<TRequirementsProvided, TRuntimeError>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n): EffectBuilder<\n Context,\n Context,\n Schema<unknown, unknown>,\n Schema<unknown, unknown>,\n Record<never, never>,\n Record<never, never>,\n TRequirementsProvided,\n TRuntimeError\n>;\n\n/**\n * Creates an Effect-aware procedure builder by wrapping an existing oRPC Builder\n * with the specified ManagedRuntime.\n *\n * @param runtime - The ManagedRuntime that provides services for Effect procedures\n * @param builder - The oRPC Builder instance to wrap (e.g., a customized `os`)\n * @returns An EffectBuilder instance that extends the original builder with Effect support\n *\n * @example\n * ```ts\n * import { makeEffectORPC } from '@orpc/effect'\n * import { os } from '@orpc/server'\n * import { Effect, Layer, ManagedRuntime } from 'effect'\n *\n * // Create a customized builder\n * const authedOs = os.use(authMiddleware)\n *\n * // Wrap it with Effect support\n * const runtime = ManagedRuntime.make(UserServiceLive)\n * const effectOs = makeEffectORPC(runtime, authedOs)\n *\n * const getUser = effectOs\n * .input(z.object({ id: z.string() }))\n * .effect(\n * Effect.fn(function* ({ input }) {\n * const userService = yield* UserService\n * return yield* userService.findById(input.id)\n * })\n * )\n * ```\n */\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n>;\n\nexport function makeEffectORPC<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n>(\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,\n builder?: AnyBuilderLike<TInputSchema, TOutputSchema, TErrorMap, TMeta>,\n): EffectBuilder<\n Context,\n Context,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n> {\n const resolvedBuilder =\n builder ?? emptyBuilder<TInputSchema, TOutputSchema, TErrorMap, TMeta>();\n return new EffectBuilder({\n ...resolvedBuilder[\"~orpc\"],\n effectErrorMap: resolvedBuilder[\"~orpc\"].errorMap,\n runtime,\n });\n}\n\nfunction emptyBuilder<\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TErrorMap extends ErrorMap,\n TMeta extends Meta,\n>() {\n return new Builder<\n Record<never, never>,\n Record<never, never>,\n TInputSchema,\n TOutputSchema,\n TErrorMap,\n TMeta\n >({\n config: {},\n route: {},\n meta: {} as TMeta,\n errorMap: {} as TErrorMap,\n inputValidationIndex: fallbackConfig(\"initialInputValidationIndex\"),\n outputValidationIndex: fallbackConfig(\"initialOutputValidationIndex\"),\n middlewares: [],\n dedupeLeadingMiddlewares: true,\n });\n}\n","import type { ClientContext } from \"@orpc/client\";\nimport type {\n AnySchema,\n ErrorMap,\n InferSchemaInput,\n InferSchemaOutput,\n Meta,\n Route,\n} from \"@orpc/contract\";\nimport type {\n AnyMiddleware,\n Context,\n CreateProcedureClientOptions,\n MapInputMiddleware,\n MergedCurrentContext,\n MergedInitialContext,\n Middleware,\n ORPCErrorConstructorMap,\n ProcedureActionableClient,\n ProcedureClient,\n ProcedureDef,\n} from \"@orpc/server\";\nimport type { IntersectPick, MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { ManagedRuntime } from \"effect\";\n\nimport { mergeMeta, mergeRoute } from \"@orpc/contract\";\nimport {\n addMiddleware,\n createActionableClient,\n createProcedureClient,\n decorateMiddleware,\n Procedure,\n} from \"@orpc/server\";\n\nimport type { EffectErrorMap, MergedEffectErrorMap } from \"./tagged-error\";\n\nimport { effectErrorMapToErrorMap } from \"./tagged-error\";\n\n/**\n * Extended procedure definition that includes the Effect ManagedRuntime.\n */\nexport interface EffectProcedureDef<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends ProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;\n effectErrorMap: TEffectErrorMap;\n}\n\n/**\n * An Effect-native decorated procedure that preserves Effect error and requirements types.\n *\n * This class extends Procedure with additional type parameters for Effect-specific\n * type information, allowing full type inference of Effect errors and requirements.\n */\nexport class EffectDecoratedProcedure<\n TInitialContext extends Context,\n TCurrentContext extends Context,\n TInputSchema extends AnySchema,\n TOutputSchema extends AnySchema,\n TEffectErrorMap extends EffectErrorMap,\n TMeta extends Meta,\n TRequirementsProvided,\n TRuntimeError,\n> extends Procedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap,\n TMeta\n> {\n declare \"~orpc\": EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n constructor(\n def: EffectProcedureDef<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >,\n ) {\n super(def);\n }\n\n /**\n * Adds type-safe custom errors.\n * Supports both traditional oRPC error definitions and ORPCTaggedError classes.\n *\n * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}\n */\n errors<U extends EffectErrorMap>(\n errors: U,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n MergedEffectErrorMap<TEffectErrorMap, U>,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n const newEffectErrorMap = { ...this[\"~orpc\"].effectErrorMap, ...errors };\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n effectErrorMap: newEffectErrorMap,\n errorMap: effectErrorMapToErrorMap(newEffectErrorMap),\n });\n }\n\n /**\n * Sets or updates the metadata.\n * The provided metadata is spared-merged with any existing metadata.\n *\n * @see {@link https://orpc.dev/docs/metadata Metadata Docs}\n */\n meta(\n meta: TMeta,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n meta: mergeMeta(this[\"~orpc\"].meta, meta),\n });\n }\n\n /**\n * Sets or updates the route definition.\n * The provided route is spared-merged with any existing route.\n * This option is typically relevant when integrating with OpenAPI.\n *\n * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}\n * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}\n */\n route(\n route: Route,\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > {\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n route: mergeRoute(this[\"~orpc\"].route, route),\n });\n }\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n InferSchemaOutput<TInputSchema>,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n /**\n * Uses a middleware to modify the context or improve the pipeline.\n *\n * @info Supports both normal middleware and inline middleware implementations.\n * @info Pass second argument to map the input.\n * @note The current context must be satisfy middleware dependent-context\n * @see {@link https://orpc.dev/docs/middleware Middleware Docs}\n */\n use<\n UOutContext extends IntersectPick<TCurrentContext, UOutContext>,\n UInput,\n UInContext extends Context = TCurrentContext,\n >(\n middleware: Middleware<\n UInContext | TCurrentContext,\n UOutContext,\n UInput,\n InferSchemaInput<TOutputSchema>,\n ORPCErrorConstructorMap<ErrorMap>,\n TMeta\n >,\n mapInput: MapInputMiddleware<InferSchemaOutput<TInputSchema>, UInput>,\n ): EffectDecoratedProcedure<\n MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,\n MergedCurrentContext<TCurrentContext, UOutContext>,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n >;\n\n use(\n middleware: AnyMiddleware,\n mapInput?: MapInputMiddleware<any, any>,\n ): EffectDecoratedProcedure<any, any, any, any, any, any, any, any> {\n const mapped = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware;\n\n return new EffectDecoratedProcedure({\n ...this[\"~orpc\"],\n middlewares: addMiddleware(this[\"~orpc\"].middlewares, mapped),\n });\n }\n\n /**\n * Make this procedure callable (works like a function while still being a procedure).\n *\n * @see {@link https://orpc.dev/docs/client/server-side Server-side Client Docs}\n */\n callable<TClientContext extends ClientContext>(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n TClientContext\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureClient<TClientContext, TInputSchema, TOutputSchema, ErrorMap> {\n const client: ProcedureClient<\n TClientContext,\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createProcedureClient(this, ...rest);\n\n return new Proxy(client, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n\n /**\n * Make this procedure compatible with server action.\n *\n * @see {@link https://orpc.dev/docs/server-action Server Action Docs}\n */\n actionable(\n ...rest: MaybeOptionalOptions<\n CreateProcedureClientOptions<\n TInitialContext,\n TOutputSchema,\n ErrorMap,\n TMeta,\n Record<never, never>\n >\n >\n ): EffectDecoratedProcedure<\n TInitialContext,\n TCurrentContext,\n TInputSchema,\n TOutputSchema,\n TEffectErrorMap,\n TMeta,\n TRequirementsProvided,\n TRuntimeError\n > &\n ProcedureActionableClient<TInputSchema, TOutputSchema, ErrorMap> {\n const action: ProcedureActionableClient<\n TInputSchema,\n TOutputSchema,\n ErrorMap\n > = createActionableClient(createProcedureClient(this, ...rest));\n\n return new Proxy(action, {\n get: (target, key) => {\n return Reflect.has(this, key)\n ? Reflect.get(this, key)\n : Reflect.get(target, key);\n },\n has: (target, key) => {\n return Reflect.has(this, key) || Reflect.has(target, key);\n },\n }) as any;\n }\n}\n","import type {\n ORPCErrorCode,\n ORPCErrorJSON,\n ORPCErrorOptions,\n} from \"@orpc/client\";\nimport type { AnySchema, ErrorMap, ErrorMapItem } from \"@orpc/contract\";\nimport type { ORPCErrorConstructorMapItemOptions } from \"@orpc/server\";\nimport type { MaybeOptionalOptions } from \"@orpc/shared\";\nimport type { Pipeable, Types } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\nimport type * as Effect from \"effect/Effect\";\n\nimport {\n fallbackORPCErrorMessage,\n fallbackORPCErrorStatus,\n isORPCErrorStatus,\n ORPCError,\n} from \"@orpc/client\";\nimport { resolveMaybeOptionalOptions } from \"@orpc/shared\";\nimport * as Data from \"effect/Data\";\n\n/**\n * Symbol to access the underlying ORPCError instance\n */\nexport const ORPCErrorSymbol: unique symbol = Symbol.for(\n \"@orpc/effect/ORPCTaggedError\",\n);\n\n/**\n * Instance type for ORPCTaggedError that combines YieldableError with ORPCError properties\n */\nexport interface ORPCTaggedErrorInstance<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n>\n extends Cause.YieldableError, Pipeable.Pipeable {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag };\n toORPCError(): ORPCError<TCode, TData>;\n commit(): Effect.Effect<never, this, never>;\n}\n\n/**\n * Options for creating an ORPCTaggedError\n */\nexport type ORPCTaggedErrorOptions<TData> = Omit<\n ORPCErrorOptions<TData>,\n \"defined\"\n> & { defined?: boolean };\n\n/**\n * Constructor type for ORPCTaggedError classes\n */\nexport interface ORPCTaggedErrorClass<\n TTag extends string,\n TCode extends ORPCErrorCode,\n TData,\n> {\n readonly _tag: TTag;\n readonly code: TCode;\n new (\n ...args: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ): ORPCTaggedErrorInstance<TTag, TCode, TData>;\n}\n\n/**\n * Type helper to infer the ORPCError type from an ORPCTaggedError\n */\nexport type InferORPCError<T> =\n T extends ORPCTaggedErrorInstance<string, infer TCode, infer TData>\n ? ORPCError<TCode, TData>\n : never;\n\n/**\n * Any ORPCTaggedErrorClass\n */\nexport type AnyORPCTaggedErrorClass = ORPCTaggedErrorClass<\n string,\n ORPCErrorCode,\n any\n>;\n\n/**\n * Check if a value is an ORPCTaggedErrorClass (constructor)\n */\nexport function isORPCTaggedErrorClass(\n value: unknown,\n): value is AnyORPCTaggedErrorClass {\n return (\n typeof value === \"function\" &&\n \"_tag\" in value &&\n \"code\" in value &&\n typeof value._tag === \"string\" &&\n typeof value.code === \"string\"\n );\n}\n\n/**\n * Check if a value is an ORPCTaggedError instance\n */\nexport function isORPCTaggedError(\n value: unknown,\n): value is ORPCTaggedErrorInstance<string, ORPCErrorCode, unknown> {\n return (\n typeof value === \"object\" && value !== null && ORPCErrorSymbol in value\n );\n}\n\n/**\n * Converts a PascalCase or camelCase string to CONSTANT_CASE.\n * e.g., \"UserNotFoundError\" -> \"USER_NOT_FOUND_ERROR\"\n */\nfunction toConstantCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1_$2\")\n .replace(/([A-Z])([A-Z][a-z])/g, \"$1_$2\")\n .toUpperCase();\n}\n\n// Type-level conversion: split on capital letters and join with underscore\ntype SplitOnCapital<\n S extends string,\n Acc extends string = \"\",\n> = S extends `${infer Head}${infer Tail}`\n ? Head extends Uppercase<Head>\n ? Head extends Lowercase<Head>\n ? SplitOnCapital<Tail, `${Acc}${Head}`>\n : Acc extends \"\"\n ? SplitOnCapital<Tail, Head>\n : `${Acc}_${SplitOnCapital<Tail, Head>}`\n : SplitOnCapital<Tail, `${Acc}${Uppercase<Head>}`>\n : Acc;\n\n/**\n * Converts a tag name to an error code in CONSTANT_CASE.\n */\nexport type TagToCode<TTag extends string> = SplitOnCapital<TTag>;\n\n/**\n * Creates a tagged error class that combines Effect's YieldableError with ORPCError.\n *\n * This allows you to create errors that:\n * - Can be yielded in Effect generators (`yield* myError`)\n * - Have all ORPCError properties (code, status, data, defined)\n * - Can be converted to a plain ORPCError for oRPC handlers\n *\n * The returned factory function takes:\n * - `tag` - The unique tag for this error type (used for discriminated unions)\n * - `codeOrOptions` - Optional ORPC error code or options. If omitted, code defaults to CONSTANT_CASE of tag\n * - `defaultOptions` - Optional default options for status and message (when code is provided)\n *\n * @example\n * ```ts\n * import { ORPCTaggedError } from '@orpc/effect'\n * import { Effect } from 'effect'\n *\n * // Define a custom error (code defaults to 'USER_NOT_FOUND_ERROR')\n * class UserNotFoundError extends ORPCTaggedError<UserNotFoundError>()('UserNotFoundError') {}\n *\n * // With explicit code\n * class NotFoundError extends ORPCTaggedError<NotFoundError>()('NotFoundError', 'NOT_FOUND') {}\n *\n * // Use in an Effect\n * const getUser = (id: string) => Effect.gen(function* () {\n * const user = yield* findUser(id)\n * if (!user) {\n * return yield* new UserNotFoundError({ data: { userId: id } })\n * }\n * return user\n * })\n *\n * // With custom data type\n * class ValidationError extends ORPCTaggedError<ValidationError, { fields: string[] }>()('ValidationError', 'BAD_REQUEST') {}\n *\n * // With options only (code defaults to 'VALIDATION_ERROR')\n * class ValidationError2 extends ORPCTaggedError<ValidationError2, { fields: string[] }>()(\n * 'ValidationError2',\n * { message: 'Validation failed' }\n * ) {}\n * ```\n */\n/**\n * Return type for the factory function with overloads\n */\ninterface ORPCTaggedErrorFactory<Self, TData> {\n // Overload 1: tag only (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 2: tag + options (code defaults to CONSTANT_CASE of tag)\n <TTag extends string>(\n tag: TTag,\n options: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, options) {}\\``\n : ORPCTaggedErrorClass<TTag, TagToCode<TTag>, TData>;\n\n // Overload 3: tag + explicit code\n <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n code: TCode,\n defaultOptions?: { status?: number; message?: string },\n ): Types.Equals<Self, unknown> extends true\n ? `Missing \\`Self\\` generic - use \\`class MyError extends ORPCTaggedError<MyError>()(tag, code) {}\\``\n : ORPCTaggedErrorClass<TTag, TCode, TData>;\n}\n\nexport function ORPCTaggedError<\n Self,\n TData = undefined,\n>(): ORPCTaggedErrorFactory<Self, TData> {\n const factory = <TTag extends string, TCode extends ORPCErrorCode>(\n tag: TTag,\n codeOrOptions?: TCode | { status?: number; message?: string },\n defaultOptions?: { status?: number; message?: string },\n ): ORPCTaggedErrorClass<TTag, TCode, TData> => {\n // Determine if second arg is code or options\n const isCodeProvided = typeof codeOrOptions === \"string\";\n const code = (\n isCodeProvided ? codeOrOptions : toConstantCase(tag)\n ) as TCode;\n const options = isCodeProvided ? defaultOptions : codeOrOptions;\n\n const defaultStatus = options?.status;\n const defaultMessage = options?.message;\n\n // Use Effect's TaggedError as the base - this handles all Effect internals\n // (YieldableError, type symbols, commit(), Symbol.iterator, pipe(), etc.)\n const BaseTaggedError = Data.TaggedError(tag) as unknown as new (args: {\n message?: string;\n cause?: unknown;\n code: TCode;\n status: number;\n data: TData;\n defined: boolean;\n }) => Cause.YieldableError & {\n readonly _tag: TTag;\n readonly code: TCode;\n readonly status: number;\n readonly data: TData;\n readonly defined: boolean;\n };\n\n class ORPCTaggedErrorBase extends BaseTaggedError {\n static readonly _tag = tag;\n static readonly code = code;\n\n readonly [ORPCErrorSymbol]: ORPCError<TCode, TData>;\n\n constructor(\n ...rest: MaybeOptionalOptions<ORPCTaggedErrorOptions<TData>>\n ) {\n const opts = resolveMaybeOptionalOptions(rest);\n const status = opts.status ?? defaultStatus;\n const inputMessage = opts.message ?? defaultMessage;\n\n if (status !== undefined && !isORPCErrorStatus(status)) {\n throw new globalThis.Error(\n \"[ORPCTaggedError] Invalid error status code.\",\n );\n }\n\n const finalStatus = fallbackORPCErrorStatus(code, status);\n const finalMessage = fallbackORPCErrorMessage(code, inputMessage);\n\n // Pass to Effect's TaggedError - it spreads these onto the instance\n super({\n message: finalMessage,\n cause: opts.cause,\n code,\n status: finalStatus,\n data: opts.data as TData,\n defined: opts.defined ?? true,\n });\n\n // Create the underlying ORPCError for interop\n this[ORPCErrorSymbol] = new ORPCError(code, {\n status: finalStatus,\n message: finalMessage,\n data: opts.data as TData,\n defined: this.defined,\n cause: opts.cause,\n });\n }\n\n /**\n * Converts this error to a plain ORPCError.\n * Useful when you need to return from an oRPC handler.\n */\n toORPCError(): ORPCError<TCode, TData> {\n return this[ORPCErrorSymbol];\n }\n\n override toJSON(): ORPCErrorJSON<TCode, TData> & { _tag: TTag } {\n return {\n _tag: this._tag,\n defined: this.defined,\n code: this.code,\n status: this.status,\n message: this.message,\n data: this.data,\n };\n }\n }\n\n return ORPCTaggedErrorBase as any;\n };\n\n return factory as ORPCTaggedErrorFactory<Self, TData>;\n}\n\n/**\n * Converts an ORPCTaggedError to a plain ORPCError.\n * Useful in handlers that need to throw ORPCError.\n *\n * @example\n * ```ts\n * const handler = effectOs.effect(function* () {\n * const result = yield* someOperation.pipe(\n * Effect.catchTag('UserNotFoundError', (e) =>\n * Effect.fail(toORPCError(e))\n * )\n * )\n * return result\n * })\n * ```\n */\nexport function toORPCError<TCode extends ORPCErrorCode, TData>(\n error: ORPCTaggedErrorInstance<string, TCode, TData>,\n): ORPCError<TCode, TData> {\n return error[ORPCErrorSymbol];\n}\n\n// ============================================================================\n// Extended Error Map Types for Effect\n// ============================================================================\n\n/**\n * An item in the EffectErrorMap - can be either a traditional ErrorMapItem or an ORPCTaggedErrorClass\n */\nexport type EffectErrorMapItem =\n | ErrorMapItem<AnySchema>\n | AnyORPCTaggedErrorClass;\n\n/**\n * Extended error map that supports both traditional oRPC errors and ORPCTaggedError classes.\n *\n * @example\n * ```ts\n * const errorMap = {\n * // Traditional format\n * BAD_REQUEST: { status: 400, message: 'Bad request' },\n *\n * // Tagged error class reference\n * USER_NOT_FOUND: UserNotFoundError,\n * } satisfies EffectErrorMap\n * ```\n */\nexport type EffectErrorMap = {\n [key in ORPCErrorCode]?: EffectErrorMapItem;\n};\n\n/**\n * Merges two EffectErrorMaps, with the second map taking precedence.\n */\nexport type MergedEffectErrorMap<\n T1 extends EffectErrorMap,\n T2 extends EffectErrorMap,\n> = T1 & T2;\n\n/**\n * Extracts the instance type from an EffectErrorMapItem\n */\nexport type EffectErrorMapItemToInstance<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> = T extends AnyORPCTaggedErrorClass\n ? InstanceType<T>\n : T extends { data?: infer TData }\n ? ORPCError<TCode, TData>\n : ORPCError<TCode, unknown>;\n\n/**\n * Converts an EffectErrorMap to a union of error instances.\n */\nexport type EffectErrorMapToUnion<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorMapItemToInstance<K, T[K]>\n : never\n : never;\n}[keyof T];\n\n/**\n * Type for the error constructors available in Effect handlers.\n * For tagged errors, it's the class constructor itself.\n * For traditional errors, it's a function that creates ORPCError.\n */\nexport type EffectErrorConstructorMapItem<\n TCode extends ORPCErrorCode,\n T extends EffectErrorMapItem,\n> =\n T extends ORPCTaggedErrorClass<infer _TTag, TCode, infer TData>\n ? ORPCTaggedErrorClass<_TTag, TCode, TData>\n : T extends { data?: infer TData }\n ? (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<TData>\n >\n ) => ORPCError<TCode, TData>\n : (\n ...args: MaybeOptionalOptions<\n ORPCErrorConstructorMapItemOptions<unknown>\n >\n ) => ORPCError<TCode, unknown>;\n\n/**\n * Constructor map for EffectErrorMap - provides typed error constructors for handlers.\n */\nexport type EffectErrorConstructorMap<T extends EffectErrorMap> = {\n [K in keyof T]: K extends ORPCErrorCode\n ? T[K] extends EffectErrorMapItem\n ? EffectErrorConstructorMapItem<K, T[K]>\n : never\n : never;\n};\n\n/**\n * Creates an error constructor map from an EffectErrorMap.\n * Tagged error classes are passed through directly.\n * Traditional error items become ORPCError factory functions.\n */\nexport function createEffectErrorConstructorMap<T extends EffectErrorMap>(\n errors: T | undefined,\n): EffectErrorConstructorMap<T> {\n const target = errors ?? ({} as T);\n const proxy = new Proxy(target, {\n get(proxyTarget, code) {\n if (typeof code !== \"string\") {\n return Reflect.get(proxyTarget, code);\n }\n\n const config = target[code];\n\n // If it's a tagged error class, return it directly\n if (isORPCTaggedErrorClass(config)) {\n return config;\n }\n\n // Otherwise, create a factory function for ORPCError\n return (\n ...rest: MaybeOptionalOptions<\n Omit<ORPCErrorOptions<unknown>, \"defined\" | \"status\">\n >\n ) => {\n const options = resolveMaybeOptionalOptions(rest);\n return new ORPCError(code, {\n defined: Boolean(config),\n status: config?.status,\n message: options.message ?? config?.message,\n data: options.data,\n cause: options.cause,\n });\n };\n },\n });\n\n return proxy as EffectErrorConstructorMap<T>;\n}\n\n/**\n * Converts an EffectErrorMap to a standard oRPC ErrorMap for interop.\n * Tagged error classes are converted to their equivalent ErrorMapItem format.\n */\nexport function effectErrorMapToErrorMap<T extends EffectErrorMap>(\n errorMap: T | undefined,\n): ErrorMap {\n const result: ErrorMap = {};\n\n if (!errorMap) {\n return result;\n }\n\n for (const [code, ClassOrErrorItem] of Object.entries(errorMap)) {\n if (!ClassOrErrorItem) {\n continue;\n }\n\n if (isORPCTaggedErrorClass(ClassOrErrorItem)) {\n const error = new ClassOrErrorItem().toORPCError();\n\n // For tagged errors, we create a minimal entry\n // The actual validation will be handled by the tagged error class\n result[code] = {\n status: error.status,\n message: error.message,\n data: error.data,\n };\n } else {\n result[code] = ClassOrErrorItem;\n }\n }\n\n return result;\n}\n"],"mappings":";AAwBA;AAAA,EACE;AAAA,EACA,aAAAA;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,OACK;AACP;AAAA,EACE,iBAAAC;AAAA,EACA;AAAA,EACA,sBAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAS,OAAO,QAAQ,YAAY;;;ACXpC,SAAS,WAAW,kBAAkB;AACtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACpBP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mCAAmC;AAC5C,YAAY,UAAU;AAKf,IAAM,kBAAiC,uBAAO;AAAA,EACnD;AACF;AAkEO,SAAS,uBACd,OACkC;AAClC,SACE,OAAO,UAAU,cACjB,UAAU,SACV,UAAU,SACV,OAAO,MAAM,SAAS,YACtB,OAAO,MAAM,SAAS;AAE1B;AAKO,SAAS,kBACd,OACkE;AAClE,SACE,OAAO,UAAU,YAAY,UAAU,QAAQ,mBAAmB;AAEtE;AAMA,SAAS,eAAe,KAAqB;AAC3C,SAAO,IACJ,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,wBAAwB,OAAO,EACvC,YAAY;AACjB;AA6FO,SAAS,kBAGyB;AACvC,QAAM,UAAU,CACd,KACA,eACA,mBAC6C;AAE7C,UAAM,iBAAiB,OAAO,kBAAkB;AAChD,UAAM,OACJ,iBAAiB,gBAAgB,eAAe,GAAG;AAErD,UAAM,UAAU,iBAAiB,iBAAiB;AAElD,UAAM,gBAAgB,SAAS;AAC/B,UAAM,iBAAiB,SAAS;AAIhC,UAAM,kBAAuB,iBAAY,GAAG;AAAA,IAe5C,MAAM,4BAA4B,gBAAgB;AAAA,MAChD,OAAgB,OAAO;AAAA,MACvB,OAAgB,OAAO;AAAA,MAEvB,CAAU,eAAe;AAAA,MAEzB,eACK,MACH;AACA,cAAM,OAAO,4BAA4B,IAAI;AAC7C,cAAM,SAAS,KAAK,UAAU;AAC9B,cAAM,eAAe,KAAK,WAAW;AAErC,YAAI,WAAW,UAAa,CAAC,kBAAkB,MAAM,GAAG;AACtD,gBAAM,IAAI,WAAW;AAAA,YACnB;AAAA,UACF;AAAA,QACF;AAEA,cAAM,cAAc,wBAAwB,MAAM,MAAM;AACxD,cAAM,eAAe,yBAAyB,MAAM,YAAY;AAGhE,cAAM;AAAA,UACJ,SAAS;AAAA,UACT,OAAO,KAAK;AAAA,UACZ;AAAA,UACA,QAAQ;AAAA,UACR,MAAM,KAAK;AAAA,UACX,SAAS,KAAK,WAAW;AAAA,QAC3B,CAAC;AAGD,aAAK,eAAe,IAAI,IAAI,UAAU,MAAM;AAAA,UAC1C,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,MAAM,KAAK;AAAA,UACX,SAAS,KAAK;AAAA,UACd,OAAO,KAAK;AAAA,QACd,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,cAAuC;AACrC,eAAO,KAAK,eAAe;AAAA,MAC7B;AAAA,MAES,SAAuD;AAC9D,eAAO;AAAA,UACL,MAAM,KAAK;AAAA,UACX,SAAS,KAAK;AAAA,UACd,MAAM,KAAK;AAAA,UACX,QAAQ,KAAK;AAAA,UACb,SAAS,KAAK;AAAA,UACd,MAAM,KAAK;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAkBO,SAAS,YACd,OACyB;AACzB,SAAO,MAAM,eAAe;AAC9B;AAqGO,SAAS,gCACd,QAC8B;AAC9B,QAAM,SAAS,UAAW,CAAC;AAC3B,QAAM,QAAQ,IAAI,MAAM,QAAQ;AAAA,IAC9B,IAAI,aAAa,MAAM;AACrB,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,QAAQ,IAAI,aAAa,IAAI;AAAA,MACtC;AAEA,YAAM,SAAS,OAAO,IAAI;AAG1B,UAAI,uBAAuB,MAAM,GAAG;AAClC,eAAO;AAAA,MACT;AAGA,aAAO,IACF,SAGA;AACH,cAAM,UAAU,4BAA4B,IAAI;AAChD,eAAO,IAAI,UAAU,MAAM;AAAA,UACzB,SAAS,QAAQ,MAAM;AAAA,UACvB,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ,WAAW,QAAQ;AAAA,UACpC,MAAM,QAAQ;AAAA,UACd,OAAO,QAAQ;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAMO,SAAS,yBACd,UACU;AACV,QAAM,SAAmB,CAAC;AAE1B,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,aAAW,CAAC,MAAM,gBAAgB,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC/D,QAAI,CAAC,kBAAkB;AACrB;AAAA,IACF;AAEA,QAAI,uBAAuB,gBAAgB,GAAG;AAC5C,YAAM,QAAQ,IAAI,iBAAiB,EAAE,YAAY;AAIjD,aAAO,IAAI,IAAI;AAAA,QACb,QAAQ,MAAM;AAAA,QACd,SAAS,MAAM;AAAA,QACf,MAAM,MAAM;AAAA,MACd;AAAA,IACF,OAAO;AACL,aAAO,IAAI,IAAI;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AACT;;;AD9bO,IAAM,2BAAN,MAAM,kCASH,UAOR;AAAA,EAYA,YACE,KAUA;AACA,UAAM,GAAG;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OACE,QAUA;AACA,UAAM,oBAAoB,EAAE,GAAG,KAAK,OAAO,EAAE,gBAAgB,GAAG,OAAO;AACvE,WAAO,IAAI,0BAAyB;AAAA,MAClC,GAAG,KAAK,OAAO;AAAA,MACf,gBAAgB;AAAA,MAChB,UAAU,yBAAyB,iBAAiB;AAAA,IACtD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KACE,MAUA;AACA,WAAO,IAAI,0BAAyB;AAAA,MAClC,GAAG,KAAK,OAAO;AAAA,MACf,MAAM,UAAU,KAAK,OAAO,EAAE,MAAM,IAAI;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MACE,OAUA;AACA,WAAO,IAAI,0BAAyB;AAAA,MAClC,GAAG,KAAK,OAAO;AAAA,MACf,OAAO,WAAW,KAAK,OAAO,EAAE,OAAO,KAAK;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA,EAkEA,IACE,YACA,UACkE;AAClE,UAAM,SAAS,WACX,mBAAmB,UAAU,EAAE,SAAS,QAAQ,IAChD;AAEJ,WAAO,IAAI,0BAAyB;AAAA,MAClC,GAAG,KAAK,OAAO;AAAA,MACf,aAAa,cAAc,KAAK,OAAO,EAAE,aAAa,MAAM;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YACK,MAmBoE;AACvE,UAAM,SAKF,sBAAsB,MAAM,GAAG,IAAI;AAEvC,WAAO,IAAI,MAAM,QAAQ;AAAA,MACvB,KAAK,CAAC,QAAQ,QAAQ;AACpB,eAAO,QAAQ,IAAI,MAAM,GAAG,IACxB,QAAQ,IAAI,MAAM,GAAG,IACrB,QAAQ,IAAI,QAAQ,GAAG;AAAA,MAC7B;AAAA,MACA,KAAK,CAAC,QAAQ,QAAQ;AACpB,eAAO,QAAQ,IAAI,MAAM,GAAG,KAAK,QAAQ,IAAI,QAAQ,GAAG;AAAA,MAC1D;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cACK,MAmB8D;AACjE,UAAM,SAIF,uBAAuB,sBAAsB,MAAM,GAAG,IAAI,CAAC;AAE/D,WAAO,IAAI,MAAM,QAAQ;AAAA,MACvB,KAAK,CAAC,QAAQ,QAAQ;AACpB,eAAO,QAAQ,IAAI,MAAM,GAAG,IACxB,QAAQ,IAAI,MAAM,GAAG,IACrB,QAAQ,IAAI,QAAQ,GAAG;AAAA,MAC7B;AAAA,MACA,KAAK,CAAC,QAAQ,QAAQ;AACpB,eAAO,QAAQ,IAAI,MAAM,GAAG,KAAK,QAAQ,IAAI,QAAQ,GAAG;AAAA,MAC1D;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ADvSO,SAAS,oBAA8C;AAC5D,QAAM,mBAAmB;AAGzB,QAAM,QAAQ,iBAAiB;AAC/B,mBAAiB,kBAAkB;AACnC,QAAM,aAAa,IAAI,MAAM;AAC7B,mBAAiB,kBAAkB;AACnC,MAAI,QAAwB;AAC5B,SAAO,MAAM;AACX,QAAI,UAAU,OAAO;AACnB,aAAO;AAAA,IACT;AACA,QAAI,WAAW,UAAU,QAAW;AAClC,YAAM,QAAQ,WAAW,MAAM,MAAM,IAAI;AACzC,UAAI,MAAM,CAAC,MAAM,QAAW;AAC1B,gBAAQ,MAAM,CAAC,EAAE,KAAK;AACtB,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AA8FO,IAAM,gBAAN,MAAM,eASX;AAAA,EACA;AAAA,EASA,YACE,KAQA;AACA,SAAK,OAAO,IAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,OACE,QAUA;AACA,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG,KAAK,OAAO;AAAA,MACf,UAAU;AAAA,QACR,KAAK,OAAO,EAAE;AAAA,QACd,yBAAyB,MAAM;AAAA,MACjC;AAAA,MACA,gBAAgB;AAAA,QACd,GAAG,KAAK,OAAO,EAAE;AAAA,QACjB,GAAG;AAAA,MACL;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAgCA,IACE,YACA,UACuD;AACvD,UAAM,SAAS,WACXC,oBAAmB,UAAU,EAAE,SAAS,QAAQ,IAChD;AAEJ,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG,KAAK,OAAO;AAAA,MACf,aAAaC,eAAc,KAAK,OAAO,EAAE,aAAa,MAAM;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KACE,MAUA;AACA,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG,KAAK,OAAO;AAAA,MACf,MAAMC,WAAU,KAAK,OAAO,EAAE,MAAM,IAAI;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MACE,OAUA;AACA,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG,KAAK,OAAO;AAAA,MACf,OAAOC,YAAW,KAAK,OAAO,EAAE,OAAO,KAAK;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MACE,QAUA;AACA,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG,KAAK,OAAO;AAAA,MACf,aAAa;AAAA,MACb,sBACE;AAAA,QACE;AAAA,QACA,KAAK,OAAO,EAAE,OAAO;AAAA,MACvB,IAAI,KAAK,OAAO,EAAE,YAAY;AAAA,IAClC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OACE,QAUA;AACA,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG,KAAK,OAAO;AAAA,MACf,cAAc;AAAA,MACd,uBACE;AAAA,QACE;AAAA,QACA,KAAK,OAAO,EAAE,OAAO;AAAA,MACvB,IAAI,KAAK,OAAO,EAAE,YAAY;AAAA,IAClC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OACE,UAUA;AACA,WAAO,IAAI,eAAc;AAAA,MACvB,GAAG,KAAK,OAAO;AAAA,MACf,YAAY;AAAA,QACV,MAAM;AAAA,QACN,mBAAmB,kBAAkB;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OACE,UAiBA;AACA,UAAM,EAAE,SAAS,WAAW,IAAI,KAAK,OAAO;AAE5C,UAAM,2BAA2B,kBAAkB;AACnD,WAAO,IAAI,yBAAyB;AAAA,MAClC,GAAG,KAAK,OAAO;AAAA,MACf,SAAS,OAAO,SAAS;AACvB,cAAM,aAKF;AAAA,UACF,SAAS,KAAK;AAAA,UACd,OAAO,KAAK;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,WAAW,KAAK;AAAA,UAChB,QAAQ,KAAK;AAAA,UACb,aAAa,KAAK;AAAA,UAClB,QAAQ,gCAAgC,KAAK,OAAO,EAAE,cAAc;AAAA,QACtE;AACA,cAAM,WAAW,YAAY,QAAQ,KAAK,KAAK,KAAK,GAAG;AACvD,cAAM,oBACJ,YAAY,qBAAqB;AACnC,cAAM,WAAW,OAAO,WAAW,QAAQ;AAC3C,cAAM,eAAe,OAAO,SAAS,SAAS,UAAU,GAAG,UAAU;AAAA,UACnE;AAAA,QACF,CAAC;AACD,cAAM,OAAO,MAAM,QAAQ,eAAe,cAAc;AAAA,UACtD,QAAQ,KAAK;AAAA,QACf,CAAC;AAED,YAAI,KAAK,UAAU,IAAI,GAAG;AACxB,gBAAM,MAAM,MAAM,KAAK,OAAO;AAAA,YAC5B,MAAM,QAAQ;AACZ,qBAAO,IAAIC,WAAU,yBAAyB;AAAA,gBAC5C,OAAO;AAAA,cACT,CAAC;AAAA,YACH;AAAA,YACA,OAAO,OAAO;AACZ,kBAAI,kBAAkB,KAAK,GAAG;AAC5B,uBAAO,MAAM,YAAY;AAAA,cAC3B;AACA,kBAAI,iBAAiBA,YAAW;AAC9B,uBAAO;AAAA,cACT;AACA,qBAAO,IAAIA,WAAU,yBAAyB;AAAA,gBAC5C,OAAO;AAAA,cACT,CAAC;AAAA,YACH;AAAA,YACA,YAAY,SAAS;AACnB,qBAAO,IAAIA,WAAU,yBAAyB;AAAA,gBAC5C,OAAO,IAAI,MAAM,GAAG,OAAO,cAAc;AAAA,cAC3C,CAAC;AAAA,YACH;AAAA,YACA,aAAa,MAAM;AACjB,qBAAO;AAAA,YACT;AAAA,YACA,SAAS,IAAIA,WAAU,yBAAyB;AAAA,cAC9C,OAAO,IAAI,MAAM,eAAe;AAAA,YAClC,CAAC;AAAA,YACD,WAAW,MAAM;AACf,qBAAO;AAAA,YACT;AAAA,UACF,CAAC;AAAA,QACH;AAEA,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAkGO,SAAS,eAQd,SACA,SAUA;AACA,QAAM,kBACJ,WAAW,aAA4D;AACzE,SAAO,IAAI,cAAc;AAAA,IACvB,GAAG,gBAAgB,OAAO;AAAA,IAC1B,gBAAgB,gBAAgB,OAAO,EAAE;AAAA,IACzC;AAAA,EACF,CAAC;AACH;AAEA,SAAS,eAKL;AACF,SAAO,IAAI,QAOT;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,MAAM,CAAC;AAAA,IACP,UAAU,CAAC;AAAA,IACX,sBAAsB,eAAe,6BAA6B;AAAA,IAClE,uBAAuB,eAAe,8BAA8B;AAAA,IACpE,aAAa,CAAC;AAAA,IACd,0BAA0B;AAAA,EAC5B,CAAC;AACH;","names":["mergeMeta","mergeRoute","ORPCError","addMiddleware","decorateMiddleware","decorateMiddleware","addMiddleware","mergeMeta","mergeRoute","ORPCError"]}
|
package/package.json
CHANGED
package/src/effect-builder.ts
CHANGED
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
} from "@orpc/server";
|
|
21
21
|
import type { IntersectPick } from "@orpc/shared";
|
|
22
22
|
import type { ManagedRuntime } from "effect";
|
|
23
|
+
import type { YieldWrap } from "effect/Utils";
|
|
23
24
|
|
|
24
25
|
import {
|
|
25
26
|
mergeErrorMap,
|
|
@@ -130,10 +131,17 @@ export type EffectProcedureHandler<
|
|
|
130
131
|
TEffectErrorMap,
|
|
131
132
|
TMeta
|
|
132
133
|
>,
|
|
133
|
-
) =>
|
|
134
|
+
) => Generator<
|
|
135
|
+
YieldWrap<
|
|
136
|
+
Effect.Effect<
|
|
137
|
+
any,
|
|
138
|
+
| EffectErrorMapToUnion<TEffectErrorMap>
|
|
139
|
+
| ORPCError<ORPCErrorCode, unknown>,
|
|
140
|
+
TRequirementsProvided
|
|
141
|
+
>
|
|
142
|
+
>,
|
|
134
143
|
THandlerOutput,
|
|
135
|
-
|
|
136
|
-
TRequirementsProvided
|
|
144
|
+
never
|
|
137
145
|
>;
|
|
138
146
|
|
|
139
147
|
/**
|
|
@@ -477,11 +485,11 @@ export class EffectBuilder<
|
|
|
477
485
|
lastEventId: opts.lastEventId,
|
|
478
486
|
errors: createEffectErrorConstructorMap(this["~orpc"].effectErrorMap),
|
|
479
487
|
};
|
|
480
|
-
const baseEffect = effectFn(effectOpts);
|
|
481
488
|
const spanName = spanConfig?.name ?? opts.path.join(".");
|
|
482
489
|
const captureStackTrace =
|
|
483
490
|
spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;
|
|
484
|
-
const
|
|
491
|
+
const resolver = Effect.fnUntraced(effectFn);
|
|
492
|
+
const tracedEffect = Effect.withSpan(resolver(effectOpts), spanName, {
|
|
485
493
|
captureStackTrace,
|
|
486
494
|
});
|
|
487
495
|
const exit = await runtime.runPromiseExit(tracedEffect, {
|
|
@@ -122,7 +122,10 @@ describe("effectBuilder", () => {
|
|
|
122
122
|
});
|
|
123
123
|
|
|
124
124
|
it(".effect", () => {
|
|
125
|
-
|
|
125
|
+
// oxlint-disable-next-line require-yield
|
|
126
|
+
const effectFn = vi.fn(function* () {
|
|
127
|
+
return { result: "test" };
|
|
128
|
+
});
|
|
126
129
|
const applied = builder.effect(effectFn);
|
|
127
130
|
|
|
128
131
|
expect(applied).instanceOf(EffectDecoratedProcedure);
|
|
@@ -131,9 +134,10 @@ describe("effectBuilder", () => {
|
|
|
131
134
|
});
|
|
132
135
|
|
|
133
136
|
it(".effect runs effect with runtime", async () => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
// oxlint-disable-next-line require-yield
|
|
138
|
+
const effectFn = vi.fn(function* ({ input }: { input: any }) {
|
|
139
|
+
return { output: `processed-${input}` };
|
|
140
|
+
});
|
|
137
141
|
|
|
138
142
|
const applied = builder.effect(effectFn);
|
|
139
143
|
|
|
@@ -175,7 +179,10 @@ describe("makeEffectORPC factory", () => {
|
|
|
175
179
|
it("creates working procedure with default os", async () => {
|
|
176
180
|
const effectBuilder = makeEffectORPC(runtime);
|
|
177
181
|
|
|
178
|
-
|
|
182
|
+
// oxlint-disable-next-line require-yield
|
|
183
|
+
const procedure = effectBuilder.effect(function* () {
|
|
184
|
+
return "hello";
|
|
185
|
+
});
|
|
179
186
|
|
|
180
187
|
const result = await procedure["~orpc"].handler({
|
|
181
188
|
context: {},
|
|
@@ -193,13 +200,12 @@ describe("makeEffectORPC factory", () => {
|
|
|
193
200
|
it("supports Effect.fn generator syntax", async () => {
|
|
194
201
|
const effectBuilder = makeEffectORPC(runtime);
|
|
195
202
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
203
|
+
// oxlint-disable-next-line require-yield
|
|
204
|
+
const procedure = effectBuilder.effect(function* () {
|
|
205
|
+
const a = yield* Effect.succeed(1);
|
|
206
|
+
const b = yield* Effect.succeed(2);
|
|
207
|
+
return a + b;
|
|
208
|
+
});
|
|
203
209
|
|
|
204
210
|
const result = await procedure["~orpc"].handler({
|
|
205
211
|
context: {},
|
|
@@ -223,7 +229,10 @@ describe("makeEffectORPC factory", () => {
|
|
|
223
229
|
.route({ path: "/test" })
|
|
224
230
|
.input(z.object({ id: z.string() }))
|
|
225
231
|
.output(z.object({ name: z.string() }))
|
|
226
|
-
|
|
232
|
+
// oxlint-disable-next-line require-yield
|
|
233
|
+
.effect(function* () {
|
|
234
|
+
return { name: "test" };
|
|
235
|
+
});
|
|
227
236
|
|
|
228
237
|
expect(procedure).instanceOf(EffectDecoratedProcedure);
|
|
229
238
|
expect(procedure["~orpc"].errorMap).toHaveProperty("NOT_FOUND");
|
|
@@ -262,12 +271,13 @@ describe("effect with services", () => {
|
|
|
262
271
|
const serviceRuntime = ManagedRuntime.make(CounterLive);
|
|
263
272
|
const effectBuilder = makeEffectORPC(serviceRuntime);
|
|
264
273
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
274
|
+
// oxlint-disable-next-line require-yield
|
|
275
|
+
const procedure = effectBuilder.input(z.number()).effect(function* ({
|
|
276
|
+
input,
|
|
277
|
+
}) {
|
|
278
|
+
const counter = yield* Counter;
|
|
279
|
+
return yield* counter.increment(input as number);
|
|
280
|
+
});
|
|
271
281
|
|
|
272
282
|
const result = await procedure["~orpc"].handler({
|
|
273
283
|
context: {},
|
|
@@ -307,7 +317,10 @@ describe(".traced", () => {
|
|
|
307
317
|
const procedure = effectBuilder
|
|
308
318
|
.input(z.object({ id: z.string() }))
|
|
309
319
|
.traced("users.getUser")
|
|
310
|
-
|
|
320
|
+
// oxlint-disable-next-line require-yield
|
|
321
|
+
.effect(function* () {
|
|
322
|
+
return { name: "test" };
|
|
323
|
+
});
|
|
311
324
|
|
|
312
325
|
expect(procedure).instanceOf(EffectDecoratedProcedure);
|
|
313
326
|
// The span wrapping happens in the handler, so we just verify the procedure was created
|
|
@@ -319,7 +332,10 @@ describe(".traced", () => {
|
|
|
319
332
|
const procedure = effectBuilder
|
|
320
333
|
.input(z.object({ id: z.string() }))
|
|
321
334
|
.traced("users.getUser")
|
|
322
|
-
|
|
335
|
+
// oxlint-disable-next-line require-yield
|
|
336
|
+
.effect(function* ({ input }) {
|
|
337
|
+
return { id: input.id, name: "Alice" };
|
|
338
|
+
});
|
|
323
339
|
|
|
324
340
|
const result = await procedure["~orpc"].handler({
|
|
325
341
|
context: {},
|
|
@@ -337,13 +353,11 @@ describe(".traced", () => {
|
|
|
337
353
|
it("traced procedure with Effect.fn generator syntax", async () => {
|
|
338
354
|
const effectBuilder = makeEffectORPC(runtime);
|
|
339
355
|
|
|
340
|
-
const procedure = effectBuilder.traced("math.add").effect(
|
|
341
|
-
Effect.
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}),
|
|
346
|
-
);
|
|
356
|
+
const procedure = effectBuilder.traced("math.add").effect(function* () {
|
|
357
|
+
const a = yield* Effect.succeed(10);
|
|
358
|
+
const b = yield* Effect.succeed(20);
|
|
359
|
+
return a + b;
|
|
360
|
+
});
|
|
347
361
|
|
|
348
362
|
const result = await procedure["~orpc"].handler({
|
|
349
363
|
context: {},
|
|
@@ -380,7 +394,10 @@ describe("default tracing (without .traced())", () => {
|
|
|
380
394
|
// No .traced() call - should still work and use path as span name
|
|
381
395
|
const procedure = effectBuilder
|
|
382
396
|
.input(z.object({ id: z.string() }))
|
|
383
|
-
|
|
397
|
+
// oxlint-disable-next-line require-yield
|
|
398
|
+
.effect(function* ({ input }) {
|
|
399
|
+
return { id: input.id, name: "Bob" };
|
|
400
|
+
});
|
|
384
401
|
|
|
385
402
|
const result = await procedure["~orpc"].handler({
|
|
386
403
|
context: {},
|
|
@@ -399,7 +416,10 @@ describe("default tracing (without .traced())", () => {
|
|
|
399
416
|
const effectBuilder = makeEffectORPC(runtime);
|
|
400
417
|
|
|
401
418
|
// Without .traced(), the span name should be derived from path
|
|
402
|
-
|
|
419
|
+
// oxlint-disable-next-line require-yield
|
|
420
|
+
const procedure = effectBuilder.effect(function* () {
|
|
421
|
+
return "hello";
|
|
422
|
+
});
|
|
403
423
|
|
|
404
424
|
// The procedure should work with any path
|
|
405
425
|
const result = await procedure["~orpc"].handler({
|
|
@@ -419,11 +439,12 @@ describe("default tracing (without .traced())", () => {
|
|
|
419
439
|
const effectBuilder = makeEffectORPC(runtime);
|
|
420
440
|
|
|
421
441
|
const procedure = effectBuilder.effect(
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const
|
|
442
|
+
// oxlint-disable-next-line require-yield
|
|
443
|
+
function* () {
|
|
444
|
+
const x = 5;
|
|
445
|
+
const y = 10;
|
|
425
446
|
return x * y;
|
|
426
|
-
}
|
|
447
|
+
},
|
|
427
448
|
);
|
|
428
449
|
|
|
429
450
|
const result = await procedure["~orpc"].handler({
|
|
@@ -454,12 +475,9 @@ describe("default tracing (without .traced())", () => {
|
|
|
454
475
|
|
|
455
476
|
const procedure = effectBuilder
|
|
456
477
|
.input(z.object({ name: z.string() }))
|
|
457
|
-
.effect(
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
return yield* greeter.greet(input.name);
|
|
461
|
-
}),
|
|
462
|
-
);
|
|
478
|
+
.effect(function* ({ input }) {
|
|
479
|
+
return yield* Greeter.greet(input.name);
|
|
480
|
+
});
|
|
463
481
|
|
|
464
482
|
const result = await procedure["~orpc"].handler({
|
|
465
483
|
context: {},
|
|
@@ -228,7 +228,8 @@ describe("effectBuilder with EffectErrorMap", () => {
|
|
|
228
228
|
BAD_REQUEST: { status: 400 },
|
|
229
229
|
})
|
|
230
230
|
.input(z.object({ id: z.string() }))
|
|
231
|
-
|
|
231
|
+
// oxlint-disable-next-line require-yield
|
|
232
|
+
.effect(function* ({ input, errors }) {
|
|
232
233
|
// errors.USER_NOT_FOUND_ERROR is the class
|
|
233
234
|
expect(errors.USER_NOT_FOUND_ERROR).toBe(UserNotFoundError);
|
|
234
235
|
|
|
@@ -249,11 +250,12 @@ describe("effectBuilder with EffectErrorMap", () => {
|
|
|
249
250
|
USER_NOT_FOUND_ERROR: UserNotFoundError,
|
|
250
251
|
})
|
|
251
252
|
.input(z.object({ id: z.string() }))
|
|
252
|
-
|
|
253
|
+
// oxlint-disable-next-line require-yield
|
|
254
|
+
.effect(function* ({ input, errors }) {
|
|
253
255
|
if (input.id === "not-found") {
|
|
254
|
-
return Effect.fail(new errors.USER_NOT_FOUND_ERROR());
|
|
256
|
+
return yield* Effect.fail(new errors.USER_NOT_FOUND_ERROR());
|
|
255
257
|
}
|
|
256
|
-
return Effect.succeed({ id: input.id, name: "Test User" });
|
|
258
|
+
return yield* Effect.succeed({ id: input.id, name: "Test User" });
|
|
257
259
|
});
|
|
258
260
|
|
|
259
261
|
// Test successful case
|
|
@@ -290,7 +292,10 @@ describe("effectDecoratedProcedure.errors()", () => {
|
|
|
290
292
|
it("should support adding errors to procedure", () => {
|
|
291
293
|
const procedure = effectOs
|
|
292
294
|
.input(z.object({ id: z.string() }))
|
|
293
|
-
|
|
295
|
+
// oxlint-disable-next-line require-yield
|
|
296
|
+
.effect(function* ({ input }) {
|
|
297
|
+
return { id: input.id };
|
|
298
|
+
})
|
|
294
299
|
.errors({ USER_NOT_FOUND_ERROR: UserNotFoundError });
|
|
295
300
|
|
|
296
301
|
expect(procedure["~orpc"].effectErrorMap.USER_NOT_FOUND_ERROR).toBe(
|
|
@@ -302,7 +307,10 @@ describe("effectDecoratedProcedure.errors()", () => {
|
|
|
302
307
|
const procedure = effectOs
|
|
303
308
|
.errors({ BAD_REQUEST: { status: 400 } })
|
|
304
309
|
.input(z.object({ id: z.string() }))
|
|
305
|
-
|
|
310
|
+
// oxlint-disable-next-line require-yield
|
|
311
|
+
.effect(function* ({ input }) {
|
|
312
|
+
return { id: input.id };
|
|
313
|
+
})
|
|
306
314
|
.errors({ USER_NOT_FOUND_ERROR: UserNotFoundError });
|
|
307
315
|
|
|
308
316
|
expect(procedure["~orpc"].effectErrorMap).toEqual({
|