0.1.19 (#20)
All checks were successful
Publish / publish (push) Successful in 12s
Lint / lint (push) Successful in 11s

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:
Julien Valverdé
2024-09-08 01:42:56 +02:00
parent ebc5b45380
commit 704aa945f7
11 changed files with 100 additions and 60 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@thilawyn/thilalib",
"version": "0.1.18",
"version": "0.1.19",
"type": "module",
"files": [
"./dist"

View File

@@ -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) =>

View File

@@ -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",
},

View File

@@ -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"

View File

@@ -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>()

View File

@@ -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

View File

@@ -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",
})
}),
)
)))

View 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
})
)
})

View 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",
})
}),
)
}))))

View 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",
})
}),
)
}))))

View File

@@ -0,0 +1,3 @@
export * from "./DecodeInput"
export * from "./ExpressOnly"
export * from "./WebSocketOnly"