diff --git a/src/resolvers/yup/route.ts b/src/resolvers/yup/route.ts index c3555f5..a69c244 100644 --- a/src/resolvers/yup/route.ts +++ b/src/resolvers/yup/route.ts @@ -1,7 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { requestFactory } from "./requestFactory"; import { responseFactory } from "./responseFactory"; -import { validSchema } from "./validSchema"; import { IYupRouteParams, YupActionReturnType } from "./types"; import { ISchema, AnyObject, InferType, ObjectSchema } from "yup"; diff --git a/src/resolvers/zod/ValidAndFormat.ts b/src/resolvers/zod/ValidAndFormat.ts new file mode 100644 index 0000000..ba13a06 --- /dev/null +++ b/src/resolvers/zod/ValidAndFormat.ts @@ -0,0 +1,119 @@ +import { headers as Headers } from "next/headers"; +import { ZodType, ZodTypeDef, ZodObject, TypeOf } from "zod"; +import { IZodSchemasValid } from "./types"; +import { NextRequest } from "next/server"; +import { ReadonlyHeaders } from "next/dist/server/web/spec-extension/adapters/headers"; + +export default class ValidAndFormat< + B extends ZodType, + C extends ZodObject, + Q extends ZodObject, + H extends ZodObject, + R extends ZodType, +> { + Schemas?: IZodSchemasValid; + NativeContext: TypeOf; + nativeRequest: NextRequest; + bodyNative: TypeOf = {}; + + constructor( + nativeRequest: NextRequest, + context: TypeOf, + Schemas?: IZodSchemasValid, + ) { + this.Schemas = Schemas; + this.NativeContext = context; + this.nativeRequest = nativeRequest; + } + + headers(): TypeOf | ReadonlyHeaders { + if (!this.Schemas?.headers) return Headers(); + + return this.Schemas.headers.parse(Headers()); + } + + context(): TypeOf { + if (!this.Schemas?.context) return this.NativeContext; + + return this.Schemas.context.parse(this.NativeContext); + } + + private getQueryWhoNoHasSchema( + queriesArray: Array>, + ): Partial> { + // + const resQueries: any = {}; + + const symbolsReq = Object.getOwnPropertySymbols(this.nativeRequest); + + const UrlNative = symbolsReq + .filter((S) => { + //@ts-ignore + const item = nativeRequest[S]; + + return item?.url; + }) + .map((S) => { + //@ts-ignore + const item = nativeRequest[S]; + + return item?.url; + })[0]; + + const validUrlNative = Object.keys(this.nativeRequest).includes("url"); + + const url = validUrlNative ? new URL(this.nativeRequest.url) : UrlNative; + + queriesArray.map((q) => { + resQueries[q] = url.searchParams.get(String(q)); + }); + + return resQueries; + } + + private createGetQueryWhoHasSchema(queryFormat: TypeOf) { + return (queriesArray: Array>): Partial> => { + const querysEntrys = Object.entries(queryFormat); + + const queryFilter = querysEntrys.filter(([k]) => + queriesArray.includes(k), + ); + + const queryObj = Object.fromEntries(queryFilter) as Partial>; + + return queryObj; + }; + } + + query() { + if (!this.Schemas?.query) return this.getQueryWhoNoHasSchema; + + const keys = Object.keys(this.Schemas.query.shape); + + const query = this.getQueryWhoNoHasSchema(keys); + + const queryFormat = this.Schemas.query.parse(query) as TypeOf; + + const getQueryWhoHasSchema = this.createGetQueryWhoHasSchema(queryFormat); + + return getQueryWhoHasSchema; + } + + private async defineBody() { + const valid_methods = !["DELETE", "GET"].includes( + this.nativeRequest.method, + ); + + if (valid_methods && this.Schemas?.body) { + this.bodyNative = await this.nativeRequest.json(); + } + } + + async body(): Promise> { + await this.defineBody(); + + if (!this.Schemas?.body) return this.bodyNative; + + return this.Schemas.body.parse(this.bodyNative); + } +} diff --git a/src/resolvers/zod/index.ts b/src/resolvers/zod/index.ts index 3b3b57d..9d4bae2 100644 --- a/src/resolvers/zod/index.ts +++ b/src/resolvers/zod/index.ts @@ -2,4 +2,4 @@ export * from "./requestFactory"; export * from "./responseFactory"; export * from "./route"; export * from "./types"; -export * from "./validSchema"; +export * from "./ValidAndFormat"; diff --git a/src/resolvers/zod/requestFactory.ts b/src/resolvers/zod/requestFactory.ts index db2baab..3b0b2af 100644 --- a/src/resolvers/zod/requestFactory.ts +++ b/src/resolvers/zod/requestFactory.ts @@ -1,9 +1,8 @@ import { NextRequest } from "next/server"; import { ZodType, ZodTypeDef, ZodObject, TypeOf } from "zod"; import { IZodSchemasValid } from "./types"; -import { formatParams } from "../methods/formatParams"; -import { headers } from "next/headers"; import { IZodRequestFactoryResp } from "./types"; +import ValidAndFormat from "./ValidAndFormat"; export const requestFactory = async < B extends ZodType, @@ -16,62 +15,25 @@ export const requestFactory = async < context: TypeOf, Schemas?: IZodSchemasValid, ) => { - const body = await (async () => { - const valid_methods = !["DELETE", "GET"].includes(nativeRequest.method); + const validAndFormat = new ValidAndFormat( + nativeRequest, + context, + Schemas, + ); - if (!(valid_methods && Schemas?.body)) return {}; + const Headers = validAndFormat.headers(); - return await nativeRequest.json(); - })(); + const Context = validAndFormat.context(); - const resp = { - getHeaders: headers, - getContext: (): TypeOf => { - const params = formatParams(context.params); - - return { ...context, params }; - }, - /** - * - * @param {String[]} queriesArray string[] - * @return {Object} Record - */ - getQuery: (queriesArray: string[]): TypeOf => { - // - const resQueries: any = {}; - - const symbolsReq = Object.getOwnPropertySymbols(nativeRequest); - - const UrlNative = symbolsReq - .filter((S) => { - //@ts-ignore - const item = nativeRequest[S]; - - return item?.url; - }) - .map((S) => { - //@ts-ignore - const item = nativeRequest[S]; + const Query = validAndFormat.query(); - return item?.url; - })[0]; + const body = await validAndFormat.body(); - const validUrlNative = Object.keys(nativeRequest).includes("url"); - - const url = validUrlNative ? new URL(nativeRequest.url) : UrlNative; - - queriesArray.map((q: string) => { - const validItem = Number(url.searchParams.get(q)); - if (validItem !== 0 && !validItem) { - resQueries[q] = url.searchParams.get(q); - } else { - resQueries[q] = validItem; - } - }); - - return resQueries; - }, - getBody: (): TypeOf => body, + const resp = { + getHeaders: () => Headers, + getContext: () => Context, + getQuery: (keys: Array | string>) => Query(keys), + getBody: () => body, }; return { ...resp, ...nativeRequest } as IZodRequestFactoryResp; diff --git a/src/resolvers/zod/route.ts b/src/resolvers/zod/route.ts index 61eb31c..91ee6b3 100644 --- a/src/resolvers/zod/route.ts +++ b/src/resolvers/zod/route.ts @@ -3,7 +3,6 @@ import { ZodType, ZodTypeDef, ZodObject, TypeOf } from "zod"; import { ZodActionReturnType, IZodRouteParams } from "./types"; import { requestFactory } from "./requestFactory"; import { responseFactory } from "./responseFactory"; -import { validSchema } from "./validSchema"; export const zodRoute = < B extends ZodType, diff --git a/src/resolvers/zod/validSchema.ts b/src/resolvers/zod/validSchema.ts deleted file mode 100644 index 974f301..0000000 --- a/src/resolvers/zod/validSchema.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ZodType, ZodTypeDef, ZodObject } from "zod"; -import { IZodRouteParams } from "./types"; - -export const validSchema = < - B extends ZodType, - C extends ZodObject, - Q extends ZodObject, - H extends ZodObject, - R extends ZodType, ->( - Schemas: IZodRouteParams["schemas"], - req: Parameters["Handler"]>["0"], -) => { - if (Schemas?.headers) { - const headers = req.getHeaders(); - Schemas.headers.parse(headers); - } - - if (Schemas?.context) { - const context = req.getContext(); - Schemas.context.parse(context); - } - - if (Schemas?.query) { - const keys = Object.keys(Schemas.query.shape); - - const query = req.getQuery(keys); - - Schemas.query.parse(query); - } - - if (Schemas?.body) { - const body = req.getBody(); - Schemas.body.parse(body); - } -};