Skip to content

Commit

Permalink
[re fact] upgrade in zod route, validShema to ValidAndFormat for can …
Browse files Browse the repository at this point in the history
…use transformt
  • Loading branch information
leomerida15 committed Sep 19, 2023
1 parent 99acbc4 commit 8a8054e
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 92 deletions.
1 change: 0 additions & 1 deletion src/resolvers/yup/route.ts
Original file line number Diff line number Diff line change
@@ -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";

Expand Down
119 changes: 119 additions & 0 deletions src/resolvers/zod/ValidAndFormat.ts
Original file line number Diff line number Diff line change
@@ -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<any, ZodTypeDef, any>,
C extends ZodObject<any>,
Q extends ZodObject<any>,
H extends ZodObject<any>,
R extends ZodType<any, ZodTypeDef, any>,
> {
Schemas?: IZodSchemasValid<B, C, Q, H, R>;
NativeContext: TypeOf<C>;
nativeRequest: NextRequest;
bodyNative: TypeOf<B> = {};

constructor(
nativeRequest: NextRequest,
context: TypeOf<C>,
Schemas?: IZodSchemasValid<B, C, Q, H, R>,
) {
this.Schemas = Schemas;
this.NativeContext = context;
this.nativeRequest = nativeRequest;
}

headers(): TypeOf<H> | ReadonlyHeaders {
if (!this.Schemas?.headers) return Headers();

return this.Schemas.headers.parse(Headers());
}

context(): TypeOf<C> {
if (!this.Schemas?.context) return this.NativeContext;

return this.Schemas.context.parse(this.NativeContext);
}

private getQueryWhoNoHasSchema(
queriesArray: Array<keyof TypeOf<Q>>,
): Partial<TypeOf<Q>> {
//
const resQueries: any = {};

const symbolsReq = Object.getOwnPropertySymbols(this.nativeRequest);

const UrlNative = symbolsReq
.filter((S) => {
//@ts-ignore
const item = nativeRequest[S];

return item?.url;
})
.map<URL>((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<Q>) {
return (queriesArray: Array<keyof TypeOf<Q>>): Partial<TypeOf<Q>> => {
const querysEntrys = Object.entries(queryFormat);

const queryFilter = querysEntrys.filter(([k]) =>
queriesArray.includes(k),
);

const queryObj = Object.fromEntries(queryFilter) as Partial<TypeOf<Q>>;

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<Q>;

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<TypeOf<B>> {
await this.defineBody();

if (!this.Schemas?.body) return this.bodyNative;

return this.Schemas.body.parse(this.bodyNative);
}
}
2 changes: 1 addition & 1 deletion src/resolvers/zod/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export * from "./requestFactory";
export * from "./responseFactory";
export * from "./route";
export * from "./types";
export * from "./validSchema";
export * from "./ValidAndFormat";
68 changes: 15 additions & 53 deletions src/resolvers/zod/requestFactory.ts
Original file line number Diff line number Diff line change
@@ -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<any, ZodTypeDef, any>,
Expand All @@ -16,62 +15,25 @@ export const requestFactory = async <
context: TypeOf<C>,
Schemas?: IZodSchemasValid<B, C, Q, H, R>,
) => {
const body = await (async () => {
const valid_methods = !["DELETE", "GET"].includes(nativeRequest.method);
const validAndFormat = new ValidAndFormat<B, C, Q, H, R>(
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<C> => {
const params = formatParams(context.params);

return { ...context, params };
},
/**
*
* @param {String[]} queriesArray string[]
* @return {Object} Record<queriesArray, (string | number)>
*/
getQuery: (queriesArray: string[]): TypeOf<Q> => {
//
const resQueries: any = {};

const symbolsReq = Object.getOwnPropertySymbols(nativeRequest);

const UrlNative = symbolsReq
.filter((S) => {
//@ts-ignore
const item = nativeRequest[S];

return item?.url;
})
.map<URL>((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<B> => body,
const resp = {
getHeaders: () => Headers,
getContext: () => Context,
getQuery: (keys: Array<keyof TypeOf<Q> | string>) => Query(keys),
getBody: () => body,
};

return { ...resp, ...nativeRequest } as IZodRequestFactoryResp<B, C, Q>;
Expand Down
1 change: 0 additions & 1 deletion src/resolvers/zod/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<any, ZodTypeDef, any>,
Expand Down
36 changes: 0 additions & 36 deletions src/resolvers/zod/validSchema.ts

This file was deleted.

0 comments on commit 8a8054e

Please sign in to comment.