effect-orpc 0.1.4 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/dist/index.js +806 -476
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/contract.ts +491 -0
- package/src/effect-builder.ts +349 -619
- package/src/effect-enhance-router.ts +20 -21
- package/src/effect-procedure.ts +274 -263
- package/src/effect-runtime.ts +134 -0
- package/src/eoc.ts +499 -0
- package/src/extension/compose-surfaces.ts +15 -0
- package/src/extension/create-node-proxy.ts +270 -0
- package/src/extension/state.ts +108 -0
- package/src/index.ts +20 -3
- package/src/tagged-error.ts +24 -4
- package/src/tests/contract.test.ts +346 -0
- package/src/tests/effect-builder.proxy.test.ts +253 -0
- package/src/tests/effect-error-map.test.ts +22 -3
- package/src/tests/parity-shared.ts +32 -0
- package/src/tests/parity.contract-builder-variants.test.ts +192 -0
- package/src/tests/parity.contract-builder.test.ts +222 -0
- package/src/tests/parity.effect-builder.test.ts +210 -0
- package/src/tests/parity.effect-procedure.test.ts +124 -0
- package/src/tests/parity.implementer-variants.test.ts +249 -0
- package/src/tests/parity.implementer.test.ts +280 -0
- package/src/tests/shared.ts +2 -0
- package/src/types/effect-builder-surface.ts +441 -0
- package/src/types/effect-procedure-surface.ts +243 -0
- package/src/types/index.ts +22 -26
- package/src/types/variants.ts +100 -16
package/src/effect-builder.ts
CHANGED
|
@@ -2,66 +2,32 @@ import type {
|
|
|
2
2
|
AnySchema,
|
|
3
3
|
ContractRouter,
|
|
4
4
|
ErrorMap,
|
|
5
|
-
HTTPPath,
|
|
6
|
-
InferSchemaOutput,
|
|
7
5
|
Meta,
|
|
8
|
-
Route,
|
|
9
6
|
Schema,
|
|
10
7
|
} from "@orpc/contract";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
mergePrefix,
|
|
14
|
-
mergeRoute,
|
|
15
|
-
mergeTags,
|
|
16
|
-
ORPCError,
|
|
17
|
-
} from "@orpc/contract";
|
|
18
|
-
import type {
|
|
19
|
-
AnyMiddleware,
|
|
20
|
-
BuilderConfig,
|
|
21
|
-
BuilderDef,
|
|
22
|
-
Context,
|
|
23
|
-
Lazy,
|
|
24
|
-
MapInputMiddleware,
|
|
25
|
-
MergedCurrentContext,
|
|
26
|
-
MergedInitialContext,
|
|
27
|
-
Middleware,
|
|
28
|
-
ProcedureHandler,
|
|
29
|
-
ProcedureHandlerOptions,
|
|
30
|
-
Router,
|
|
31
|
-
} from "@orpc/server";
|
|
32
|
-
import {
|
|
33
|
-
addMiddleware,
|
|
34
|
-
Builder,
|
|
35
|
-
decorateMiddleware,
|
|
36
|
-
fallbackConfig,
|
|
37
|
-
lazy,
|
|
38
|
-
} from "@orpc/server";
|
|
39
|
-
import type { IntersectPick } from "@orpc/shared";
|
|
8
|
+
import type { Context, Router } from "@orpc/server";
|
|
9
|
+
import { Builder, fallbackConfig, lazy } from "@orpc/server";
|
|
40
10
|
import type { ManagedRuntime } from "effect";
|
|
41
|
-
import { Cause, Effect, Exit, FiberRefs } from "effect";
|
|
42
11
|
|
|
43
12
|
import { enhanceEffectRouter } from "./effect-enhance-router";
|
|
44
13
|
import { EffectDecoratedProcedure } from "./effect-procedure";
|
|
45
|
-
import {
|
|
46
|
-
import
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} from "./
|
|
14
|
+
import { createEffectProcedureHandler } from "./effect-runtime";
|
|
15
|
+
import {
|
|
16
|
+
createNodeProxy,
|
|
17
|
+
unhandled,
|
|
18
|
+
type NodeProxyContext,
|
|
19
|
+
} from "./extension/create-node-proxy";
|
|
51
20
|
import {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
21
|
+
attachEffectState,
|
|
22
|
+
getEffectErrorMap,
|
|
23
|
+
unwrapEffectUpstream,
|
|
24
|
+
type EffectProxyTarget,
|
|
25
|
+
} from "./extension/state";
|
|
26
|
+
import type { EffectErrorMap, MergedEffectErrorMap } from "./tagged-error";
|
|
27
|
+
import { effectErrorMapToErrorMap } from "./tagged-error";
|
|
56
28
|
import type {
|
|
57
29
|
AnyBuilderLike,
|
|
58
30
|
EffectBuilderDef,
|
|
59
|
-
EffectErrorMapToErrorMap,
|
|
60
|
-
EffectProcedureBuilderWithInput,
|
|
61
|
-
EffectProcedureBuilderWithOutput,
|
|
62
|
-
EffectProcedureHandler,
|
|
63
|
-
EffectRouterBuilder,
|
|
64
|
-
EnhancedEffectRouter,
|
|
65
31
|
InferBuilderCurrentContext,
|
|
66
32
|
InferBuilderErrorMap,
|
|
67
33
|
InferBuilderInitialContext,
|
|
@@ -69,12 +35,215 @@ import type {
|
|
|
69
35
|
InferBuilderMeta,
|
|
70
36
|
InferBuilderOutputSchema,
|
|
71
37
|
} from "./types";
|
|
38
|
+
import type { EffectBuilderSurface } from "./types/effect-builder-surface";
|
|
39
|
+
|
|
40
|
+
const builderVirtualDescriptors = {
|
|
41
|
+
"~effect": { enumerable: true },
|
|
42
|
+
effect: { enumerable: false },
|
|
43
|
+
errors: { enumerable: false },
|
|
44
|
+
handler: { enumerable: false },
|
|
45
|
+
lazy: { enumerable: false },
|
|
46
|
+
router: { enumerable: false },
|
|
47
|
+
traced: { enumerable: false },
|
|
48
|
+
} as const;
|
|
49
|
+
|
|
50
|
+
const builderVirtualKeys = [
|
|
51
|
+
"~effect",
|
|
52
|
+
"errors",
|
|
53
|
+
"effect",
|
|
54
|
+
"traced",
|
|
55
|
+
"handler",
|
|
56
|
+
"router",
|
|
57
|
+
"lazy",
|
|
58
|
+
] as const;
|
|
59
|
+
|
|
60
|
+
type EffectBuilderTarget = EffectBuilder<
|
|
61
|
+
any,
|
|
62
|
+
any,
|
|
63
|
+
any,
|
|
64
|
+
any,
|
|
65
|
+
any,
|
|
66
|
+
any,
|
|
67
|
+
any,
|
|
68
|
+
any
|
|
69
|
+
> &
|
|
70
|
+
EffectProxyTarget<AnyBuilderLike>;
|
|
71
|
+
|
|
72
|
+
function isBuilderLike(value: unknown): value is AnyBuilderLike {
|
|
73
|
+
return typeof value === "object" && value !== null && "~orpc" in value;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getOrCreateVirtualMethod<T>(
|
|
77
|
+
context: NodeProxyContext<EffectBuilderTarget, AnyBuilderLike>,
|
|
78
|
+
prop: PropertyKey,
|
|
79
|
+
factory: () => T,
|
|
80
|
+
): T {
|
|
81
|
+
const cache = context.methodCache;
|
|
82
|
+
if (cache.has(prop)) {
|
|
83
|
+
return cache.get(prop) as T;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const value = factory();
|
|
87
|
+
cache.set(prop, value);
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getEffectBuilderDef(
|
|
92
|
+
context: NodeProxyContext<EffectBuilderTarget, AnyBuilderLike>,
|
|
93
|
+
): EffectBuilderDef<any, any, any, any, any, any> {
|
|
94
|
+
return {
|
|
95
|
+
...context.upstream["~orpc"],
|
|
96
|
+
effectErrorMap: context.state.effectErrorMap,
|
|
97
|
+
runtime: context.state.runtime,
|
|
98
|
+
spanConfig: context.state.spanConfig,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function wrapBuilderLike(
|
|
103
|
+
builder: AnyBuilderLike,
|
|
104
|
+
state: NodeProxyContext<EffectBuilderTarget, AnyBuilderLike>["state"],
|
|
105
|
+
): EffectBuilder<any, any, any, any, any, any, any, any> {
|
|
106
|
+
return new EffectBuilder(
|
|
107
|
+
{
|
|
108
|
+
...builder["~orpc"],
|
|
109
|
+
effectErrorMap: state.effectErrorMap,
|
|
110
|
+
runtime: state.runtime,
|
|
111
|
+
spanConfig: state.spanConfig,
|
|
112
|
+
},
|
|
113
|
+
unwrapEffectUpstream(builder),
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function createEffectBuilderProxy(
|
|
118
|
+
target: EffectBuilderTarget,
|
|
119
|
+
): EffectBuilderTarget {
|
|
120
|
+
return createNodeProxy<EffectBuilderTarget, AnyBuilderLike>(target, {
|
|
121
|
+
getVirtual(context, prop) {
|
|
122
|
+
const effectDef = getEffectBuilderDef(context);
|
|
123
|
+
if (prop === "~effect") {
|
|
124
|
+
return getEffectBuilderDef(context);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const { upstream: source, state } = context;
|
|
128
|
+
|
|
129
|
+
switch (prop) {
|
|
130
|
+
case "errors":
|
|
131
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
132
|
+
return <U extends EffectErrorMap>(errors: U) => {
|
|
133
|
+
const nextEffectErrorMap: MergedEffectErrorMap<
|
|
134
|
+
typeof state.effectErrorMap,
|
|
135
|
+
U
|
|
136
|
+
> = {
|
|
137
|
+
...state.effectErrorMap,
|
|
138
|
+
...errors,
|
|
139
|
+
};
|
|
140
|
+
const nextBuilder: AnyBuilderLike = Reflect.apply(
|
|
141
|
+
Reflect.get(source, "errors", source),
|
|
142
|
+
source,
|
|
143
|
+
[effectErrorMapToErrorMap(errors)],
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
return wrapBuilderLike(nextBuilder, {
|
|
147
|
+
...state,
|
|
148
|
+
effectErrorMap: nextEffectErrorMap,
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
case "effect":
|
|
153
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
154
|
+
return (
|
|
155
|
+
effectFn: Parameters<
|
|
156
|
+
EffectBuilderSurface<
|
|
157
|
+
any,
|
|
158
|
+
any,
|
|
159
|
+
any,
|
|
160
|
+
any,
|
|
161
|
+
any,
|
|
162
|
+
any,
|
|
163
|
+
any,
|
|
164
|
+
any
|
|
165
|
+
>["effect"]
|
|
166
|
+
>[0],
|
|
167
|
+
) => {
|
|
168
|
+
const defaultCaptureStackTrace = addSpanStackTrace();
|
|
169
|
+
return new EffectDecoratedProcedure({
|
|
170
|
+
...effectDef,
|
|
171
|
+
handler: async (opts) => {
|
|
172
|
+
return createEffectProcedureHandler({
|
|
173
|
+
defaultCaptureStackTrace,
|
|
174
|
+
effectErrorMap: state.effectErrorMap,
|
|
175
|
+
effectFn,
|
|
176
|
+
runtime: state.runtime,
|
|
177
|
+
spanConfig: state.spanConfig,
|
|
178
|
+
})(opts as any);
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
case "traced":
|
|
184
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
185
|
+
return (spanName: string) =>
|
|
186
|
+
wrapBuilderLike(source, {
|
|
187
|
+
...state,
|
|
188
|
+
spanConfig: {
|
|
189
|
+
captureStackTrace: addSpanStackTrace(),
|
|
190
|
+
name: spanName,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
case "handler":
|
|
195
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
196
|
+
return (
|
|
197
|
+
handler: Parameters<
|
|
198
|
+
EffectBuilderSurface<
|
|
199
|
+
any,
|
|
200
|
+
any,
|
|
201
|
+
any,
|
|
202
|
+
any,
|
|
203
|
+
any,
|
|
204
|
+
any,
|
|
205
|
+
any,
|
|
206
|
+
any
|
|
207
|
+
>["handler"]
|
|
208
|
+
>[0],
|
|
209
|
+
) =>
|
|
210
|
+
new EffectDecoratedProcedure({
|
|
211
|
+
...effectDef,
|
|
212
|
+
handler,
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
case "router":
|
|
216
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
217
|
+
return (router: Router<ContractRouter<any>, any>) =>
|
|
218
|
+
enhanceEffectRouter(router, effectDef) as any;
|
|
219
|
+
});
|
|
220
|
+
case "lazy":
|
|
221
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
222
|
+
return (
|
|
223
|
+
loader: () => Promise<{
|
|
224
|
+
default: Router<ContractRouter<any>, any>;
|
|
225
|
+
}>,
|
|
226
|
+
) => enhanceEffectRouter(lazy(loader), effectDef) as any;
|
|
227
|
+
});
|
|
228
|
+
default:
|
|
229
|
+
return unhandled();
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
virtualDescriptors: builderVirtualDescriptors,
|
|
233
|
+
virtualKeys: builderVirtualKeys,
|
|
234
|
+
wrapResult(context, _prop, result) {
|
|
235
|
+
if (!isBuilderLike(result)) {
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return wrapBuilderLike(result, context.state);
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
}
|
|
72
243
|
|
|
73
244
|
/**
|
|
74
245
|
* Captures the stack trace at the call site for better error reporting in spans.
|
|
75
246
|
* This is called at procedure definition time to capture where the procedure was defined.
|
|
76
|
-
*
|
|
77
|
-
* @returns A function that lazily extracts the relevant stack frame
|
|
78
247
|
*/
|
|
79
248
|
export function addSpanStackTrace(): () => string | undefined {
|
|
80
249
|
const ErrorConstructor = Error as typeof Error & {
|
|
@@ -113,49 +282,37 @@ export class EffectBuilder<
|
|
|
113
282
|
TMeta extends Meta,
|
|
114
283
|
TRequirementsProvided,
|
|
115
284
|
TRuntimeError,
|
|
285
|
+
> implements EffectBuilderSurface<
|
|
286
|
+
TInitialContext,
|
|
287
|
+
TCurrentContext,
|
|
288
|
+
TInputSchema,
|
|
289
|
+
TOutputSchema,
|
|
290
|
+
TEffectErrorMap,
|
|
291
|
+
TMeta,
|
|
292
|
+
TRequirementsProvided,
|
|
293
|
+
TRuntimeError
|
|
116
294
|
> {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
declare "~effect": EffectBuilderDef<
|
|
295
|
+
declare $config: EffectBuilderSurface<
|
|
296
|
+
TInitialContext,
|
|
297
|
+
TCurrentContext,
|
|
121
298
|
TInputSchema,
|
|
122
299
|
TOutputSchema,
|
|
123
300
|
TEffectErrorMap,
|
|
124
301
|
TMeta,
|
|
125
302
|
TRequirementsProvided,
|
|
126
303
|
TRuntimeError
|
|
127
|
-
|
|
128
|
-
declare
|
|
304
|
+
>["$config"];
|
|
305
|
+
declare $context: EffectBuilderSurface<
|
|
306
|
+
TInitialContext,
|
|
307
|
+
TCurrentContext,
|
|
129
308
|
TInputSchema,
|
|
130
309
|
TOutputSchema,
|
|
131
|
-
|
|
132
|
-
TMeta
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
TInputSchema,
|
|
138
|
-
TOutputSchema,
|
|
139
|
-
TEffectErrorMap,
|
|
140
|
-
TMeta,
|
|
141
|
-
TRequirementsProvided,
|
|
142
|
-
TRuntimeError
|
|
143
|
-
>,
|
|
144
|
-
) {
|
|
145
|
-
const { runtime, spanConfig, effectErrorMap, ...orpcDef } = def;
|
|
146
|
-
this["~orpc"] = orpcDef;
|
|
147
|
-
this["~effect"] = { runtime, spanConfig, effectErrorMap, ...orpcDef };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Sets or overrides the config.
|
|
152
|
-
*
|
|
153
|
-
* @see {@link https://orpc.dev/docs/client/server-side#middlewares-order Middlewares Order Docs}
|
|
154
|
-
* @see {@link https://orpc.dev/docs/best-practices/dedupe-middleware#configuration Dedupe Middleware Docs}
|
|
155
|
-
*/
|
|
156
|
-
$config(
|
|
157
|
-
config: BuilderConfig,
|
|
158
|
-
): EffectBuilder<
|
|
310
|
+
TEffectErrorMap,
|
|
311
|
+
TMeta,
|
|
312
|
+
TRequirementsProvided,
|
|
313
|
+
TRuntimeError
|
|
314
|
+
>["$context"];
|
|
315
|
+
declare $meta: EffectBuilderSurface<
|
|
159
316
|
TInitialContext,
|
|
160
317
|
TCurrentContext,
|
|
161
318
|
TInputSchema,
|
|
@@ -164,110 +321,36 @@ export class EffectBuilder<
|
|
|
164
321
|
TMeta,
|
|
165
322
|
TRequirementsProvided,
|
|
166
323
|
TRuntimeError
|
|
167
|
-
>
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
"initialInputValidationIndex",
|
|
172
|
-
this["~effect"].config.initialInputValidationIndex,
|
|
173
|
-
);
|
|
174
|
-
const outputValidationCount =
|
|
175
|
-
this["~effect"].outputValidationIndex -
|
|
176
|
-
fallbackConfig(
|
|
177
|
-
"initialOutputValidationIndex",
|
|
178
|
-
this["~effect"].config.initialOutputValidationIndex,
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
return new EffectBuilder({
|
|
182
|
-
...this["~effect"],
|
|
183
|
-
config,
|
|
184
|
-
dedupeLeadingMiddlewares: fallbackConfig(
|
|
185
|
-
"dedupeLeadingMiddlewares",
|
|
186
|
-
config.dedupeLeadingMiddlewares,
|
|
187
|
-
),
|
|
188
|
-
inputValidationIndex:
|
|
189
|
-
fallbackConfig(
|
|
190
|
-
"initialInputValidationIndex",
|
|
191
|
-
config.initialInputValidationIndex,
|
|
192
|
-
) + inputValidationCount,
|
|
193
|
-
outputValidationIndex:
|
|
194
|
-
fallbackConfig(
|
|
195
|
-
"initialOutputValidationIndex",
|
|
196
|
-
config.initialOutputValidationIndex,
|
|
197
|
-
) + outputValidationCount,
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Set or override the initial context.
|
|
203
|
-
*
|
|
204
|
-
* @see {@link https://orpc.dev/docs/context Context Docs}
|
|
205
|
-
*/
|
|
206
|
-
$context<U extends Context>(): EffectBuilder<
|
|
207
|
-
U & Record<never, never>,
|
|
208
|
-
U,
|
|
324
|
+
>["$meta"];
|
|
325
|
+
declare $route: EffectBuilderSurface<
|
|
326
|
+
TInitialContext,
|
|
327
|
+
TCurrentContext,
|
|
209
328
|
TInputSchema,
|
|
210
329
|
TOutputSchema,
|
|
211
330
|
TEffectErrorMap,
|
|
212
331
|
TMeta,
|
|
213
332
|
TRequirementsProvided,
|
|
214
333
|
TRuntimeError
|
|
215
|
-
>
|
|
216
|
-
|
|
217
|
-
* We need `& Record<never, never>` to deal with `has no properties in common with type` error
|
|
218
|
-
*/
|
|
219
|
-
|
|
220
|
-
return new EffectBuilder({
|
|
221
|
-
...this["~effect"],
|
|
222
|
-
middlewares: [],
|
|
223
|
-
inputValidationIndex: fallbackConfig(
|
|
224
|
-
"initialInputValidationIndex",
|
|
225
|
-
this["~effect"].config.initialInputValidationIndex,
|
|
226
|
-
),
|
|
227
|
-
outputValidationIndex: fallbackConfig(
|
|
228
|
-
"initialOutputValidationIndex",
|
|
229
|
-
this["~effect"].config.initialOutputValidationIndex,
|
|
230
|
-
),
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Sets or overrides the initial meta.
|
|
236
|
-
*
|
|
237
|
-
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
|
|
238
|
-
*/
|
|
239
|
-
$meta<U extends Meta>(
|
|
240
|
-
initialMeta: U,
|
|
241
|
-
): EffectBuilder<
|
|
334
|
+
>["$route"];
|
|
335
|
+
declare $input: EffectBuilderSurface<
|
|
242
336
|
TInitialContext,
|
|
243
337
|
TCurrentContext,
|
|
244
338
|
TInputSchema,
|
|
245
339
|
TOutputSchema,
|
|
246
340
|
TEffectErrorMap,
|
|
247
|
-
|
|
341
|
+
TMeta,
|
|
248
342
|
TRequirementsProvided,
|
|
249
343
|
TRuntimeError
|
|
250
|
-
>
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Sets or overrides the initial route.
|
|
263
|
-
* This option is typically relevant when integrating with OpenAPI.
|
|
264
|
-
*
|
|
265
|
-
* @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}
|
|
266
|
-
* @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
|
|
267
|
-
*/
|
|
268
|
-
$route(
|
|
269
|
-
initialRoute: Route,
|
|
270
|
-
): EffectBuilder<
|
|
344
|
+
>["$input"];
|
|
345
|
+
declare "~effect": EffectBuilderDef<
|
|
346
|
+
TInputSchema,
|
|
347
|
+
TOutputSchema,
|
|
348
|
+
TEffectErrorMap,
|
|
349
|
+
TMeta,
|
|
350
|
+
TRequirementsProvided,
|
|
351
|
+
TRuntimeError
|
|
352
|
+
>;
|
|
353
|
+
declare "~orpc": EffectBuilderSurface<
|
|
271
354
|
TInitialContext,
|
|
272
355
|
TCurrentContext,
|
|
273
356
|
TInputSchema,
|
|
@@ -276,133 +359,38 @@ export class EffectBuilder<
|
|
|
276
359
|
TMeta,
|
|
277
360
|
TRequirementsProvided,
|
|
278
361
|
TRuntimeError
|
|
279
|
-
>
|
|
280
|
-
|
|
281
|
-
...this["~effect"],
|
|
282
|
-
route: initialRoute,
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Sets or overrides the initial input schema.
|
|
288
|
-
*
|
|
289
|
-
* @see {@link https://orpc.dev/docs/procedure#initial-configuration Initial Procedure Configuration Docs}
|
|
290
|
-
*/
|
|
291
|
-
$input<U extends AnySchema>(
|
|
292
|
-
initialInputSchema?: U,
|
|
293
|
-
): EffectBuilder<
|
|
362
|
+
>["~orpc"];
|
|
363
|
+
declare middleware: EffectBuilderSurface<
|
|
294
364
|
TInitialContext,
|
|
295
365
|
TCurrentContext,
|
|
296
|
-
|
|
366
|
+
TInputSchema,
|
|
297
367
|
TOutputSchema,
|
|
298
368
|
TEffectErrorMap,
|
|
299
369
|
TMeta,
|
|
300
370
|
TRequirementsProvided,
|
|
301
371
|
TRuntimeError
|
|
302
|
-
>
|
|
303
|
-
|
|
304
|
-
...this["~effect"],
|
|
305
|
-
inputSchema: initialInputSchema,
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Adds type-safe custom errors.
|
|
311
|
-
* Supports both traditional oRPC error definitions and ORPCTaggedError classes.
|
|
312
|
-
*
|
|
313
|
-
* @example
|
|
314
|
-
* ```ts
|
|
315
|
-
* // Traditional format
|
|
316
|
-
* builder.errors({ BAD_REQUEST: { status: 400, message: 'Bad request' } })
|
|
317
|
-
*
|
|
318
|
-
* // Tagged error class
|
|
319
|
-
* builder.errors({ USER_NOT_FOUND: UserNotFoundError })
|
|
320
|
-
*
|
|
321
|
-
* // Mixed
|
|
322
|
-
* builder.errors({
|
|
323
|
-
* BAD_REQUEST: { status: 400 },
|
|
324
|
-
* USER_NOT_FOUND: UserNotFoundError,
|
|
325
|
-
* })
|
|
326
|
-
* ```
|
|
327
|
-
*
|
|
328
|
-
* @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}
|
|
329
|
-
*/
|
|
330
|
-
errors<U extends EffectErrorMap>(
|
|
331
|
-
errors: U,
|
|
332
|
-
): EffectBuilder<
|
|
372
|
+
>["middleware"];
|
|
373
|
+
declare errors: EffectBuilderSurface<
|
|
333
374
|
TInitialContext,
|
|
334
375
|
TCurrentContext,
|
|
335
376
|
TInputSchema,
|
|
336
377
|
TOutputSchema,
|
|
337
|
-
|
|
378
|
+
TEffectErrorMap,
|
|
338
379
|
TMeta,
|
|
339
380
|
TRequirementsProvided,
|
|
340
381
|
TRuntimeError
|
|
341
|
-
>
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
};
|
|
346
|
-
return new EffectBuilder({
|
|
347
|
-
...this["~effect"],
|
|
348
|
-
errorMap: effectErrorMapToErrorMap(newEffectErrorMap),
|
|
349
|
-
effectErrorMap: newEffectErrorMap,
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Uses a middleware to modify the context or improve the pipeline.
|
|
355
|
-
*
|
|
356
|
-
* @info Supports both normal middleware and inline middleware implementations.
|
|
357
|
-
* @note The current context must be satisfy middleware dependent-context
|
|
358
|
-
* @see {@link https://orpc.dev/docs/middleware Middleware Docs}
|
|
359
|
-
*/
|
|
360
|
-
use<
|
|
361
|
-
UOutContext extends IntersectPick<TCurrentContext, UOutContext>,
|
|
362
|
-
UInContext extends Context = TCurrentContext,
|
|
363
|
-
>(
|
|
364
|
-
middleware: Middleware<
|
|
365
|
-
UInContext | TCurrentContext,
|
|
366
|
-
UOutContext,
|
|
367
|
-
InferSchemaOutput<TInputSchema>,
|
|
368
|
-
unknown,
|
|
369
|
-
EffectErrorConstructorMap<TEffectErrorMap>,
|
|
370
|
-
TMeta
|
|
371
|
-
>,
|
|
372
|
-
): EffectBuilder<
|
|
373
|
-
MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,
|
|
374
|
-
MergedCurrentContext<TCurrentContext, UOutContext>,
|
|
382
|
+
>["errors"];
|
|
383
|
+
declare use: EffectBuilderSurface<
|
|
384
|
+
TInitialContext,
|
|
385
|
+
TCurrentContext,
|
|
375
386
|
TInputSchema,
|
|
376
387
|
TOutputSchema,
|
|
377
388
|
TEffectErrorMap,
|
|
378
389
|
TMeta,
|
|
379
390
|
TRequirementsProvided,
|
|
380
391
|
TRuntimeError
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
use(
|
|
384
|
-
middleware: AnyMiddleware,
|
|
385
|
-
mapInput?: MapInputMiddleware<any, any>,
|
|
386
|
-
): EffectBuilder<any, any, any, any, any, any, any, any> {
|
|
387
|
-
const mapped = mapInput
|
|
388
|
-
? decorateMiddleware(middleware).mapInput(mapInput)
|
|
389
|
-
: middleware;
|
|
390
|
-
|
|
391
|
-
return new EffectBuilder({
|
|
392
|
-
...this["~effect"],
|
|
393
|
-
middlewares: addMiddleware(this["~effect"].middlewares, mapped),
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Sets or updates the metadata.
|
|
399
|
-
* The provided metadata is spared-merged with any existing metadata.
|
|
400
|
-
*
|
|
401
|
-
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
|
|
402
|
-
*/
|
|
403
|
-
meta(
|
|
404
|
-
meta: TMeta,
|
|
405
|
-
): EffectBuilder<
|
|
392
|
+
>["use"];
|
|
393
|
+
declare meta: EffectBuilderSurface<
|
|
406
394
|
TInitialContext,
|
|
407
395
|
TCurrentContext,
|
|
408
396
|
TInputSchema,
|
|
@@ -411,24 +399,8 @@ export class EffectBuilder<
|
|
|
411
399
|
TMeta,
|
|
412
400
|
TRequirementsProvided,
|
|
413
401
|
TRuntimeError
|
|
414
|
-
>
|
|
415
|
-
|
|
416
|
-
...this["~effect"],
|
|
417
|
-
meta: mergeMeta(this["~effect"].meta, meta),
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* Sets or updates the route definition.
|
|
423
|
-
* The provided route is spared-merged with any existing route.
|
|
424
|
-
* This option is typically relevant when integrating with OpenAPI.
|
|
425
|
-
*
|
|
426
|
-
* @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}
|
|
427
|
-
* @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
|
|
428
|
-
*/
|
|
429
|
-
route(
|
|
430
|
-
route: Route,
|
|
431
|
-
): EffectBuilder<
|
|
402
|
+
>["meta"];
|
|
403
|
+
declare route: EffectBuilderSurface<
|
|
432
404
|
TInitialContext,
|
|
433
405
|
TCurrentContext,
|
|
434
406
|
TInputSchema,
|
|
@@ -437,98 +409,28 @@ export class EffectBuilder<
|
|
|
437
409
|
TMeta,
|
|
438
410
|
TRequirementsProvided,
|
|
439
411
|
TRuntimeError
|
|
440
|
-
>
|
|
441
|
-
|
|
442
|
-
...this["~effect"],
|
|
443
|
-
route: mergeRoute(this["~effect"].route, route),
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Defines the input validation schema.
|
|
449
|
-
*
|
|
450
|
-
* @see {@link https://orpc.dev/docs/procedure#input-output-validation Input Validation Docs}
|
|
451
|
-
*/
|
|
452
|
-
input<USchema extends AnySchema>(
|
|
453
|
-
schema: USchema,
|
|
454
|
-
): EffectProcedureBuilderWithInput<
|
|
412
|
+
>["route"];
|
|
413
|
+
declare input: EffectBuilderSurface<
|
|
455
414
|
TInitialContext,
|
|
456
415
|
TCurrentContext,
|
|
457
|
-
|
|
416
|
+
TInputSchema,
|
|
458
417
|
TOutputSchema,
|
|
459
418
|
TEffectErrorMap,
|
|
460
419
|
TMeta,
|
|
461
420
|
TRequirementsProvided,
|
|
462
421
|
TRuntimeError
|
|
463
|
-
>
|
|
464
|
-
|
|
465
|
-
...this["~effect"],
|
|
466
|
-
inputSchema: schema,
|
|
467
|
-
inputValidationIndex:
|
|
468
|
-
fallbackConfig(
|
|
469
|
-
"initialInputValidationIndex",
|
|
470
|
-
this["~effect"].config.initialInputValidationIndex,
|
|
471
|
-
) + this["~effect"].middlewares.length,
|
|
472
|
-
// we cast to any because EffectProcedureBuilderWithInput is expecting
|
|
473
|
-
// use() input type to be defined, and EffectBuilder types its use() input
|
|
474
|
-
// to unknown to allow any middleware to be passed
|
|
475
|
-
// ---
|
|
476
|
-
// note: the original implentation of the builder also uses any for the same reason
|
|
477
|
-
}) as any;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Defines the output validation schema.
|
|
482
|
-
*
|
|
483
|
-
* @see {@link https://orpc.dev/docs/procedure#input-output-validation Output Validation Docs}
|
|
484
|
-
*/
|
|
485
|
-
output<USchema extends AnySchema>(
|
|
486
|
-
schema: USchema,
|
|
487
|
-
): EffectProcedureBuilderWithOutput<
|
|
422
|
+
>["input"];
|
|
423
|
+
declare output: EffectBuilderSurface<
|
|
488
424
|
TInitialContext,
|
|
489
425
|
TCurrentContext,
|
|
490
426
|
TInputSchema,
|
|
491
|
-
|
|
427
|
+
TOutputSchema,
|
|
492
428
|
TEffectErrorMap,
|
|
493
429
|
TMeta,
|
|
494
430
|
TRequirementsProvided,
|
|
495
431
|
TRuntimeError
|
|
496
|
-
>
|
|
497
|
-
|
|
498
|
-
// handler/effect output typing based on the declared output schema.
|
|
499
|
-
return new EffectBuilder({
|
|
500
|
-
...this["~effect"],
|
|
501
|
-
outputSchema: schema,
|
|
502
|
-
outputValidationIndex:
|
|
503
|
-
fallbackConfig(
|
|
504
|
-
"initialOutputValidationIndex",
|
|
505
|
-
this["~effect"].config.initialOutputValidationIndex,
|
|
506
|
-
) + this["~effect"].middlewares.length,
|
|
507
|
-
}) as any;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* Adds a traceable span to the procedure for telemetry.
|
|
512
|
-
* The span name is used for Effect tracing via `Effect.withSpan`.
|
|
513
|
-
* Stack trace is captured at the call site for better error reporting.
|
|
514
|
-
*
|
|
515
|
-
* @param spanName - The name of the span for telemetry (e.g., 'users.getUser')
|
|
516
|
-
* @returns An EffectBuilder with span tracing configured
|
|
517
|
-
*
|
|
518
|
-
* @example
|
|
519
|
-
* ```ts
|
|
520
|
-
* const getUser = effectOs
|
|
521
|
-
* .input(z.object({ id: z.string() }))
|
|
522
|
-
* .traced('users.getUser')
|
|
523
|
-
* .effect(function* ({ input }) {
|
|
524
|
-
* const userService = yield* UserService
|
|
525
|
-
* return yield* userService.findById(input.id)
|
|
526
|
-
* })
|
|
527
|
-
* ```
|
|
528
|
-
*/
|
|
529
|
-
traced(
|
|
530
|
-
spanName: string,
|
|
531
|
-
): EffectBuilder<
|
|
432
|
+
>["output"];
|
|
433
|
+
declare traced: EffectBuilderSurface<
|
|
532
434
|
TInitialContext,
|
|
533
435
|
TCurrentContext,
|
|
534
436
|
TInputSchema,
|
|
@@ -537,250 +439,97 @@ export class EffectBuilder<
|
|
|
537
439
|
TMeta,
|
|
538
440
|
TRequirementsProvided,
|
|
539
441
|
TRuntimeError
|
|
540
|
-
>
|
|
541
|
-
|
|
542
|
-
...this["~effect"],
|
|
543
|
-
spanConfig: {
|
|
544
|
-
name: spanName,
|
|
545
|
-
captureStackTrace: addSpanStackTrace(),
|
|
546
|
-
},
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
handler<UFuncOutput>(
|
|
551
|
-
handler: ProcedureHandler<
|
|
552
|
-
TCurrentContext,
|
|
553
|
-
InferSchemaOutput<TInputSchema>,
|
|
554
|
-
UFuncOutput,
|
|
555
|
-
EffectErrorMapToErrorMap<TEffectErrorMap>,
|
|
556
|
-
TMeta
|
|
557
|
-
>,
|
|
558
|
-
): EffectDecoratedProcedure<
|
|
442
|
+
>["traced"];
|
|
443
|
+
declare handler: EffectBuilderSurface<
|
|
559
444
|
TInitialContext,
|
|
560
445
|
TCurrentContext,
|
|
561
446
|
TInputSchema,
|
|
562
|
-
|
|
447
|
+
TOutputSchema,
|
|
563
448
|
TEffectErrorMap,
|
|
564
449
|
TMeta,
|
|
565
450
|
TRequirementsProvided,
|
|
566
451
|
TRuntimeError
|
|
567
|
-
>
|
|
568
|
-
|
|
569
|
-
...this["~effect"],
|
|
570
|
-
handler,
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Defines the handler of the procedure using an Effect.
|
|
576
|
-
* The Effect is executed using the ManagedRuntime provided during builder creation.
|
|
577
|
-
* The effect is automatically wrapped with `Effect.withSpan`.
|
|
578
|
-
*
|
|
579
|
-
* @see {@link https://orpc.dev/docs/procedure Procedure Docs}
|
|
580
|
-
*/
|
|
581
|
-
effect<UFuncOutput>(
|
|
582
|
-
effectFn: EffectProcedureHandler<
|
|
583
|
-
TCurrentContext,
|
|
584
|
-
TInputSchema,
|
|
585
|
-
UFuncOutput,
|
|
586
|
-
TEffectErrorMap,
|
|
587
|
-
TRequirementsProvided,
|
|
588
|
-
TMeta
|
|
589
|
-
>,
|
|
590
|
-
): EffectDecoratedProcedure<
|
|
452
|
+
>["handler"];
|
|
453
|
+
declare effect: EffectBuilderSurface<
|
|
591
454
|
TInitialContext,
|
|
592
455
|
TCurrentContext,
|
|
593
456
|
TInputSchema,
|
|
594
|
-
|
|
457
|
+
TOutputSchema,
|
|
595
458
|
TEffectErrorMap,
|
|
596
459
|
TMeta,
|
|
597
460
|
TRequirementsProvided,
|
|
598
461
|
TRuntimeError
|
|
599
|
-
>
|
|
600
|
-
|
|
601
|
-
// Capture stack trace at definition time for default tracing
|
|
602
|
-
const defaultCaptureStackTrace = addSpanStackTrace();
|
|
603
|
-
return new EffectDecoratedProcedure({
|
|
604
|
-
...this["~effect"],
|
|
605
|
-
handler: async (opts) => {
|
|
606
|
-
const effectOpts: ProcedureHandlerOptions<
|
|
607
|
-
TCurrentContext,
|
|
608
|
-
InferSchemaOutput<TInputSchema>,
|
|
609
|
-
EffectErrorConstructorMap<TEffectErrorMap>,
|
|
610
|
-
TMeta
|
|
611
|
-
> = {
|
|
612
|
-
context: opts.context,
|
|
613
|
-
input: opts.input,
|
|
614
|
-
path: opts.path,
|
|
615
|
-
procedure: opts.procedure,
|
|
616
|
-
signal: opts.signal,
|
|
617
|
-
lastEventId: opts.lastEventId,
|
|
618
|
-
errors: createEffectErrorConstructorMap(
|
|
619
|
-
this["~effect"].effectErrorMap,
|
|
620
|
-
),
|
|
621
|
-
};
|
|
622
|
-
const spanName = spanConfig?.name ?? opts.path.join(".");
|
|
623
|
-
const captureStackTrace =
|
|
624
|
-
spanConfig?.captureStackTrace ?? defaultCaptureStackTrace;
|
|
625
|
-
const resolver = Effect.fnUntraced(effectFn);
|
|
626
|
-
const tracedEffect = Effect.withSpan(resolver(effectOpts), spanName, {
|
|
627
|
-
captureStackTrace,
|
|
628
|
-
});
|
|
629
|
-
const parentFiberRefs = getCurrentFiberRefs();
|
|
630
|
-
const effectWithRefs = parentFiberRefs
|
|
631
|
-
? Effect.fiberIdWith((fiberId) =>
|
|
632
|
-
Effect.flatMap(Effect.getFiberRefs, (fiberRefs) =>
|
|
633
|
-
Effect.setFiberRefs(
|
|
634
|
-
FiberRefs.joinAs(fiberRefs, fiberId, parentFiberRefs),
|
|
635
|
-
).pipe(Effect.andThen(tracedEffect)),
|
|
636
|
-
),
|
|
637
|
-
)
|
|
638
|
-
: tracedEffect;
|
|
639
|
-
const exit = await runtime.runPromiseExit(effectWithRefs, {
|
|
640
|
-
signal: opts.signal,
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
if (Exit.isFailure(exit)) {
|
|
644
|
-
throw Cause.match(exit.cause, {
|
|
645
|
-
onDie(defect) {
|
|
646
|
-
return new ORPCError("INTERNAL_SERVER_ERROR", {
|
|
647
|
-
cause: defect,
|
|
648
|
-
});
|
|
649
|
-
},
|
|
650
|
-
onFail(error) {
|
|
651
|
-
if (isORPCTaggedError(error)) {
|
|
652
|
-
return error.toORPCError();
|
|
653
|
-
}
|
|
654
|
-
if (error instanceof ORPCError) {
|
|
655
|
-
return error;
|
|
656
|
-
}
|
|
657
|
-
return new ORPCError("INTERNAL_SERVER_ERROR", {
|
|
658
|
-
cause: error,
|
|
659
|
-
});
|
|
660
|
-
},
|
|
661
|
-
onInterrupt(fiberId) {
|
|
662
|
-
return new ORPCError("INTERNAL_SERVER_ERROR", {
|
|
663
|
-
cause: new Error(`${fiberId} Interrupted`),
|
|
664
|
-
});
|
|
665
|
-
},
|
|
666
|
-
onSequential(left) {
|
|
667
|
-
return left;
|
|
668
|
-
},
|
|
669
|
-
onEmpty: new ORPCError("INTERNAL_SERVER_ERROR", {
|
|
670
|
-
cause: new Error("Unknown error"),
|
|
671
|
-
}),
|
|
672
|
-
onParallel(left) {
|
|
673
|
-
return left;
|
|
674
|
-
},
|
|
675
|
-
});
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
return exit.value;
|
|
679
|
-
},
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* Prefixes all procedures in the router.
|
|
685
|
-
* The provided prefix is post-appended to any existing router prefix.
|
|
686
|
-
*
|
|
687
|
-
* @note This option does not affect procedures that do not define a path in their route definition.
|
|
688
|
-
*
|
|
689
|
-
* @see {@link https://orpc.dev/docs/openapi/routing#route-prefixes OpenAPI Route Prefixes Docs}
|
|
690
|
-
*/
|
|
691
|
-
prefix(
|
|
692
|
-
prefix: HTTPPath,
|
|
693
|
-
): EffectRouterBuilder<
|
|
462
|
+
>["effect"];
|
|
463
|
+
declare prefix: EffectBuilderSurface<
|
|
694
464
|
TInitialContext,
|
|
695
465
|
TCurrentContext,
|
|
466
|
+
TInputSchema,
|
|
467
|
+
TOutputSchema,
|
|
696
468
|
TEffectErrorMap,
|
|
697
469
|
TMeta,
|
|
698
470
|
TRequirementsProvided,
|
|
699
471
|
TRuntimeError
|
|
700
|
-
>
|
|
701
|
-
|
|
702
|
-
...this["~effect"],
|
|
703
|
-
prefix: mergePrefix(this["~effect"].prefix, prefix),
|
|
704
|
-
}) as any;
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
/**
|
|
708
|
-
* Adds tags to all procedures in the router.
|
|
709
|
-
* This helpful when you want to group procedures together in the OpenAPI specification.
|
|
710
|
-
*
|
|
711
|
-
* @see {@link https://orpc.dev/docs/openapi/openapi-specification#operation-metadata OpenAPI Operation Metadata Docs}
|
|
712
|
-
*/
|
|
713
|
-
tag(
|
|
714
|
-
...tags: string[]
|
|
715
|
-
): EffectRouterBuilder<
|
|
472
|
+
>["prefix"];
|
|
473
|
+
declare tag: EffectBuilderSurface<
|
|
716
474
|
TInitialContext,
|
|
717
475
|
TCurrentContext,
|
|
476
|
+
TInputSchema,
|
|
477
|
+
TOutputSchema,
|
|
718
478
|
TEffectErrorMap,
|
|
719
479
|
TMeta,
|
|
720
480
|
TRequirementsProvided,
|
|
721
481
|
TRuntimeError
|
|
722
|
-
>
|
|
723
|
-
|
|
724
|
-
...this["~effect"],
|
|
725
|
-
tags: mergeTags(this["~effect"].tags, tags),
|
|
726
|
-
}) as any;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
/**
|
|
730
|
-
* Applies all of the previously defined options to the specified router.
|
|
731
|
-
*
|
|
732
|
-
* @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}
|
|
733
|
-
*/
|
|
734
|
-
router<U extends Router<ContractRouter<TMeta>, TCurrentContext>>(
|
|
735
|
-
router: U,
|
|
736
|
-
): EnhancedEffectRouter<
|
|
737
|
-
U,
|
|
482
|
+
>["tag"];
|
|
483
|
+
declare router: EffectBuilderSurface<
|
|
738
484
|
TInitialContext,
|
|
739
485
|
TCurrentContext,
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
* Create a lazy router
|
|
749
|
-
* And applies all of the previously defined options to the specified router.
|
|
750
|
-
*
|
|
751
|
-
* @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}
|
|
752
|
-
*/
|
|
753
|
-
lazy<U extends Router<ContractRouter<TMeta>, TCurrentContext>>(
|
|
754
|
-
loader: () => Promise<{ default: U }>,
|
|
755
|
-
): EnhancedEffectRouter<
|
|
756
|
-
Lazy<U>,
|
|
486
|
+
TInputSchema,
|
|
487
|
+
TOutputSchema,
|
|
488
|
+
TEffectErrorMap,
|
|
489
|
+
TMeta,
|
|
490
|
+
TRequirementsProvided,
|
|
491
|
+
TRuntimeError
|
|
492
|
+
>["router"];
|
|
493
|
+
declare lazy: EffectBuilderSurface<
|
|
757
494
|
TInitialContext,
|
|
758
495
|
TCurrentContext,
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
496
|
+
TInputSchema,
|
|
497
|
+
TOutputSchema,
|
|
498
|
+
TEffectErrorMap,
|
|
499
|
+
TMeta,
|
|
500
|
+
TRequirementsProvided,
|
|
501
|
+
TRuntimeError
|
|
502
|
+
>["lazy"];
|
|
503
|
+
|
|
504
|
+
constructor(
|
|
505
|
+
def: EffectBuilderDef<
|
|
506
|
+
TInputSchema,
|
|
507
|
+
TOutputSchema,
|
|
508
|
+
TEffectErrorMap,
|
|
509
|
+
TMeta,
|
|
510
|
+
TRequirementsProvided,
|
|
511
|
+
TRuntimeError
|
|
512
|
+
>,
|
|
513
|
+
builder?: AnyBuilderLike,
|
|
514
|
+
) {
|
|
515
|
+
const { runtime, spanConfig, effectErrorMap, ...orpcDef } = def;
|
|
516
|
+
|
|
517
|
+
attachEffectState(this, builder ?? new Builder(orpcDef), {
|
|
518
|
+
effectErrorMap,
|
|
519
|
+
runtime,
|
|
520
|
+
spanConfig,
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
return createEffectBuilderProxy(this);
|
|
764
524
|
}
|
|
765
525
|
}
|
|
766
526
|
|
|
767
527
|
/**
|
|
768
528
|
* Creates an Effect-aware procedure builder with the specified ManagedRuntime.
|
|
769
|
-
* Uses the default
|
|
529
|
+
* Uses the default builder shape from `@orpc/server`.
|
|
770
530
|
*
|
|
771
531
|
* @param runtime - The ManagedRuntime that provides services for Effect procedures
|
|
772
532
|
* @returns An EffectBuilder instance for creating Effect-native procedures
|
|
773
|
-
*
|
|
774
|
-
* @example
|
|
775
|
-
* ```ts
|
|
776
|
-
* import { makeEffectORPC } from '@orpc/effect'
|
|
777
|
-
* import { Effect, Layer, ManagedRuntime } from 'effect'
|
|
778
|
-
*
|
|
779
|
-
* const runtime = ManagedRuntime.make(Layer.empty)
|
|
780
|
-
* const effectOs = makeEffectORPC(runtime)
|
|
781
|
-
*
|
|
782
|
-
* const hello = effectOs.effect(() => Effect.succeed('Hello!'))
|
|
783
|
-
* ```
|
|
784
533
|
*/
|
|
785
534
|
export function makeEffectORPC<TRequirementsProvided, TRuntimeError>(
|
|
786
535
|
runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,
|
|
@@ -800,31 +549,8 @@ export function makeEffectORPC<TRequirementsProvided, TRuntimeError>(
|
|
|
800
549
|
* with the specified ManagedRuntime.
|
|
801
550
|
*
|
|
802
551
|
* @param runtime - The ManagedRuntime that provides services for Effect procedures
|
|
803
|
-
* @param builder - The oRPC Builder instance to wrap
|
|
552
|
+
* @param builder - The oRPC Builder instance to wrap
|
|
804
553
|
* @returns An EffectBuilder instance that extends the original builder with Effect support
|
|
805
|
-
*
|
|
806
|
-
* @example
|
|
807
|
-
* ```ts
|
|
808
|
-
* import { makeEffectORPC } from '@orpc/effect'
|
|
809
|
-
* import { os } from '@orpc/server'
|
|
810
|
-
* import { Effect, Layer, ManagedRuntime } from 'effect'
|
|
811
|
-
*
|
|
812
|
-
* // Create a customized builder
|
|
813
|
-
* const authedOs = os.use(authMiddleware)
|
|
814
|
-
*
|
|
815
|
-
* // Wrap it with Effect support
|
|
816
|
-
* const runtime = ManagedRuntime.make(UserServiceLive)
|
|
817
|
-
* const effectOs = makeEffectORPC(runtime, authedOs)
|
|
818
|
-
*
|
|
819
|
-
* const getUser = effectOs
|
|
820
|
-
* .input(z.object({ id: z.string() }))
|
|
821
|
-
* .effect(
|
|
822
|
-
* Effect.fn(function* ({ input }) {
|
|
823
|
-
* const userService = yield* UserService
|
|
824
|
-
* return yield* userService.findById(input.id)
|
|
825
|
-
* })
|
|
826
|
-
* )
|
|
827
|
-
* ```
|
|
828
554
|
*/
|
|
829
555
|
export function makeEffectORPC<
|
|
830
556
|
TBuilder extends AnyBuilderLike<
|
|
@@ -867,23 +593,27 @@ export function makeEffectORPC<TRequirementsProvided, TRuntimeError>(
|
|
|
867
593
|
TRuntimeError
|
|
868
594
|
> {
|
|
869
595
|
const resolvedBuilder = builder ?? emptyBuilder();
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
596
|
+
const effectErrorMap = getEffectErrorMap(resolvedBuilder);
|
|
597
|
+
return new EffectBuilder(
|
|
598
|
+
{
|
|
599
|
+
...resolvedBuilder["~orpc"],
|
|
600
|
+
effectErrorMap: effectErrorMap,
|
|
601
|
+
errorMap: effectErrorMapToErrorMap(effectErrorMap),
|
|
602
|
+
runtime,
|
|
603
|
+
},
|
|
604
|
+
unwrapEffectUpstream(resolvedBuilder),
|
|
605
|
+
);
|
|
876
606
|
}
|
|
877
607
|
|
|
878
608
|
function emptyBuilder(): AnyBuilderLike {
|
|
879
609
|
return new Builder({
|
|
880
610
|
config: {},
|
|
881
|
-
|
|
882
|
-
meta: {},
|
|
611
|
+
dedupeLeadingMiddlewares: true,
|
|
883
612
|
errorMap: {},
|
|
884
613
|
inputValidationIndex: fallbackConfig("initialInputValidationIndex"),
|
|
885
|
-
|
|
614
|
+
meta: {},
|
|
886
615
|
middlewares: [],
|
|
887
|
-
|
|
616
|
+
outputValidationIndex: fallbackConfig("initialOutputValidationIndex"),
|
|
617
|
+
route: {},
|
|
888
618
|
});
|
|
889
619
|
}
|