@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,81 @@
|
|
|
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
|
+
|
|
6
|
+
export type TrpcTest<Options, Caller, Provided> = <
|
|
7
|
+
A,
|
|
8
|
+
Eff extends Effect.Effect<unknown, unknown, Provided>,
|
|
9
|
+
>(
|
|
10
|
+
name: string,
|
|
11
|
+
body: (
|
|
12
|
+
trpc: EffectCallerFactory<Options, Caller>,
|
|
13
|
+
context: TestContext,
|
|
14
|
+
) => Generator<Eff, A, never>,
|
|
15
|
+
options?: number | TestOptions,
|
|
16
|
+
) => void;
|
|
17
|
+
|
|
18
|
+
export interface TrpcTester<Options, Caller, Provided>
|
|
19
|
+
extends TrpcTest<Options, Caller, Provided> {
|
|
20
|
+
readonly skip: TrpcTest<Options, Caller, Provided>;
|
|
21
|
+
readonly skipIf: (condition: unknown) => TrpcTest<Options, Caller, Provided>;
|
|
22
|
+
readonly runIf: (condition: unknown) => TrpcTest<Options, Caller, Provided>;
|
|
23
|
+
readonly only: TrpcTest<Options, Caller, Provided>;
|
|
24
|
+
readonly each: <Item>(
|
|
25
|
+
cases: ReadonlyArray<Item>,
|
|
26
|
+
) => <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(
|
|
27
|
+
name: string,
|
|
28
|
+
body: (
|
|
29
|
+
item: Item,
|
|
30
|
+
trpc: EffectCallerFactory<Options, Caller>,
|
|
31
|
+
context: TestContext,
|
|
32
|
+
) => Generator<Eff, A, never>,
|
|
33
|
+
options?: number | TestOptions,
|
|
34
|
+
) => void;
|
|
35
|
+
readonly fails: TrpcTest<Options, Caller, Provided>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type TrpcIt<Options, Caller, Provided> = Vitest.Methods & {
|
|
39
|
+
readonly effectTRPC: TrpcTester<Options, Caller, Provided>;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export interface TrpcTestRuntimeOptions<
|
|
43
|
+
Options,
|
|
44
|
+
Caller extends object,
|
|
45
|
+
Provided,
|
|
46
|
+
LayerError,
|
|
47
|
+
> {
|
|
48
|
+
readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
|
|
49
|
+
readonly around?: <A, E>(
|
|
50
|
+
effect: Effect.Effect<A, E, Provided>,
|
|
51
|
+
) => Effect.Effect<A, unknown, Provided>;
|
|
52
|
+
readonly createCaller: (options?: Options) => Caller;
|
|
53
|
+
readonly layer: Layer.Layer<Provided, LayerError>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface MakeTrpcItOptions<
|
|
57
|
+
CreateCaller extends (...arguments_: never[]) => object,
|
|
58
|
+
// biome-ignore lint/suspicious/noExplicitAny: Layer output and error are recovered with Layer utility types
|
|
59
|
+
TestLayer extends Layer.Layer<any, any, never>,
|
|
60
|
+
> {
|
|
61
|
+
readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
|
|
62
|
+
readonly around?: <A, E>(
|
|
63
|
+
effect: Effect.Effect<A, E, Layer.Success<TestLayer>>,
|
|
64
|
+
) => Effect.Effect<A, unknown, Layer.Success<TestLayer>>;
|
|
65
|
+
readonly createCaller: CreateCaller;
|
|
66
|
+
readonly layer: TestLayer;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type CallerOptions<CreateCaller> = CreateCaller extends (
|
|
70
|
+
...arguments_: infer Arguments
|
|
71
|
+
) => object
|
|
72
|
+
? Arguments[0]
|
|
73
|
+
: never;
|
|
74
|
+
|
|
75
|
+
export type CallerResult<CreateCaller> = CreateCaller extends (
|
|
76
|
+
...arguments_: infer _Arguments
|
|
77
|
+
) => infer Caller
|
|
78
|
+
? Caller extends object
|
|
79
|
+
? Caller
|
|
80
|
+
: never
|
|
81
|
+
: never;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { it as effectIt } from "@effect/vitest";
|
|
2
|
+
import { Effect, Exit, Layer, Scope } from "effect";
|
|
3
|
+
import {
|
|
4
|
+
type FixtureTestApi,
|
|
5
|
+
fixtureName,
|
|
6
|
+
makeTrpcTester,
|
|
7
|
+
} from "../internal/vitest-trpc.js";
|
|
8
|
+
import type {
|
|
9
|
+
CallerOptions,
|
|
10
|
+
CallerResult,
|
|
11
|
+
MakeTrpcItOptions,
|
|
12
|
+
TrpcIt,
|
|
13
|
+
} from "./types.js";
|
|
14
|
+
|
|
15
|
+
export const makeTrpcIt = <
|
|
16
|
+
CreateCaller extends (...arguments_: never[]) => object,
|
|
17
|
+
// biome-ignore lint/suspicious/noExplicitAny: Layer output and error are recovered with Layer utility types
|
|
18
|
+
TestLayer extends Layer.Layer<any, any, never>,
|
|
19
|
+
>(
|
|
20
|
+
options: MakeTrpcItOptions<CreateCaller, TestLayer>,
|
|
21
|
+
): TrpcIt<
|
|
22
|
+
CallerOptions<CreateCaller>,
|
|
23
|
+
CallerResult<CreateCaller>,
|
|
24
|
+
Layer.Success<TestLayer>
|
|
25
|
+
> => {
|
|
26
|
+
type Options = CallerOptions<CreateCaller>;
|
|
27
|
+
type Caller = CallerResult<CreateCaller>;
|
|
28
|
+
type Provided = Layer.Success<TestLayer>;
|
|
29
|
+
|
|
30
|
+
const fixtureIt = effectIt.extend(
|
|
31
|
+
fixtureName,
|
|
32
|
+
{ scope: "worker" },
|
|
33
|
+
// biome-ignore lint/correctness/noEmptyPattern: Vitest fixtures require a destructured context parameter.
|
|
34
|
+
async ({}, { onCleanup }) => {
|
|
35
|
+
const scope = Effect.runSync(Scope.make());
|
|
36
|
+
onCleanup(() => Effect.runPromise(Scope.close(scope, Exit.void)));
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
return await Effect.runPromise(
|
|
40
|
+
Layer.buildWithScope(options.layer, scope),
|
|
41
|
+
);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
await Effect.runPromise(Scope.close(scope, Exit.void));
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const effectTRPC = makeTrpcTester(
|
|
50
|
+
fixtureIt as unknown as FixtureTestApi<Provided>,
|
|
51
|
+
options as unknown as Parameters<
|
|
52
|
+
typeof makeTrpcTester<Options, Caller, Provided, Layer.Error<TestLayer>>
|
|
53
|
+
>[1],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return new Proxy(effectIt, {
|
|
57
|
+
get(target, property, receiver) {
|
|
58
|
+
if (property === "effectTRPC") {
|
|
59
|
+
return effectTRPC;
|
|
60
|
+
}
|
|
61
|
+
return Reflect.get(target, property, receiver);
|
|
62
|
+
},
|
|
63
|
+
}) as TrpcIt<Options, Caller, Provided>;
|
|
64
|
+
};
|
package/src/testing.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type EffectCaller,
|
|
3
|
+
type EffectCallerFactory,
|
|
4
|
+
makeEffectCaller,
|
|
5
|
+
makeEffectCallerFactory,
|
|
6
|
+
} from "./testing/caller.js";
|
|
7
|
+
export type {
|
|
8
|
+
MakeTrpcItOptions,
|
|
9
|
+
TrpcIt,
|
|
10
|
+
TrpcTest,
|
|
11
|
+
TrpcTester,
|
|
12
|
+
} from "./testing/types.js";
|
|
13
|
+
export { makeTrpcIt } from "./testing/vitest.js";
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { TRPCError } from "@trpc/server";
|
|
2
|
+
import type { Effect } from "effect";
|
|
3
|
+
|
|
4
|
+
export type ProcedureKind = "mutation" | "query";
|
|
5
|
+
|
|
6
|
+
export interface ProcedureInfo {
|
|
7
|
+
readonly captureStackTrace: () => string | undefined;
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly type: ProcedureKind;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface EffectTRPCErrorContext extends ProcedureInfo {
|
|
13
|
+
readonly origin: "defect" | "failure";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type EffectTRPCErrorMapper = (
|
|
17
|
+
error: unknown,
|
|
18
|
+
context: EffectTRPCErrorContext,
|
|
19
|
+
) => TRPCError | undefined;
|
|
20
|
+
|
|
21
|
+
export type EffectTRPCInstrument = <A, E, R>(
|
|
22
|
+
effect: Effect.Effect<A, E, R>,
|
|
23
|
+
procedure: ProcedureInfo,
|
|
24
|
+
) => Effect.Effect<A, E, R>;
|