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",
|
"name": "@thilawyn/thilalib",
|
||||||
"version": "0.1.18",
|
"version": "0.1.19",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
"./dist"
|
"./dist"
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import { makeObservable, observable, type CreateObservableOptions } from "mobx"
|
|||||||
import { mapValues } from "remeda"
|
import { mapValues } from "remeda"
|
||||||
|
|
||||||
|
|
||||||
interface ObservableClassSelf {
|
export interface ObservableClassSelf {
|
||||||
new(...args: any[]): Schema.Struct.Type<Schema.Struct.Fields>
|
new(...args: any[]): Schema.Struct.Type<Schema.Struct.Fields>
|
||||||
readonly fields: { readonly [K in keyof Schema.Struct.Fields]: Schema.Struct.Fields[K] }
|
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) =>
|
export const ObservableClass = (options?: ObservableClassOptions) =>
|
||||||
<Self extends ObservableClassSelf>(self: Self) =>
|
<Self extends ObservableClassSelf>(self: Self) =>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Schema } from "@effect/schema"
|
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,
|
/^(?!\.)(?!.*\.\.)([A-Z0-9_+-.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}$/i,
|
||||||
|
|
||||||
{
|
{
|
||||||
identifier: "Email",
|
identifier: "email",
|
||||||
title: "email",
|
title: "email",
|
||||||
message: () => "Not an email address",
|
message: () => "Not an email address",
|
||||||
},
|
},
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
export * from "./Class"
|
export * from "./Class"
|
||||||
export * from "./DateTime"
|
export * from "./DateTime"
|
||||||
export * from "./Email"
|
export * from "./email"
|
||||||
export * from "./encodedAsPrismaJsonValue"
|
export * from "./encodedAsPrismaJsonValue"
|
||||||
export * from "./Kind"
|
export * from "./Kind"
|
||||||
export * as MobX from "./MobX"
|
export * as MobX from "./MobX"
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import type { IncomingMessage } from "node:http"
|
|||||||
import type { WebSocket } from "ws"
|
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 runtime: Runtime.Runtime<R>
|
||||||
|
|
||||||
readonly run: <A, E>(
|
readonly run: <A, E>(
|
||||||
@@ -18,12 +20,14 @@ export interface TRPCContext<R> {
|
|||||||
effect: Effect.Effect<A, E, R>,
|
effect: Effect.Effect<A, E, R>,
|
||||||
options?: Runtime.RunForkOptions,
|
options?: Runtime.RunForkOptions,
|
||||||
) => RuntimeFiber<A, TRPCError>
|
) => 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 Express: {
|
||||||
readonly req: express.Request
|
readonly req: express.Request
|
||||||
readonly res: express.Response
|
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 type { CreateWSSContextFnOptions } from "@trpc/server/adapters/ws"
|
||||||
import { Context, Effect, Layer, Runtime } from "effect"
|
import { Context, Effect, Layer, Runtime } from "effect"
|
||||||
import { createTRCPErrorMapper } from "./createTRCPErrorMapper"
|
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"
|
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 TRPCContextCreator<R> extends Context.Tag<typeof Identifier, TRPCContextCreatorService<R>> {}
|
||||||
|
|
||||||
export interface 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 createExpressContext: (context: CreateExpressContextOptions) => TRPCContext<R>
|
||||||
readonly createWebSocketContext: (context: CreateWSSContextFnOptions) => TRPCContext<R>
|
readonly createWebSocketContext: (context: CreateWSSContextFnOptions) => TRPCContext<R>
|
||||||
}
|
}
|
||||||
@@ -41,16 +41,16 @@ export const make = <R>() => {
|
|||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
|
|
||||||
const createContext = (transaction: TRPCContextTransaction) => ({
|
const createContext = (transaction: TRPCTransaction) => ({
|
||||||
runtime,
|
runtime,
|
||||||
run,
|
run,
|
||||||
fork,
|
fork,
|
||||||
transaction,
|
transaction,
|
||||||
})
|
})
|
||||||
const createExpressContext = (context: CreateExpressContextOptions) => createContext(TRPCContextTransactionEnum.Express(context))
|
const createExpressContext = (context: CreateExpressContextOptions) => createContext(TRPCTransactionEnum.Express(context))
|
||||||
const createWebSocketContext = (context: CreateWSSContextFnOptions) => createContext(TRPCContextTransactionEnum.WebSocket(context))
|
const createWebSocketContext = (context: CreateWSSContextFnOptions) => createContext(TRPCTransactionEnum.WebSocket(context))
|
||||||
|
|
||||||
return { createContext, createExpressContext, createWebSocketContext }
|
return { createContext, createExpressContext, createWebSocketContext } as const
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return { TRPCContextCreator, TRPCContextCreatorLive } 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