|
| 1 | +import { cookies } from "next/headers"; |
| 2 | +import { unauthorized } from "next/navigation"; |
| 3 | +import * as v from "valibot"; |
| 4 | +import { failure, type ResultAsync } from "./result"; |
| 5 | + |
| 6 | +export const withValidate = <T extends v.TupleItems>(...schemas: T) => { |
| 7 | + return <R>( |
| 8 | + handler: (...args: v.InferOutput<v.TupleSchema<T, any>>) => ResultAsync<R, string>, |
| 9 | + ) => { |
| 10 | + return async (...args: v.InferOutput<v.TupleSchema<T, any>>): ResultAsync<R, string> => { |
| 11 | + const validationResult = v.safeParse(v.tuple(schemas), args); |
| 12 | + if (!validationResult.success) { |
| 13 | + return failure("Invalid arguments"); |
| 14 | + } |
| 15 | + return handler(...args); |
| 16 | + }; |
| 17 | + }; |
| 18 | +}; |
| 19 | + |
| 20 | +export const withAuth = |
| 21 | + <T extends () => void>(handler: T) => |
| 22 | + async (): Promise<void> => { |
| 23 | + const cookie = await cookies(); |
| 24 | + const authToken = cookie.get("auth-token")?.value; |
| 25 | + if (!authToken) { |
| 26 | + return unauthorized(); |
| 27 | + } |
| 28 | + return handler(); |
| 29 | + }; |
| 30 | + |
| 31 | +export function pipe<T1, T2>(value: T1, fn: (value: T1) => T2): T2; |
| 32 | +export function pipe<T1, T2, T3>(value: T1, fn1: (value: T1) => T2, fn2: (value: T2) => T3): T3; |
| 33 | +export function pipe<T1, T2, T3, T4>( |
| 34 | + value: T1, |
| 35 | + fn1: (value: T1) => T2, |
| 36 | + fn2: (value: T2) => T3, |
| 37 | + fn3: (value: T3) => T4, |
| 38 | +): T4; |
| 39 | +export function pipe<T1, T2, T3, T4, T5>( |
| 40 | + value: T1, |
| 41 | + fn1: (value: T1) => T2, |
| 42 | + fn2: (value: T2) => T3, |
| 43 | + fn3: (value: T3) => T4, |
| 44 | + fn4: (value: T4) => T5, |
| 45 | +): T5; |
| 46 | +export function pipe<T1, T2, T3, T4, T5, T6>( |
| 47 | + value: T1, |
| 48 | + fn1: (value: T1) => T2, |
| 49 | + fn2: (value: T2) => T3, |
| 50 | + fn3: (value: T3) => T4, |
| 51 | + fn4: (value: T4) => T5, |
| 52 | + fn5: (value: T5) => T6, |
| 53 | +): T6; |
| 54 | +export function pipe(value: unknown, ...fns: Function[]): unknown { |
| 55 | + return fns.reduce((acc, fn) => fn(acc), value); |
| 56 | +} |
| 57 | + |
| 58 | +export function pipeAsync<T1, T2>(value: T1, fn: (value: T1) => Promise<T2>): Promise<T2>; |
| 59 | +export function pipeAsync<T1, T2, T3>( |
| 60 | + value: T1, |
| 61 | + fn1: (value: T1) => Promise<T2>, |
| 62 | + fn2: (value: T2) => Promise<T3>, |
| 63 | +): Promise<T3>; |
| 64 | +export function pipeAsync<T1, T2, T3, T4>( |
| 65 | + value: T1, |
| 66 | + fn1: (value: T1) => Promise<T2>, |
| 67 | + fn2: (value: T2) => Promise<T3>, |
| 68 | + fn3: (value: T3) => Promise<T4>, |
| 69 | +): Promise<T4>; |
| 70 | +export function pipeAsync<T1, T2, T3, T4, T5>( |
| 71 | + value: T1, |
| 72 | + fn1: (value: T1) => Promise<T2>, |
| 73 | + fn2: (value: T2) => Promise<T3>, |
| 74 | + fn3: (value: T3) => Promise<T4>, |
| 75 | + fn4: (value: T4) => Promise<T5>, |
| 76 | +): Promise<T5>; |
| 77 | +export function pipeAsync<T1, T2, T3, T4, T5, T6>( |
| 78 | + value: T1, |
| 79 | + fn1: (value: T1) => Promise<T2>, |
| 80 | + fn2: (value: T2) => Promise<T3>, |
| 81 | + fn3: (value: T3) => Promise<T4>, |
| 82 | + fn4: (value: T4) => Promise<T5>, |
| 83 | + fn5: (value: T5) => Promise<T6>, |
| 84 | +): Promise<T6>; |
| 85 | +export async function pipeAsync( |
| 86 | + value: unknown, |
| 87 | + ...fns: ((...args: unknown[]) => Promise<unknown>)[] |
| 88 | +): Promise<unknown> { |
| 89 | + let result = value; |
| 90 | + for (const fn of fns) { |
| 91 | + result = await fn(result); |
| 92 | + } |
| 93 | + return result; |
| 94 | +} |
0 commit comments