@shivaedev/effect-trpc 0.0.0
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/CHANGELOG.md +6 -0
- package/LICENSE +21 -0
- package/README.md +142 -0
- package/dist/adapter.d.ts +16 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +12 -0
- package/dist/adapter.js.map +1 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +11 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/context-bridge.d.ts +7 -0
- package/dist/internal/context-bridge.d.ts.map +1 -0
- package/dist/internal/context-bridge.js +9 -0
- package/dist/internal/context-bridge.js.map +1 -0
- package/dist/internal/procedure-handler.d.ts +13 -0
- package/dist/internal/procedure-handler.d.ts.map +1 -0
- package/dist/internal/procedure-handler.js +12 -0
- package/dist/internal/procedure-handler.js.map +1 -0
- package/dist/internal/procedure-types.d.ts +9 -0
- package/dist/internal/procedure-types.d.ts.map +1 -0
- package/dist/internal/procedure-types.js +2 -0
- package/dist/internal/procedure-types.js.map +1 -0
- package/dist/internal/runtime.d.ts +16 -0
- package/dist/internal/runtime.d.ts.map +1 -0
- package/dist/internal/runtime.js +60 -0
- package/dist/internal/runtime.js.map +1 -0
- package/dist/internal/stack-trace.d.ts +2 -0
- package/dist/internal/stack-trace.d.ts.map +1 -0
- package/dist/internal/stack-trace.js +19 -0
- package/dist/internal/stack-trace.js.map +1 -0
- package/dist/internal/vitest-trpc.d.ts +18 -0
- package/dist/internal/vitest-trpc.d.ts.map +1 -0
- package/dist/internal/vitest-trpc.js +70 -0
- package/dist/internal/vitest-trpc.js.map +1 -0
- package/dist/procedure.d.ts +27 -0
- package/dist/procedure.d.ts.map +1 -0
- package/dist/procedure.js +34 -0
- package/dist/procedure.js.map +1 -0
- package/dist/request-services.d.ts +7 -0
- package/dist/request-services.d.ts.map +1 -0
- package/dist/request-services.js +4 -0
- package/dist/request-services.js.map +1 -0
- package/dist/testing/caller.d.ts +10 -0
- package/dist/testing/caller.d.ts.map +1 -0
- package/dist/testing/caller.js +41 -0
- package/dist/testing/caller.js.map +1 -0
- package/dist/testing/types.d.ts +31 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing/types.js +2 -0
- package/dist/testing/types.js.map +1 -0
- package/dist/testing/vitest.d.ts +4 -0
- package/dist/testing/vitest.d.ts.map +1 -0
- package/dist/testing/vitest.js +28 -0
- package/dist/testing/vitest.js.map +1 -0
- package/dist/testing.d.ts +4 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +3 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +73 -0
- package/src/adapter.ts +85 -0
- package/src/errors.ts +30 -0
- package/src/index.ts +28 -0
- package/src/internal/context-bridge.ts +20 -0
- package/src/internal/procedure-handler.ts +48 -0
- package/src/internal/procedure-types.ts +49 -0
- package/src/internal/runtime.ts +131 -0
- package/src/internal/stack-trace.ts +19 -0
- package/src/internal/vitest-trpc.ts +202 -0
- package/src/procedure.ts +191 -0
- package/src/request-services.ts +43 -0
- package/src/testing/caller.ts +80 -0
- package/src/testing/types.ts +81 -0
- package/src/testing/vitest.ts +64 -0
- package/src/testing.ts +13 -0
- package/src/types.ts +24 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedure.d.ts","sourceRoot":"","sources":["../src/procedure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { makeProcedureHandler } from "./internal/procedure-handler.js";
|
|
3
|
+
import { captureStackTrace } from "./internal/stack-trace.js";
|
|
4
|
+
export class EffectProcedureBuilder {
|
|
5
|
+
builder;
|
|
6
|
+
requestServices;
|
|
7
|
+
runtime;
|
|
8
|
+
constructor(builder, requestServices, runtime) {
|
|
9
|
+
this.builder = builder;
|
|
10
|
+
this.requestServices = requestServices;
|
|
11
|
+
this.runtime = runtime;
|
|
12
|
+
}
|
|
13
|
+
input(schema) {
|
|
14
|
+
const next = this.builder.input(Schema.toStandardSchemaV1(schema));
|
|
15
|
+
return new EffectProcedureBuilder(next, this.requestServices, this.runtime);
|
|
16
|
+
}
|
|
17
|
+
output(schema) {
|
|
18
|
+
const next = this.builder.output(Schema.toStandardSchemaV1(schema));
|
|
19
|
+
return new EffectProcedureBuilder(next, this.requestServices, this.runtime);
|
|
20
|
+
}
|
|
21
|
+
query(resolver) {
|
|
22
|
+
return this.dispatch("query", resolver);
|
|
23
|
+
}
|
|
24
|
+
mutation(resolver) {
|
|
25
|
+
return this.dispatch("mutation", resolver);
|
|
26
|
+
}
|
|
27
|
+
dispatch(type, resolver) {
|
|
28
|
+
const handler = makeProcedureHandler(this.runtime, resolver, this.requestServices, { captureStackTrace: captureStackTrace(), type });
|
|
29
|
+
return type === "query"
|
|
30
|
+
? this.builder.query(handler)
|
|
31
|
+
: this.builder.mutation(handler);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=procedure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedure.js","sourceRoot":"","sources":["../src/procedure.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAQvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAsB9D,MAAM,OAAO,sBAAsB;IAahB;IASA;IAeA;IAzBlB,YACkB,OAQhB,EACgB,eAchB,EACgB,OAA2C;QAxB3C,YAAO,GAAP,OAAO,CAQvB;QACgB,oBAAe,GAAf,eAAe,CAc/B;QACgB,YAAO,GAAP,OAAO,CAAoC;IAC1D,CAAC;IAEJ,KAAK,CACJ,MAAmB;QAanB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAU,CAAC,CAAC;QAC5E,OAAO,IAAI,sBAAsB,CAChC,IAQC,EACD,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,CACZ,CAAC;IACH,CAAC;IAED,MAAM,CACL,MAAmB;QAanB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,OAAO,IAAI,sBAAsB,CAChC,IAQC,EACD,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,CACZ,CAAC;IACH,CAAC;IAED,KAAK,CACJ,QAIC;QAMD,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAIpC,CAAC;IACJ,CAAC;IAED,QAAQ,CACP,QAIC;QAMD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAIvC,CAAC;IACJ,CAAC;IAEO,QAAQ,CACf,IAA0B,EAC1B,QAIC;QAED,MAAM,OAAO,GAAG,oBAAoB,CACnC,IAAI,CAAC,OAAO,EACZ,QAAQ,EACR,IAAI,CAAC,eAAe,EACpB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,CACvC,CAAC;QACX,OAAO,IAAI,KAAK,OAAO;YACtB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YAC7B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Layer as EffectLayer } from "effect";
|
|
2
|
+
export interface EffectProcedureRequestServices<Context, Requirements, Error = never> {
|
|
3
|
+
readonly layer: (context: Context) => EffectLayer.Layer<Requirements, Error>;
|
|
4
|
+
}
|
|
5
|
+
export declare const makeRequestServices: <Context, Requirements, Error = never>(layer: (context: Context) => EffectLayer.Layer<Requirements, Error>) => EffectProcedureRequestServices<Context, Requirements, Error>;
|
|
6
|
+
export declare const extendRequestServices: <BaseContext, Context extends BaseContext, BaseRequirements, BaseError, AdditionalRequirements, AdditionalError, AdditionalDependencies extends BaseRequirements = BaseRequirements>(base: EffectProcedureRequestServices<BaseContext, BaseRequirements, BaseError>, additional: (context: Context) => EffectLayer.Layer<AdditionalRequirements, AdditionalError, AdditionalDependencies>) => EffectProcedureRequestServices<Context, BaseRequirements | AdditionalRequirements, BaseError | AdditionalError>;
|
|
7
|
+
//# sourceMappingURL=request-services.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-services.d.ts","sourceRoot":"","sources":["../src/request-services.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,IAAI,WAAW,EAAS,MAAM,QAAQ,CAAC;AAE1D,MAAM,WAAW,8BAA8B,CAC9C,OAAO,EACP,YAAY,EACZ,KAAK,GAAG,KAAK;IAEb,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;CAC7E;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,EAAE,YAAY,EAAE,KAAK,GAAG,KAAK,EACvE,OAAO,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,KACjE,8BAA8B,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,CAAgB,CAAC;AAE/E,eAAO,MAAM,qBAAqB,GACjC,WAAW,EACX,OAAO,SAAS,WAAW,EAC3B,gBAAgB,EAChB,SAAS,EACT,sBAAsB,EACtB,eAAe,EACf,sBAAsB,SAAS,gBAAgB,GAAG,gBAAgB,EAElE,MAAM,8BAA8B,CACnC,WAAW,EACX,gBAAgB,EAChB,SAAS,CACT,EACD,YAAY,CACX,OAAO,EAAE,OAAO,KACZ,WAAW,CAAC,KAAK,CACrB,sBAAsB,EACtB,eAAe,EACf,sBAAsB,CACtB,KACC,8BAA8B,CAChC,OAAO,EACP,gBAAgB,GAAG,sBAAsB,EACzC,SAAS,GAAG,eAAe,CAI1B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Layer } from "effect";
|
|
2
|
+
export const makeRequestServices = (layer) => ({ layer });
|
|
3
|
+
export const extendRequestServices = (base, additional) => makeRequestServices((context) => Layer.provideMerge(additional(context), base.layer(context)));
|
|
4
|
+
//# sourceMappingURL=request-services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-services.js","sourceRoot":"","sources":["../src/request-services.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,EAAE,MAAM,QAAQ,CAAC;AAU1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAClC,KAAmE,EACJ,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CASpC,IAIC,EACD,UAMC,EAKA,EAAE,CACH,mBAAmB,CAAC,CAAC,OAAgB,EAAE,EAAE,CACxC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAC5D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type TRPCError } from "@trpc/server";
|
|
2
|
+
import { type Context, Effect } from "effect";
|
|
3
|
+
import type { EffectTRPCAdapter } from "../adapter.js";
|
|
4
|
+
export type EffectCaller<Caller> = {
|
|
5
|
+
readonly [Key in keyof Caller]: Caller[Key] extends (...arguments_: infer Arguments) => Promise<infer Result> ? (...arguments_: Arguments) => Effect.Effect<Result, TRPCError> : Caller[Key] extends (...arguments_: infer Arguments) => infer Result ? (...arguments_: Arguments) => Result : Caller[Key] extends Record<string, unknown> ? EffectCaller<Caller[Key]> : Caller[Key];
|
|
6
|
+
};
|
|
7
|
+
export type EffectCallerFactory<Options, Caller> = EffectCaller<Caller> & ((options?: Options) => EffectCaller<Caller>);
|
|
8
|
+
export declare const makeEffectCaller: <Caller extends object, Services>(adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">, promiseCaller: Caller, services: Context.Context<Services>) => EffectCaller<Caller>;
|
|
9
|
+
export declare const makeEffectCallerFactory: <Options, Caller extends object, Services>(adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">, createCaller: (options?: Options) => Caller, services: Context.Context<Services>) => EffectCallerFactory<Options, Caller>;
|
|
10
|
+
//# sourceMappingURL=caller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caller.d.ts","sourceRoot":"","sources":["../../src/testing/caller.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,MAAM,YAAY,CAAC,MAAM,IAAI;IAClC,QAAQ,EAAE,GAAG,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CACnD,GAAG,UAAU,EAAE,MAAM,SAAS,KAC1B,OAAO,CAAC,MAAM,MAAM,CAAC,GACvB,CAAC,GAAG,UAAU,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAC9D,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,UAAU,EAAE,MAAM,SAAS,KAAK,MAAM,MAAM,GACnE,CAAC,GAAG,UAAU,EAAE,SAAS,KAAK,MAAM,GACpC,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC1C,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GACzB,MAAM,CAAC,GAAG,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,IAAI,YAAY,CAAC,MAAM,CAAC,GACtE,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;AAE/C,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,EAAE,QAAQ,EAC/D,SAAS,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,EAC1D,eAAe,MAAM,EACrB,UAAU,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KACjC,YAAY,CAAC,MAAM,CA8BrB,CAAC;AAEF,eAAO,MAAM,uBAAuB,GACnC,OAAO,EACP,MAAM,SAAS,MAAM,EACrB,QAAQ,EAER,SAAS,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,EAC1D,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,MAAM,EAC3C,UAAU,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KACjC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAgBrC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getTRPCErrorFromUnknown } from "@trpc/server";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
export const makeEffectCaller = (adapter, promiseCaller, services) => {
|
|
4
|
+
const build = (path) => new Proxy(Object.assign(() => undefined, { path }), {
|
|
5
|
+
apply(_target, _this, argumentsList) {
|
|
6
|
+
return Effect.tryPromise({
|
|
7
|
+
catch: getTRPCErrorFromUnknown,
|
|
8
|
+
try: () => adapter.runWithServices(services, () => {
|
|
9
|
+
let leaf = promiseCaller;
|
|
10
|
+
for (const segment of path) {
|
|
11
|
+
leaf = leaf[segment];
|
|
12
|
+
}
|
|
13
|
+
return leaf(...argumentsList);
|
|
14
|
+
}),
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
get(_target, property) {
|
|
18
|
+
if (typeof property !== "string" || property === "then") {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return build([...path, property]);
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return build([]);
|
|
25
|
+
};
|
|
26
|
+
export const makeEffectCallerFactory = (adapter, createCaller, services) => {
|
|
27
|
+
const defaultCaller = makeEffectCaller(adapter, createCaller(), services);
|
|
28
|
+
const target = (options) => makeEffectCaller(adapter, createCaller(options), services);
|
|
29
|
+
return new Proxy(target, {
|
|
30
|
+
get(_target, property, receiver) {
|
|
31
|
+
if (property === "then") {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
if (typeof property !== "string") {
|
|
35
|
+
return Reflect.get(_target, property, receiver);
|
|
36
|
+
}
|
|
37
|
+
return Reflect.get(defaultCaller, property);
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=caller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caller.js","sourceRoot":"","sources":["../../src/testing/caller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAkB,MAAM,cAAc,CAAC;AACvE,OAAO,EAAgB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAkB9C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,OAA0D,EAC1D,aAAqB,EACrB,QAAmC,EACZ,EAAE;IACzB,MAAM,KAAK,GAAG,CAAC,IAA2B,EAAW,EAAE,CACtD,IAAI,KAAK,CACR,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EACxC;QACC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa;YAClC,OAAO,MAAM,CAAC,UAAU,CAAC;gBACxB,KAAK,EAAE,uBAAuB;gBAC9B,GAAG,EAAE,GAAG,EAAE,CACT,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE;oBACtC,IAAI,IAAI,GAAY,aAAa,CAAC;oBAClC,KAAK,MAAM,OAAO,IAAI,IAAI,EAAE,CAAC;wBAC5B,IAAI,GAAI,IAAgC,CAAC,OAAO,CAAC,CAAC;oBACnD,CAAC;oBACD,OAAQ,IAAiD,CACxD,GAAG,aAAa,CAChB,CAAC;gBACH,CAAC,CAAC;aACH,CAAC,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,QAAQ;YACpB,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACzD,OAAO,SAAS,CAAC;YAClB,CAAC;YACD,OAAO,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnC,CAAC;KACD,CACD,CAAC;IAEH,OAAO,KAAK,CAAC,EAAE,CAAyB,CAAC;AAC1C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAKtC,OAA0D,EAC1D,YAA2C,EAC3C,QAAmC,EACI,EAAE;IACzC,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,CAAC,OAAiB,EAAE,EAAE,CACpC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE5D,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACxB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ;YAC9B,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACzB,OAAO,SAAS,CAAC;YAClB,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAClC,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACjD,CAAC;YACD,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAC7C,CAAC;KACD,CAAyC,CAAC;AAC5C,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { TestContext, TestOptions, Vitest } from "@effect/vitest";
|
|
2
|
+
import type { Effect, Layer } from "effect";
|
|
3
|
+
import type { EffectTRPCAdapter } from "../adapter.js";
|
|
4
|
+
import type { EffectCallerFactory } from "./caller.js";
|
|
5
|
+
export type TrpcTest<Options, Caller, Provided> = <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(name: string, body: (trpc: EffectCallerFactory<Options, Caller>, context: TestContext) => Generator<Eff, A, never>, options?: number | TestOptions) => void;
|
|
6
|
+
export interface TrpcTester<Options, Caller, Provided> extends TrpcTest<Options, Caller, Provided> {
|
|
7
|
+
readonly skip: TrpcTest<Options, Caller, Provided>;
|
|
8
|
+
readonly skipIf: (condition: unknown) => TrpcTest<Options, Caller, Provided>;
|
|
9
|
+
readonly runIf: (condition: unknown) => TrpcTest<Options, Caller, Provided>;
|
|
10
|
+
readonly only: TrpcTest<Options, Caller, Provided>;
|
|
11
|
+
readonly each: <Item>(cases: ReadonlyArray<Item>) => <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(name: string, body: (item: Item, trpc: EffectCallerFactory<Options, Caller>, context: TestContext) => Generator<Eff, A, never>, options?: number | TestOptions) => void;
|
|
12
|
+
readonly fails: TrpcTest<Options, Caller, Provided>;
|
|
13
|
+
}
|
|
14
|
+
export type TrpcIt<Options, Caller, Provided> = Vitest.Methods & {
|
|
15
|
+
readonly effectTRPC: TrpcTester<Options, Caller, Provided>;
|
|
16
|
+
};
|
|
17
|
+
export interface TrpcTestRuntimeOptions<Options, Caller extends object, Provided, LayerError> {
|
|
18
|
+
readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
|
|
19
|
+
readonly around?: <A, E>(effect: Effect.Effect<A, E, Provided>) => Effect.Effect<A, unknown, Provided>;
|
|
20
|
+
readonly createCaller: (options?: Options) => Caller;
|
|
21
|
+
readonly layer: Layer.Layer<Provided, LayerError>;
|
|
22
|
+
}
|
|
23
|
+
export interface MakeTrpcItOptions<CreateCaller extends (...arguments_: never[]) => object, TestLayer extends Layer.Layer<any, any, never>> {
|
|
24
|
+
readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
|
|
25
|
+
readonly around?: <A, E>(effect: Effect.Effect<A, E, Layer.Success<TestLayer>>) => Effect.Effect<A, unknown, Layer.Success<TestLayer>>;
|
|
26
|
+
readonly createCaller: CreateCaller;
|
|
27
|
+
readonly layer: TestLayer;
|
|
28
|
+
}
|
|
29
|
+
export type CallerOptions<CreateCaller> = CreateCaller extends (...arguments_: infer Arguments) => object ? Arguments[0] : never;
|
|
30
|
+
export type CallerResult<CreateCaller> = CreateCaller extends (...arguments_: infer _Arguments) => infer Caller ? Caller extends object ? Caller : never : never;
|
|
31
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Layer } from "effect";
|
|
2
|
+
import type { CallerOptions, CallerResult, MakeTrpcItOptions, TrpcIt } from "./types.js";
|
|
3
|
+
export declare const makeTrpcIt: <CreateCaller extends (...arguments_: never[]) => object, TestLayer extends Layer.Layer<any, any, never>>(options: MakeTrpcItOptions<CreateCaller, TestLayer>) => TrpcIt<CallerOptions<CreateCaller>, CallerResult<CreateCaller>, Layer.Success<TestLayer>>;
|
|
4
|
+
//# sourceMappingURL=vitest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../src/testing/vitest.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,EAAS,MAAM,QAAQ,CAAC;AAMpD,OAAO,KAAK,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACN,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,UAAU,GACtB,YAAY,SAAS,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,KAAK,MAAM,EAEvD,SAAS,SAAS,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,EAE9C,SAAS,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,KACjD,MAAM,CACR,aAAa,CAAC,YAAY,CAAC,EAC3B,YAAY,CAAC,YAAY,CAAC,EAC1B,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAwCxB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { it as effectIt } from "@effect/vitest";
|
|
2
|
+
import { Effect, Exit, Layer, Scope } from "effect";
|
|
3
|
+
import { fixtureName, makeTrpcTester, } from "../internal/vitest-trpc.js";
|
|
4
|
+
export const makeTrpcIt = (options) => {
|
|
5
|
+
const fixtureIt = effectIt.extend(fixtureName, { scope: "worker" },
|
|
6
|
+
// biome-ignore lint/correctness/noEmptyPattern: Vitest fixtures require a destructured context parameter.
|
|
7
|
+
async ({}, { onCleanup }) => {
|
|
8
|
+
const scope = Effect.runSync(Scope.make());
|
|
9
|
+
onCleanup(() => Effect.runPromise(Scope.close(scope, Exit.void)));
|
|
10
|
+
try {
|
|
11
|
+
return await Effect.runPromise(Layer.buildWithScope(options.layer, scope));
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
await Effect.runPromise(Scope.close(scope, Exit.void));
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const effectTRPC = makeTrpcTester(fixtureIt, options);
|
|
19
|
+
return new Proxy(effectIt, {
|
|
20
|
+
get(target, property, receiver) {
|
|
21
|
+
if (property === "effectTRPC") {
|
|
22
|
+
return effectTRPC;
|
|
23
|
+
}
|
|
24
|
+
return Reflect.get(target, property, receiver);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=vitest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.js","sourceRoot":"","sources":["../../src/testing/vitest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAEN,WAAW,EACX,cAAc,GACd,MAAM,4BAA4B,CAAC;AAQpC,MAAM,CAAC,MAAM,UAAU,GAAG,CAKzB,OAAmD,EAKlD,EAAE;IAKH,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAChC,WAAW,EACX,EAAE,KAAK,EAAE,QAAQ,EAAE;IACnB,0GAA0G;IAC1G,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAElE,IAAI,CAAC;YACJ,OAAO,MAAM,MAAM,CAAC,UAAU,CAC7B,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAC1C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACvD,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC,CACD,CAAC;IAEF,MAAM,UAAU,GAAG,cAAc,CAChC,SAAgD,EAChD,OAEI,CACJ,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE;QAC1B,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ;YAC7B,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC/B,OAAO,UAAU,CAAC;YACnB,CAAC;YACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChD,CAAC;KACD,CAAsC,CAAC;AACzC,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { type EffectCaller, type EffectCallerFactory, makeEffectCaller, makeEffectCallerFactory, } from "./testing/caller.js";
|
|
2
|
+
export type { MakeTrpcItOptions, TrpcIt, TrpcTest, TrpcTester, } from "./testing/types.js";
|
|
3
|
+
export { makeTrpcIt } from "./testing/vitest.js";
|
|
4
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACX,iBAAiB,EACjB,MAAM,EACN,QAAQ,EACR,UAAU,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TRPCError } from "@trpc/server";
|
|
2
|
+
import type { Effect } from "effect";
|
|
3
|
+
export type ProcedureKind = "mutation" | "query";
|
|
4
|
+
export interface ProcedureInfo {
|
|
5
|
+
readonly captureStackTrace: () => string | undefined;
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly type: ProcedureKind;
|
|
8
|
+
}
|
|
9
|
+
export interface EffectTRPCErrorContext extends ProcedureInfo {
|
|
10
|
+
readonly origin: "defect" | "failure";
|
|
11
|
+
}
|
|
12
|
+
export type EffectTRPCErrorMapper = (error: unknown, context: EffectTRPCErrorContext) => TRPCError | undefined;
|
|
13
|
+
export type EffectTRPCInstrument = <A, E, R>(effect: Effect.Effect<A, E, R>, procedure: ProcedureInfo) => Effect.Effect<A, E, R>;
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC5D,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,MAAM,qBAAqB,GAAG,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,sBAAsB,KAC3B,SAAS,GAAG,SAAS,CAAC;AAE3B,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,SAAS,EAAE,aAAa,KACpB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shivaedev/effect-trpc",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Effect-native procedures and testing for tRPC",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ShivaeDev/platform.git",
|
|
10
|
+
"directory": "packages/effect-trpc"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/effect-trpc#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/ShivaeDev/platform/issues"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=24"
|
|
18
|
+
},
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"src",
|
|
23
|
+
"CHANGELOG.md",
|
|
24
|
+
"README.md"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"source": "./src/index.ts",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./testing": {
|
|
34
|
+
"types": "./dist/testing.d.ts",
|
|
35
|
+
"source": "./src/testing.ts",
|
|
36
|
+
"import": "./dist/testing.js",
|
|
37
|
+
"default": "./dist/testing.js"
|
|
38
|
+
},
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public",
|
|
43
|
+
"provenance": true
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@effect/vitest": "4.0.0-beta.102",
|
|
47
|
+
"@trpc/server": "11.18.0",
|
|
48
|
+
"effect": "4.0.0-beta.102"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"@effect/vitest": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@effect/vitest": "4.0.0-beta.102",
|
|
57
|
+
"@trpc/server": "11.18.0",
|
|
58
|
+
"@types/node": "24.10.1",
|
|
59
|
+
"@typescript/native": "npm:typescript@7.0.2",
|
|
60
|
+
"effect": "4.0.0-beta.102",
|
|
61
|
+
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
62
|
+
"vitest": "4.1.9"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "node --eval \"import('node:fs').then(({ rmSync }) => rmSync('dist', { force: true, recursive: true }))\" && tsc6 --project tsconfig.build.json",
|
|
66
|
+
"check": "biome check .",
|
|
67
|
+
"test": "vitest run",
|
|
68
|
+
"test:package": "node scripts/test-package.mjs",
|
|
69
|
+
"typecheck": "tsc --noEmit",
|
|
70
|
+
"typecheck:compat": "tsc6 --noEmit",
|
|
71
|
+
"ready": "pnpm check && pnpm typecheck && pnpm typecheck:compat && pnpm test && pnpm build && pnpm test:package"
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/adapter.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
inferProcedureBuilderResolverOptions,
|
|
3
|
+
TRPCProcedureBuilder,
|
|
4
|
+
} from "@trpc/server";
|
|
5
|
+
import type { Context, ManagedRuntime } from "effect";
|
|
6
|
+
import { makeContextBridge } from "./internal/context-bridge.js";
|
|
7
|
+
import { makeRuntimeBridge } from "./internal/runtime.js";
|
|
8
|
+
import { EffectProcedureBuilder } from "./procedure.js";
|
|
9
|
+
import type { EffectProcedureRequestServices } from "./request-services.js";
|
|
10
|
+
import type { EffectTRPCErrorMapper, EffectTRPCInstrument } from "./types.js";
|
|
11
|
+
|
|
12
|
+
export interface MakeEffectTRPCOptions<Requirements, RuntimeError> {
|
|
13
|
+
readonly instrument?: EffectTRPCInstrument;
|
|
14
|
+
readonly mapError?: EffectTRPCErrorMapper;
|
|
15
|
+
readonly runtime: ManagedRuntime.ManagedRuntime<Requirements, RuntimeError>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface EffectTRPCAdapter<Requirements> {
|
|
19
|
+
readonly procedure: <
|
|
20
|
+
Context,
|
|
21
|
+
Meta,
|
|
22
|
+
ContextOverrides,
|
|
23
|
+
InputIn,
|
|
24
|
+
InputOut,
|
|
25
|
+
OutputIn,
|
|
26
|
+
OutputOut,
|
|
27
|
+
ProvidedServices,
|
|
28
|
+
LayerError,
|
|
29
|
+
>(
|
|
30
|
+
builder: TRPCProcedureBuilder<
|
|
31
|
+
Context,
|
|
32
|
+
Meta,
|
|
33
|
+
ContextOverrides,
|
|
34
|
+
InputIn,
|
|
35
|
+
InputOut,
|
|
36
|
+
OutputIn,
|
|
37
|
+
OutputOut,
|
|
38
|
+
false
|
|
39
|
+
>,
|
|
40
|
+
requestServices: EffectProcedureRequestServices<
|
|
41
|
+
inferProcedureBuilderResolverOptions<
|
|
42
|
+
TRPCProcedureBuilder<
|
|
43
|
+
Context,
|
|
44
|
+
Meta,
|
|
45
|
+
ContextOverrides,
|
|
46
|
+
InputIn,
|
|
47
|
+
InputOut,
|
|
48
|
+
OutputIn,
|
|
49
|
+
OutputOut,
|
|
50
|
+
false
|
|
51
|
+
>
|
|
52
|
+
>["ctx"],
|
|
53
|
+
ProvidedServices,
|
|
54
|
+
LayerError
|
|
55
|
+
>,
|
|
56
|
+
) => EffectProcedureBuilder<
|
|
57
|
+
Context,
|
|
58
|
+
Meta,
|
|
59
|
+
ContextOverrides,
|
|
60
|
+
InputIn,
|
|
61
|
+
InputOut,
|
|
62
|
+
OutputIn,
|
|
63
|
+
OutputOut,
|
|
64
|
+
ProvidedServices,
|
|
65
|
+
LayerError,
|
|
66
|
+
Requirements
|
|
67
|
+
>;
|
|
68
|
+
readonly runWithServices: <Services, Value>(
|
|
69
|
+
services: Context.Context<Services>,
|
|
70
|
+
evaluate: () => Value,
|
|
71
|
+
) => Value;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const makeEffectTRPC = <Requirements, RuntimeError = never>(
|
|
75
|
+
options: MakeEffectTRPCOptions<Requirements, RuntimeError>,
|
|
76
|
+
): EffectTRPCAdapter<Requirements> => {
|
|
77
|
+
const contextBridge = makeContextBridge();
|
|
78
|
+
const runtime = makeRuntimeBridge(options.runtime, contextBridge, options);
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
procedure: (builder, requestServices) =>
|
|
82
|
+
new EffectProcedureBuilder(builder, requestServices, runtime) as never,
|
|
83
|
+
runWithServices: contextBridge.run,
|
|
84
|
+
};
|
|
85
|
+
};
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { TRPCError } from "@trpc/server";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
|
|
4
|
+
export const fail = (
|
|
5
|
+
code: TRPCError["code"],
|
|
6
|
+
message: string,
|
|
7
|
+
cause?: unknown,
|
|
8
|
+
): Effect.Effect<never, TRPCError> =>
|
|
9
|
+
Effect.fail(new TRPCError({ cause, code, message }));
|
|
10
|
+
|
|
11
|
+
export const badRequest = (message: string, cause?: unknown) =>
|
|
12
|
+
fail("BAD_REQUEST", message, cause);
|
|
13
|
+
|
|
14
|
+
export const unauthorized = (message: string, cause?: unknown) =>
|
|
15
|
+
fail("UNAUTHORIZED", message, cause);
|
|
16
|
+
|
|
17
|
+
export const forbidden = (message: string, cause?: unknown) =>
|
|
18
|
+
fail("FORBIDDEN", message, cause);
|
|
19
|
+
|
|
20
|
+
export const notFound = (message: string, cause?: unknown) =>
|
|
21
|
+
fail("NOT_FOUND", message, cause);
|
|
22
|
+
|
|
23
|
+
export const conflict = (message: string, cause?: unknown) =>
|
|
24
|
+
fail("CONFLICT", message, cause);
|
|
25
|
+
|
|
26
|
+
export const preconditionFailed = (message: string, cause?: unknown) =>
|
|
27
|
+
fail("PRECONDITION_FAILED", message, cause);
|
|
28
|
+
|
|
29
|
+
export const internalServerError = (message: string, cause?: unknown) =>
|
|
30
|
+
fail("INTERNAL_SERVER_ERROR", message, cause);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type EffectTRPCAdapter,
|
|
3
|
+
type MakeEffectTRPCOptions,
|
|
4
|
+
makeEffectTRPC,
|
|
5
|
+
} from "./adapter.js";
|
|
6
|
+
export {
|
|
7
|
+
badRequest,
|
|
8
|
+
conflict,
|
|
9
|
+
fail,
|
|
10
|
+
forbidden,
|
|
11
|
+
internalServerError,
|
|
12
|
+
notFound,
|
|
13
|
+
preconditionFailed,
|
|
14
|
+
unauthorized,
|
|
15
|
+
} from "./errors.js";
|
|
16
|
+
export type { EffectProcedureBuilder } from "./procedure.js";
|
|
17
|
+
export {
|
|
18
|
+
type EffectProcedureRequestServices,
|
|
19
|
+
extendRequestServices,
|
|
20
|
+
makeRequestServices,
|
|
21
|
+
} from "./request-services.js";
|
|
22
|
+
export type {
|
|
23
|
+
EffectTRPCErrorContext,
|
|
24
|
+
EffectTRPCErrorMapper,
|
|
25
|
+
EffectTRPCInstrument,
|
|
26
|
+
ProcedureInfo,
|
|
27
|
+
ProcedureKind,
|
|
28
|
+
} from "./types.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import type { Context } from "effect";
|
|
3
|
+
|
|
4
|
+
export interface ContextBridge {
|
|
5
|
+
readonly current: () => Context.Context<never> | undefined;
|
|
6
|
+
readonly run: <Services, Value>(
|
|
7
|
+
services: Context.Context<Services>,
|
|
8
|
+
evaluate: () => Value,
|
|
9
|
+
) => Value;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const makeContextBridge = (): ContextBridge => {
|
|
13
|
+
const storage = new AsyncLocalStorage<Context.Context<never>>();
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
current: () => storage.getStore(),
|
|
17
|
+
run: (services, evaluate) =>
|
|
18
|
+
storage.run(services as Context.Context<never>, evaluate),
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { EffectProcedureRequestServices } from "../request-services.js";
|
|
3
|
+
import type { ProcedureInfo } from "../types.js";
|
|
4
|
+
import type { EffectProcedureResolver } from "./procedure-types.js";
|
|
5
|
+
import type { RuntimeBridge } from "./runtime.js";
|
|
6
|
+
|
|
7
|
+
interface ProcedureInvocation<Context, Input> {
|
|
8
|
+
readonly ctx: Context;
|
|
9
|
+
readonly input: Input;
|
|
10
|
+
readonly path: string;
|
|
11
|
+
readonly signal?: AbortSignal;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const makeProcedureHandler = <
|
|
15
|
+
RuntimeRequirements,
|
|
16
|
+
Context,
|
|
17
|
+
Input,
|
|
18
|
+
ProvidedServices,
|
|
19
|
+
LayerError,
|
|
20
|
+
Output,
|
|
21
|
+
>(
|
|
22
|
+
runtime: RuntimeBridge<RuntimeRequirements>,
|
|
23
|
+
resolver: EffectProcedureResolver<
|
|
24
|
+
Input,
|
|
25
|
+
ProvidedServices | NoInfer<RuntimeRequirements>,
|
|
26
|
+
Output
|
|
27
|
+
>,
|
|
28
|
+
requestServices: EffectProcedureRequestServices<
|
|
29
|
+
Context,
|
|
30
|
+
ProvidedServices,
|
|
31
|
+
LayerError
|
|
32
|
+
>,
|
|
33
|
+
procedure: Omit<ProcedureInfo, "path">,
|
|
34
|
+
) => {
|
|
35
|
+
const tracedResolver = Effect.fnUntraced(resolver);
|
|
36
|
+
|
|
37
|
+
return async (invocation: ProcedureInvocation<Context, Input>) => {
|
|
38
|
+
const provided = Effect.suspend(() =>
|
|
39
|
+
tracedResolver(invocation.input).pipe(
|
|
40
|
+
Effect.provide(requestServices.layer(invocation.ctx)),
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
return await runtime.runEffect(provided, {
|
|
44
|
+
procedure: { ...procedure, path: invocation.path },
|
|
45
|
+
...(invocation.signal === undefined ? {} : { signal: invocation.signal }),
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
inferProcedureBuilderResolverOptions,
|
|
3
|
+
TRPCProcedureBuilder,
|
|
4
|
+
TRPCUnsetMarker,
|
|
5
|
+
} from "@trpc/server";
|
|
6
|
+
import type { Effect } from "effect";
|
|
7
|
+
|
|
8
|
+
export type AnyProcedureBuilder = TRPCProcedureBuilder<
|
|
9
|
+
// biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
|
|
10
|
+
any,
|
|
11
|
+
// biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
|
|
12
|
+
any,
|
|
13
|
+
// biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
|
|
14
|
+
any,
|
|
15
|
+
// biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
|
|
16
|
+
any,
|
|
17
|
+
// biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
|
|
18
|
+
any,
|
|
19
|
+
// biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
|
|
20
|
+
any,
|
|
21
|
+
// biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
|
|
22
|
+
any,
|
|
23
|
+
false
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
export type DefaultValue<Value, Fallback> = Value extends TRPCUnsetMarker
|
|
27
|
+
? Fallback
|
|
28
|
+
: Value;
|
|
29
|
+
|
|
30
|
+
export type IntersectIfDefined<Value, With> = Value extends TRPCUnsetMarker
|
|
31
|
+
? With
|
|
32
|
+
: With extends TRPCUnsetMarker
|
|
33
|
+
? Value
|
|
34
|
+
: Value & With;
|
|
35
|
+
|
|
36
|
+
export type ResolverContext<Builder extends AnyProcedureBuilder> =
|
|
37
|
+
inferProcedureBuilderResolverOptions<Builder>["ctx"];
|
|
38
|
+
|
|
39
|
+
export type ProcedureEffect<Requirements> = Effect.Effect<
|
|
40
|
+
// biome-ignore lint/suspicious/noExplicitAny: success is inferred from each yielded Effect
|
|
41
|
+
any,
|
|
42
|
+
// biome-ignore lint/suspicious/noExplicitAny: errors are inferred from each yielded Effect
|
|
43
|
+
any,
|
|
44
|
+
Requirements
|
|
45
|
+
>;
|
|
46
|
+
|
|
47
|
+
export type EffectProcedureResolver<Input, Requirements, Output> = (
|
|
48
|
+
input: Input,
|
|
49
|
+
) => Generator<ProcedureEffect<Requirements>, Output, never>;
|