0.1.19 (#20)
Co-authored-by: Julien Valverdé <julien.valverde@mailo.com> Reviewed-on: #20
This commit was merged in pull request #20.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thilawyn/thilalib",
|
||||
"version": "0.1.18",
|
||||
"version": "0.1.19",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"./dist"
|
||||
|
||||
@@ -3,12 +3,12 @@ import { makeObservable, observable, type CreateObservableOptions } from "mobx"
|
||||
import { mapValues } from "remeda"
|
||||
|
||||
|
||||
interface ObservableClassSelf {
|
||||
export interface ObservableClassSelf {
|
||||
new(...args: any[]): Schema.Struct.Type<Schema.Struct.Fields>
|
||||
readonly fields: { readonly [K in keyof Schema.Struct.Fields]: Schema.Struct.Fields[K] }
|
||||
}
|
||||
|
||||
interface ObservableClassOptions extends Omit<CreateObservableOptions, "proxy"> {}
|
||||
export interface ObservableClassOptions extends Omit<CreateObservableOptions, "proxy"> {}
|
||||
|
||||
export const ObservableClass = (options?: ObservableClassOptions) =>
|
||||
<Self extends ObservableClassSelf>(self: Self) =>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Schema } from "@effect/schema"
|
||||
|
||||
|
||||
export const Email = Schema.pattern(
|
||||
export const email = Schema.pattern(
|
||||
/^(?!\.)(?!.*\.\.)([A-Z0-9_+-.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}$/i,
|
||||
|
||||
{
|
||||
identifier: "Email",
|
||||
identifier: "email",
|
||||
title: "email",
|
||||
message: () => "Not an email address",
|
||||
},
|
||||
@@ -1,6 +1,6 @@
|
||||
export * from "./Class"
|
||||
export * from "./DateTime"
|
||||
export * from "./Email"
|
||||
export * from "./email"
|
||||
export * from "./encodedAsPrismaJsonValue"
|
||||
export * from "./Kind"
|
||||
export * as MobX from "./MobX"
|
||||
|
||||
@@ -6,7 +6,9 @@ import type { IncomingMessage } from "node:http"
|
||||
import type { WebSocket } from "ws"
|
||||
|
||||
|
||||
export interface TRPCContext<R> {
|
||||
export interface TRPCContext<R> extends TRPCContextRuntime<R>, TRPCContextTransaction {}
|
||||
|
||||
export interface TRPCContextRuntime<R> {
|
||||
readonly runtime: Runtime.Runtime<R>
|
||||
|
||||
readonly run: <A, E>(
|
||||
@@ -18,12 +20,14 @@ export interface TRPCContext<R> {
|
||||
effect: Effect.Effect<A, E, R>,
|
||||
options?: Runtime.RunForkOptions,
|
||||
) => RuntimeFiber<A, TRPCError>
|
||||
}
|
||||
|
||||
readonly transaction: TRPCContextTransaction
|
||||
export interface TRPCContextTransaction {
|
||||
readonly transaction: TRPCTransaction
|
||||
}
|
||||
|
||||
|
||||
export type TRPCContextTransaction = Data.TaggedEnum<{
|
||||
export type TRPCTransaction = Data.TaggedEnum<{
|
||||
readonly Express: {
|
||||
readonly req: express.Request
|
||||
readonly res: express.Response
|
||||
@@ -35,4 +39,4 @@ export type TRPCContextTransaction = Data.TaggedEnum<{
|
||||
}
|
||||
}>
|
||||
|
||||
export const TRPCContextTransactionEnum = Data.taggedEnum<TRPCContextTransaction>()
|
||||
export const TRPCTransactionEnum = Data.taggedEnum<TRPCTransaction>()
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { CreateExpressContextOptions } from "@trpc/server/adapters/express"
|
||||
import type { CreateWSSContextFnOptions } from "@trpc/server/adapters/ws"
|
||||
import { Context, Effect, Layer, Runtime } from "effect"
|
||||
import { createTRCPErrorMapper } from "./createTRCPErrorMapper"
|
||||
import { TRPCContextTransactionEnum, type TRPCContext, type TRPCContextTransaction } from "./TRPCContext"
|
||||
import { TRPCTransactionEnum, type TRPCContext, type TRPCTransaction } from "./TRPCContext"
|
||||
|
||||
|
||||
export const Identifier = "@thilalib/TRPC/TRPCContextCreator"
|
||||
@@ -10,7 +10,7 @@ export const Identifier = "@thilalib/TRPC/TRPCContextCreator"
|
||||
export interface TRPCContextCreator<R> extends Context.Tag<typeof Identifier, TRPCContextCreatorService<R>> {}
|
||||
|
||||
export interface TRPCContextCreatorService<R> {
|
||||
readonly createContext: (transaction: TRPCContextTransaction) => TRPCContext<R>
|
||||
readonly createContext: (transaction: TRPCTransaction) => TRPCContext<R>
|
||||
readonly createExpressContext: (context: CreateExpressContextOptions) => TRPCContext<R>
|
||||
readonly createWebSocketContext: (context: CreateWSSContextFnOptions) => TRPCContext<R>
|
||||
}
|
||||
@@ -41,16 +41,16 @@ export const make = <R>() => {
|
||||
options,
|
||||
)
|
||||
|
||||
const createContext = (transaction: TRPCContextTransaction) => ({
|
||||
const createContext = (transaction: TRPCTransaction) => ({
|
||||
runtime,
|
||||
run,
|
||||
fork,
|
||||
transaction,
|
||||
})
|
||||
const createExpressContext = (context: CreateExpressContextOptions) => createContext(TRPCContextTransactionEnum.Express(context))
|
||||
const createWebSocketContext = (context: CreateWSSContextFnOptions) => createContext(TRPCContextTransactionEnum.WebSocket(context))
|
||||
const createExpressContext = (context: CreateExpressContextOptions) => createContext(TRPCTransactionEnum.Express(context))
|
||||
const createWebSocketContext = (context: CreateWSSContextFnOptions) => createContext(TRPCTransactionEnum.WebSocket(context))
|
||||
|
||||
return { createContext, createExpressContext, createWebSocketContext }
|
||||
return { createContext, createExpressContext, createWebSocketContext } as const
|
||||
}))
|
||||
|
||||
return { TRPCContextCreator, TRPCContextCreatorLive } as const
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { Effect, Match } from "effect"
|
||||
import type { TRPCContextTransaction } from "./TRPCContext"
|
||||
import { importTRPCServer } from "./importTRPCServer"
|
||||
|
||||
|
||||
export const ExpressOnly = importTRPCServer.pipe(Effect.map(({
|
||||
experimental_standaloneMiddleware,
|
||||
TRPCError,
|
||||
}) => experimental_standaloneMiddleware<{
|
||||
ctx: { readonly transaction: TRPCContextTransaction }
|
||||
}>().create(opts =>
|
||||
Match.value(opts.ctx.transaction).pipe(
|
||||
Match.tag("Express", transaction =>
|
||||
opts.next({ ctx: { transaction } })
|
||||
),
|
||||
|
||||
Match.orElse(() => {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Only Express transport is supported by this procedure",
|
||||
})
|
||||
}),
|
||||
)
|
||||
)))
|
||||
|
||||
export const WebSocketOnly = importTRPCServer.pipe(Effect.map(({
|
||||
experimental_standaloneMiddleware,
|
||||
TRPCError,
|
||||
}) => experimental_standaloneMiddleware<{
|
||||
ctx: { readonly transaction: TRPCContextTransaction }
|
||||
}>().create(opts =>
|
||||
Match.value(opts.ctx.transaction).pipe(
|
||||
Match.tag("WebSocket", transaction =>
|
||||
opts.next({ ctx: { transaction } })
|
||||
),
|
||||
|
||||
Match.orElse(() => {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Only WebSocket transport is supported by this procedure",
|
||||
})
|
||||
}),
|
||||
)
|
||||
)))
|
||||
33
src/TRPC/middlewares/DecodeInput.ts
Normal file
33
src/TRPC/middlewares/DecodeInput.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Schema } from "@effect/schema"
|
||||
import type { ParseOptions } from "@effect/schema/AST"
|
||||
import { Effect } from "effect"
|
||||
import { importTRPCServer } from "../importTRPCServer"
|
||||
import type { TRPCContextRuntime } from "../TRPCContext"
|
||||
|
||||
|
||||
export const DecodeInput = <A, I>(
|
||||
schema: Schema.Schema<A, I>,
|
||||
options?: ParseOptions,
|
||||
) => Effect.gen(function*() {
|
||||
const { experimental_standaloneMiddleware, TRPCError } = yield* importTRPCServer
|
||||
|
||||
const decode = (value: I) => Schema.decode(schema, options)(value).pipe(
|
||||
Effect.matchEffect({
|
||||
onSuccess: Effect.succeed,
|
||||
onFailure: e => Effect.fail(new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Could not decode input",
|
||||
cause: e,
|
||||
})),
|
||||
})
|
||||
)
|
||||
|
||||
return experimental_standaloneMiddleware<{
|
||||
ctx: TRPCContextRuntime<any>
|
||||
input: I
|
||||
}>().create(
|
||||
async ({ ctx, input, next }) => next({
|
||||
ctx: { decodedInput: await ctx.run(decode(input)) } as const
|
||||
})
|
||||
)
|
||||
})
|
||||
22
src/TRPC/middlewares/ExpressOnly.ts
Normal file
22
src/TRPC/middlewares/ExpressOnly.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Effect, identity, Match } from "effect"
|
||||
import { importTRPCServer } from "../importTRPCServer"
|
||||
import type { TRPCContextTransaction } from "../TRPCContext"
|
||||
|
||||
|
||||
export const ExpressOnly = importTRPCServer.pipe(Effect.map(({
|
||||
experimental_standaloneMiddleware,
|
||||
TRPCError,
|
||||
}) => experimental_standaloneMiddleware<{
|
||||
ctx: TRPCContextTransaction
|
||||
}>().create(({ ctx, next }) => next({
|
||||
ctx: Match.value(ctx.transaction).pipe(
|
||||
Match.tag("Express", identity),
|
||||
|
||||
Match.orElse(() => {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Only Express transport is supported by this procedure",
|
||||
})
|
||||
}),
|
||||
)
|
||||
}))))
|
||||
22
src/TRPC/middlewares/WebSocketOnly.ts
Normal file
22
src/TRPC/middlewares/WebSocketOnly.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Effect, identity, Match } from "effect"
|
||||
import { importTRPCServer } from "../importTRPCServer"
|
||||
import type { TRPCContextTransaction } from "../TRPCContext"
|
||||
|
||||
|
||||
export const WebSocketOnly = importTRPCServer.pipe(Effect.map(({
|
||||
experimental_standaloneMiddleware,
|
||||
TRPCError,
|
||||
}) => experimental_standaloneMiddleware<{
|
||||
ctx: TRPCContextTransaction
|
||||
}>().create(({ ctx, next }) => next({
|
||||
ctx: Match.value(ctx.transaction).pipe(
|
||||
Match.tag("WebSocket", identity),
|
||||
|
||||
Match.orElse(() => {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Only WebSocket transport is supported by this procedure",
|
||||
})
|
||||
}),
|
||||
)
|
||||
}))))
|
||||
3
src/TRPC/middlewares/index.ts
Normal file
3
src/TRPC/middlewares/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./DecodeInput"
|
||||
export * from "./ExpressOnly"
|
||||
export * from "./WebSocketOnly"
|
||||
Reference in New Issue
Block a user