@arkyn/server 3.0.1-beta.75 → 3.0.1-beta.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +285 -141
- package/dist/bundle.umd.cjs +7 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/services/formAsyncParse.d.ts +59 -0
- package/dist/services/formAsyncParse.d.ts.map +1 -0
- package/dist/services/formAsyncParse.js +58 -0
- package/dist/services/schemaValidator.d.ts +145 -0
- package/dist/services/schemaValidator.d.ts.map +1 -1
- package/dist/services/schemaValidator.js +158 -0
- package/package.json +1 -1
package/dist/bundle.umd.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
`;e.debugs.forEach(l=>{h+=`${
|
|
3
|
-
`}),console.log(h)}}const
|
|
4
|
-
`).map(i=>i.trim()),r=
|
|
1
|
+
(function(a,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("zod"),require("@arkyn/shared"),require("node:dns"),require("@arkyn/templates")):typeof define=="function"&&define.amd?define(["exports","zod","@arkyn/shared","node:dns","@arkyn/templates"],d):(a=typeof globalThis<"u"?globalThis:a||self,d(a["@arkyn/server"]={},null,a.shared,a.dns,a.templates))})(this,function(a,d,m,M,Y){"use strict";var Us=Object.defineProperty;var ws=(a,d,m)=>d in a?Us(a,d,{enumerable:!0,configurable:!0,writable:!0,value:m}):a[d]=m;var o=(a,d,m)=>ws(a,typeof d!="symbol"?d+"":d,m);function T(e){var s;if(process.env.NODE_ENV==="development"||((s=process.env)==null?void 0:s.SHOW_ERRORS_IN_CONSOLE)==="true"){const u=`${{yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m",green:"\x1B[32m"}[e.scheme]}[${e.name}]\x1B[0m`;let h=`
|
|
2
|
+
`;e.debugs.forEach(l=>{h+=`${u} ${l.trim()}
|
|
3
|
+
`}),console.log(h)}}const _={};class v{static setIgnoreFile(t){this.ignoreFiles.push(t)}static clearIgnoreFiles(){this.ignoreFiles=[]}}o(v,"ignoreFiles",[]);function N(){const e=process.cwd(),n=(new Error().stack||"").split(`
|
|
4
|
+
`).map(i=>i.trim()),r=v.ignoreFiles;let u=2;for(;u<n.length&&(n[u].includes("node:internal")||n[u].includes("/node_modules/"));)u++;if(r.length>0)for(;u<n.length&&r.some(i=>n[u].includes(i));)u++;const h=n[u]||"";let l="Unknown function",c="Unknown caller";const f=h.match(/at\s+([^(\s]+)\s+\(([^)]+)\)/);if(f)l=f[1],c=f[2];else{const i=h.match(/at\s+(.+)/);if(i){c=i[1];const g=c.match(/at\s+([^(\s]+)\s+/);g&&g[1]!=="new"&&(l=g[1])}}c.includes("(")&&(c=c.substring(c.indexOf("(")+1,c.lastIndexOf(")"))),c=c.split(":").slice(0,-2).join(":");try{c=_.relative(e,c)}catch{}return{functionName:l,callerInfo:c}}class p{onDebug(t){const{name:s,body:n,cause:r,message:u}=t,h=[],{callerInfo:l,functionName:c}=N();h.push(`${s} initialized`),h.push(`Caller Function: ${c}`),h.push(`Caller Location: ${l}`),u&&h.push(`Message: ${u}`),n&&h.push(`Body: ${JSON.stringify(n,null,2)}`),r&&h.push(`Cause: ${JSON.stringify(r,null,2)}`),T({scheme:"red",name:"ARKYN-BAD-RESPONSE-DEBUG",debugs:h})}}class I extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",502);o(this,"statusText");this.body={name:"BadGateway",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"BadGateway",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class S extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",400);o(this,"statusText");this.body={name:"BadRequest",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"BadRequest",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class $ extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",409);o(this,"statusText");this.body={name:"Conflict",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"Conflict",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class C extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",403);o(this,"statusText");this.body={name:"Forbidden",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"Forbidden",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class A extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",404);o(this,"statusText");this.body={name:"NotFound",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"NotFound",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class k extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",501);o(this,"statusText");this.body={name:"NotImplemented",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"NotImplemented",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class E extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",500);o(this,"statusText");this.body={name:"ServerError",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"ServerError",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class U extends p{constructor(s,n){super();o(this,"body");o(this,"cause");o(this,"status",401);o(this,"statusText");this.body={name:"Unauthorized",message:s},this.statusText=s,this.cause=n?JSON.stringify(n):void 0,this.onDebug({name:"Unauthorized",body:this.body,cause:this.cause,message:this.statusText})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class D extends p{constructor(s){super();o(this,"body");o(this,"status",422);o(this,"statusText");this.statusText=s.message||"Unprocessable Entity",this.body={name:"UnprocessableEntity",message:s.message||null,data:s.data,fieldErrors:s.fieldErrors,fields:s.fields},this.onDebug({name:"UnprocessableEntity",cause:s.fieldErrors,message:s.message})}toResponse(){const s={headers:{"Content-Type":"application/json"},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class R{onDebug(t,s,n){const r=[],{callerInfo:u,functionName:h}=N();r.push(`${t} initialized
|
|
5
5
|
`),r.push(`Caller Function: ${h}
|
|
6
|
-
`),r.push(`Caller Location: ${
|
|
6
|
+
`),r.push(`Caller Location: ${u}
|
|
7
7
|
`),r.push(`Body: ${JSON.stringify(s,null,2)}
|
|
8
8
|
`),n&&r.push(`Cause: ${JSON.stringify(n,null,2)}
|
|
9
|
-
`),T({scheme:"green",name:"ARKYN-SUCCESS-RESPONSE-DEBUG",debugs:r})}}class j extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||201,this.statusText=(n==null?void 0:n.statusText)||"Resource created successfully",this.onDebug("Created",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class J extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||302,this.statusText=(n==null?void 0:n.statusText)||"Found",this.onDebug("Found",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class L extends R{constructor(s){super();o(this,"headers");o(this,"status");o(this,"statusText");this.headers=(s==null?void 0:s.headers)||{},this.status=(s==null?void 0:s.status)||204,this.statusText=(s==null?void 0:s.statusText)??"No content",this.onDebug("No content",null)}toResponse(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return new Response(null,s)}}class B extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||200,this.statusText=(n==null?void 0:n.statusText)??"OK",this.onDebug("Success",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class q extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||200,this.statusText=(n==null?void 0:n.statusText)||"Resource updated successfully",this.onDebug("Updated",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class Y{static mapHeaders(t){return t instanceof Headers?Object.fromEntries(t.entries()):typeof t=="object"?Object.entries(t).reduce((s,[n,r])=>(typeof r=="string"?s[n]=r:Array.isArray(r)?s[n]=r.join(", "):s[n]=JSON.stringify(r),s),{}):{}}static mapQueryParams(t){const s={};return t.forEach((n,r)=>{s[r]=n}),s}static handle(t){return{rawUrl:t.url,status:t.status,method:t.method,token:null,elapsedTime:t.elapsedTime,requestHeaders:this.mapHeaders(t.requestHeaders),requestBody:t.requestBody||null,queryParams:this.mapQueryParams(t.queryParams),responseHeaders:this.mapHeaders(t.responseHeaders),responseBody:t.responseBody||null}}}class I{static setArkynConfig(t){if(this.arkynConfig)return;let n=t.arkynLogBaseApiUrl||"https://logs-arkyn-flow-logs.vw6wo7.easypanel.host";n=n+"/http-traffic-records/:trafficSourceId",this.arkynConfig={arkynTrafficSourceId:t.arkynTrafficSourceId,arkynUserToken:t.arkynUserToken,arkynApiUrl:n}}static getArkynConfig(){return this.arkynConfig}static resetArkynConfig(){this.arkynConfig=void 0}}o(I,"arkynConfig");async function _(e){const t=I.getArkynConfig();if(!t)return;const{arkynUserToken:s,arkynApiUrl:n}=t,{elapsedTime:r,method:a,queryParams:h,requestBody:l,requestHeaders:c,responseBody:f,responseHeaders:i,status:g,token:Cs,rawUrl:y}=e;if(process.env.NODE_ENV!=="development")try{const b=new URL(y);let z="HTTPS";b.protocol==="http:"&&(z="HTTP");const Os=JSON.stringify({domainUrl:b.protocol+"//"+b.host,pathnameUrl:b.pathname,status:g,protocol:z,method:a,trafficUserId:null,elapsedTime:r,requestHeaders:c,requestBody:l,queryParams:h,responseHeaders:i,responseBody:f});await fetch(n.replace(":trafficSourceId",t.arkynTrafficSourceId),{method:"POST",body:Os,headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`}})}catch(b){T({debugs:[`Error sending request: ${b}`],name:"ARKYN_LOG_ERROR",scheme:"red"})}}async function x(e,t,s={},n){const r={POST:"Resource created successfully",PUT:"Resource updated successfully",DELETE:"Resource deleted successfully",PATCH:"Resource patched successfully",GET:"Request successful"};try{const a=performance.now(),h={...s,"Content-Type":"application/json"},l=await fetch(t,{method:e,headers:h,body:n?JSON.stringify(n):void 0}),c=performance.now()-a,f=l.status;let i=null;try{i=await l.json()}catch{i=null}const g=Y.handle({elapsedTime:c,method:e,queryParams:new URL(t).searchParams,requestHeaders:h,requestBody:n,responseBody:i,responseHeaders:l.headers,status:f,url:t});return _(g),l.ok?{success:!0,status:f,message:(i==null?void 0:i.message)||r[e],response:i,cause:null}:{success:!1,status:f,message:(i==null?void 0:i.message)||l.statusText||"Request failed",response:i,cause:null}}catch(a){return T({debugs:[`Network error or request failed: ${a}`],name:"ARKYN_MAKE_REQUEST_ERROR",scheme:"red"}),{success:!1,status:0,message:"Network error or request failed",response:null,cause:a instanceof Error?a.message:String(a)}}}async function V(e,t={},s){return x("DELETE",e,t,s)}async function G(e,t={}){return x("GET",e,t)}async function Z(e,t={},s){return x("PATCH",e,t,s)}async function W(e,t={},s){return x("POST",e,t,s)}async function K(e,t={},s){return x("PUT",e,t,s)}class Q{constructor(t){o(this,"baseUrl");o(this,"baseHeaders");o(this,"baseToken");o(this,"enableDebug");this.baseUrl=t.baseUrl,this.baseHeaders=t.baseHeaders||void 0,this.baseToken=t.baseToken||void 0,this.enableDebug=t.enableDebug||!1}onDebug(t,s,n){if(this.enableDebug){const r=[];r.push(`Base URL: ${this.baseUrl}`),r.push(`Endpoint: ${t}`),r.push(`Method: ${s}`),n[0]&&r.push(`Headers: ${JSON.stringify(n[0])}`),n[1]&&r.push(`Body: ${JSON.stringify(n[1])}`),T({debugs:r,name:"ARKYN-API-DEBUG",scheme:"yellow"})}}generateURL(t){return this.baseUrl+t}generateHeaders(t,s){let n={};return this.baseToken&&(n={Authorization:`Bearer ${this.baseToken}`}),this.baseHeaders&&(n={...n,...this.baseHeaders}),t&&(n={...n,...t}),s&&(n={...n,Authorization:`Bearer ${s}`}),n}async get(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token);return this.onDebug(t,"get",[r]),await G(n,r)}async post(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),a=s==null?void 0:s.body;return this.onDebug(t,"post",[r,a]),await W(n,r,a)}async put(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),a=s==null?void 0:s.body;return this.onDebug(t,"put",[r,a]),await K(n,r,a)}async patch(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),a=s==null?void 0:s.body;return this.onDebug(t,"patch",[r,a]),await Z(n,r,a)}async delete(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),a=s==null?void 0:s.body;return this.onDebug(t,"delete",[r,a]),await V(n,r,a)}}function X(e,t){var s,n,r;return e!=null&&e.message&&typeof(e==null?void 0:e.message)=="string"?e==null?void 0:e.message:e!=null&&e.error&&typeof(e==null?void 0:e.error)=="string"?e==null?void 0:e.error:(s=e==null?void 0:e.error)!=null&&s.message&&typeof((n=e==null?void 0:e.error)==null?void 0:n.message)=="string"?(r=e==null?void 0:e.error)==null?void 0:r.message:t!=null&&t.statusText&&typeof(t==null?void 0:t.statusText)=="string"?t==null?void 0:t.statusText:"Missing error message"}const ss=async e=>{let t;const s=await e.arrayBuffer(),n=new TextDecoder().decode(s);try{t=JSON.parse(n)}catch{try{if(n.includes("=")){const a=new URLSearchParams(n);t=Object.fromEntries(a.entries())}else throw new S("Invalid URLSearchParams format")}catch{throw new S("Failed to extract data from request")}}return t};function es(e){switch(!0){case e instanceof Response:return e;case e instanceof J:return e.toResponse();case e instanceof j:return e.toResponse();case e instanceof q:return e.toResponse();case e instanceof B:return e.toResponse();case e instanceof L:return e.toResponse()}switch(!0){case e instanceof C:return e.toResponse();case e instanceof S:return e.toResponse();case e instanceof O:return e.toResponse();case e instanceof U:return e.toResponse();case e instanceof k:return e.toResponse();case e instanceof A:return e.toResponse();case e instanceof E:return e.toResponse();case e instanceof w:return e.toResponse();case e instanceof v:return e.toResponse()}return new E("Server error",e).toResponse()}function F([e,t]){const s=t.safeParse(e);if(s.success===!1){const n=Object.fromEntries(s.error.issues.map(r=>[r.path.join("."),r.message]));return{success:s.success,fieldErrors:n,fields:e}}else return{success:s.success,data:s.data}}const ts=(e,t="")=>{const s=new URL(e.url);if(t==="")return s.searchParams;const n=Array.from(s.searchParams.entries()).filter(([r])=>r.startsWith(`${t}:`)).map(([r,a])=>[r.replace(`${t}:`,""),a]);return new URLSearchParams(n)};function ns(e){const t="Error validating:",s=e.issues.map(({path:n,message:r})=>`-> ${n.join(".")}: ${r}`);return[t,...s].join(`
|
|
10
|
-
`)}class
|
|
9
|
+
`),T({scheme:"green",name:"ARKYN-SUCCESS-RESPONSE-DEBUG",debugs:r})}}class w extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||201,this.statusText=(n==null?void 0:n.statusText)||"Resource created successfully",this.onDebug("Created",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class j extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||302,this.statusText=(n==null?void 0:n.statusText)||"Found",this.onDebug("Found",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class J extends R{constructor(s){super();o(this,"headers");o(this,"status");o(this,"statusText");this.headers=(s==null?void 0:s.headers)||{},this.status=(s==null?void 0:s.status)||204,this.statusText=(s==null?void 0:s.statusText)??"No content",this.onDebug("No content",null)}toResponse(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return new Response(null,s)}}class L extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||200,this.statusText=(n==null?void 0:n.statusText)??"OK",this.onDebug("Success",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class B extends R{constructor(s,n){super();o(this,"body");o(this,"headers");o(this,"status");o(this,"statusText");this.body=s,this.headers=(n==null?void 0:n.headers)||{},this.status=(n==null?void 0:n.status)||200,this.statusText=(n==null?void 0:n.statusText)||"Resource updated successfully",this.onDebug("Updated",s)}toResponse(){const s={headers:{"Content-Type":"application/json",...this.headers},status:this.status,statusText:this.statusText};return new Response(JSON.stringify(this.body),s)}toJson(){const s={headers:this.headers,status:this.status,statusText:this.statusText};return Response.json(this.body,s)}}class V{static mapHeaders(t){return t instanceof Headers?Object.fromEntries(t.entries()):typeof t=="object"?Object.entries(t).reduce((s,[n,r])=>(typeof r=="string"?s[n]=r:Array.isArray(r)?s[n]=r.join(", "):s[n]=JSON.stringify(r),s),{}):{}}static mapQueryParams(t){const s={};return t.forEach((n,r)=>{s[r]=n}),s}static handle(t){return{rawUrl:t.url,status:t.status,method:t.method,token:null,elapsedTime:t.elapsedTime,requestHeaders:this.mapHeaders(t.requestHeaders),requestBody:t.requestBody||null,queryParams:this.mapQueryParams(t.queryParams),responseHeaders:this.mapHeaders(t.responseHeaders),responseBody:t.responseBody||null}}}class O{static setArkynConfig(t){if(this.arkynConfig)return;let n=t.arkynLogBaseApiUrl||"https://logs-arkyn-flow-logs.vw6wo7.easypanel.host";n=n+"/http-traffic-records/:trafficSourceId",this.arkynConfig={arkynTrafficSourceId:t.arkynTrafficSourceId,arkynUserToken:t.arkynUserToken,arkynApiUrl:n}}static getArkynConfig(){return this.arkynConfig}static resetArkynConfig(){this.arkynConfig=void 0}}o(O,"arkynConfig");async function G(e){const t=O.getArkynConfig();if(!t)return;const{arkynUserToken:s,arkynApiUrl:n}=t,{elapsedTime:r,method:u,queryParams:h,requestBody:l,requestHeaders:c,responseBody:f,responseHeaders:i,status:g,token:As,rawUrl:y}=e;if(process.env.NODE_ENV!=="development")try{const b=new URL(y);let z="HTTPS";b.protocol==="http:"&&(z="HTTP");const ks=JSON.stringify({domainUrl:b.protocol+"//"+b.host,pathnameUrl:b.pathname,status:g,protocol:z,method:u,trafficUserId:null,elapsedTime:r,requestHeaders:c,requestBody:l,queryParams:h,responseHeaders:i,responseBody:f});await fetch(n.replace(":trafficSourceId",t.arkynTrafficSourceId),{method:"POST",body:ks,headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`}})}catch(b){T({debugs:[`Error sending request: ${b}`],name:"ARKYN_LOG_ERROR",scheme:"red"})}}async function x(e,t,s={},n){const r={POST:"Resource created successfully",PUT:"Resource updated successfully",DELETE:"Resource deleted successfully",PATCH:"Resource patched successfully",GET:"Request successful"};try{const u=performance.now(),h={...s,"Content-Type":"application/json"},l=await fetch(t,{method:e,headers:h,body:n?JSON.stringify(n):void 0}),c=performance.now()-u,f=l.status;let i=null;try{i=await l.json()}catch{i=null}const g=V.handle({elapsedTime:c,method:e,queryParams:new URL(t).searchParams,requestHeaders:h,requestBody:n,responseBody:i,responseHeaders:l.headers,status:f,url:t});return G(g),l.ok?{success:!0,status:f,message:(i==null?void 0:i.message)||r[e],response:i,cause:null}:{success:!1,status:f,message:(i==null?void 0:i.message)||l.statusText||"Request failed",response:i,cause:null}}catch(u){return T({debugs:[`Network error or request failed: ${u}`],name:"ARKYN_MAKE_REQUEST_ERROR",scheme:"red"}),{success:!1,status:0,message:"Network error or request failed",response:null,cause:u instanceof Error?u.message:String(u)}}}async function Z(e,t={},s){return x("DELETE",e,t,s)}async function W(e,t={}){return x("GET",e,t)}async function K(e,t={},s){return x("PATCH",e,t,s)}async function Q(e,t={},s){return x("POST",e,t,s)}async function X(e,t={},s){return x("PUT",e,t,s)}class ss{constructor(t){o(this,"baseUrl");o(this,"baseHeaders");o(this,"baseToken");o(this,"enableDebug");this.baseUrl=t.baseUrl,this.baseHeaders=t.baseHeaders||void 0,this.baseToken=t.baseToken||void 0,this.enableDebug=t.enableDebug||!1}onDebug(t,s,n){if(this.enableDebug){const r=[];r.push(`Base URL: ${this.baseUrl}`),r.push(`Endpoint: ${t}`),r.push(`Method: ${s}`),n[0]&&r.push(`Headers: ${JSON.stringify(n[0])}`),n[1]&&r.push(`Body: ${JSON.stringify(n[1])}`),T({debugs:r,name:"ARKYN-API-DEBUG",scheme:"yellow"})}}generateURL(t){return this.baseUrl+t}generateHeaders(t,s){let n={};return this.baseToken&&(n={Authorization:`Bearer ${this.baseToken}`}),this.baseHeaders&&(n={...n,...this.baseHeaders}),t&&(n={...n,...t}),s&&(n={...n,Authorization:`Bearer ${s}`}),n}async get(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token);return this.onDebug(t,"get",[r]),await W(n,r)}async post(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),u=s==null?void 0:s.body;return this.onDebug(t,"post",[r,u]),await Q(n,r,u)}async put(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),u=s==null?void 0:s.body;return this.onDebug(t,"put",[r,u]),await X(n,r,u)}async patch(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),u=s==null?void 0:s.body;return this.onDebug(t,"patch",[r,u]),await K(n,r,u)}async delete(t,s){const n=this.generateURL(t),r=this.generateHeaders((s==null?void 0:s.headers)||{},s==null?void 0:s.token),u=s==null?void 0:s.body;return this.onDebug(t,"delete",[r,u]),await Z(n,r,u)}}function es(e,t){var s,n,r;return e!=null&&e.message&&typeof(e==null?void 0:e.message)=="string"?e==null?void 0:e.message:e!=null&&e.error&&typeof(e==null?void 0:e.error)=="string"?e==null?void 0:e.error:(s=e==null?void 0:e.error)!=null&&s.message&&typeof((n=e==null?void 0:e.error)==null?void 0:n.message)=="string"?(r=e==null?void 0:e.error)==null?void 0:r.message:t!=null&&t.statusText&&typeof(t==null?void 0:t.statusText)=="string"?t==null?void 0:t.statusText:"Missing error message"}const ts=async e=>{let t;const s=await e.arrayBuffer(),n=new TextDecoder().decode(s);try{t=JSON.parse(n)}catch{try{if(n.includes("=")){const u=new URLSearchParams(n);t=Object.fromEntries(u.entries())}else throw new S("Invalid URLSearchParams format")}catch{throw new S("Failed to extract data from request")}}return t};function ns(e){switch(!0){case e instanceof Response:return e;case e instanceof j:return e.toResponse();case e instanceof w:return e.toResponse();case e instanceof B:return e.toResponse();case e instanceof L:return e.toResponse();case e instanceof J:return e.toResponse()}switch(!0){case e instanceof I:return e.toResponse();case e instanceof S:return e.toResponse();case e instanceof $:return e.toResponse();case e instanceof C:return e.toResponse();case e instanceof A:return e.toResponse();case e instanceof k:return e.toResponse();case e instanceof E:return e.toResponse();case e instanceof U:return e.toResponse();case e instanceof D:return e.toResponse()}return new E("Server error",e).toResponse()}async function q([e,t]){const s=await t.safeParseAsync(e);if(s.success===!1){const n=Object.fromEntries(s.error.issues.map(r=>[r.path.join("."),r.message]));return{success:s.success,fieldErrors:n,fields:e}}else return{success:s.success,data:s.data}}function F([e,t]){const s=t.safeParse(e);if(s.success===!1){const n=Object.fromEntries(s.error.issues.map(r=>[r.path.join("."),r.message]));return{success:s.success,fieldErrors:n,fields:e}}else return{success:s.success,data:s.data}}const rs=(e,t="")=>{const s=new URL(e.url);if(t==="")return s.searchParams;const n=Array.from(s.searchParams.entries()).filter(([r])=>r.startsWith(`${t}:`)).map(([r,u])=>[r.replace(`${t}:`,""),u]);return new URLSearchParams(n)};function os(e){const t="Error validating:",s=e.issues.map(({path:n,message:r})=>`-> ${n.join(".")}: ${r}`);return[t,...s].join(`
|
|
10
|
+
`)}class as{constructor(t){o(this,"functionName");o(this,"callerInfo");this.schema=t;const{callerInfo:s,functionName:n}=N();this.callerInfo=s,this.functionName=n}isValid(t){return this.schema.safeParse(t).success}safeValidate(t){return this.schema.safeParse(t)}validate(t){try{return this.schema.parse(t)}catch(s){throw new E(os(s))}}formValidate(t,s){const n=F([t,this.schema]);if(!n.success){const r=Object.keys(n.fieldErrors)[0];throw new D({fields:n.fields,fieldErrors:n.fieldErrors,data:{scrollTo:r},message:s})}return n.data}async formAsyncValidate(t,s){const n=await q([t,this.schema]);if(!n.success){const r=Object.keys(n.fieldErrors)[0];throw new D({fields:n.fields,fieldErrors:n.fieldErrors,data:{scrollTo:r},message:s})}return n.data}}const us=e=>{if(!e||!/^[0-9-]+$/.test(e))return!1;const s=m.removeNonNumeric(e),n=8,r=/^\d{8}$/.test(s);return s.length===n&&r};function is(e){return e.length!==14}function cs(e){const[t]=e;return[...e].every(s=>s===t)}function H(e,t){let s=0;for(let r=0;r<t.length;r++)s+=parseInt(e[r])*t[r];const n=s%11;return n<2?0:11-n}function hs(e){return e.slice(12)}const ls=e=>{if(!e)return!1;const t=m.removeNonNumeric(e);if(is(t)||cs(t))return!1;const s=t.slice(0,12),n=H(s,[5,4,3,2,9,8,7,6,5,4,3,2]),r=H(s+n,[6,5,4,3,2,9,8,7,6,5,4,3,2]);return hs(t)===`${n}${r}`};function fs(e){return e.length!==11}function ds(e){const[t]=e;return[...e].every(s=>s===t)}function P(e,t){let s=0;for(const r of e)t>1&&(s+=parseInt(r)*t--);const n=s%11;return n<2?0:11-n}function ys(e){return e.slice(9)}const ps=e=>{if(!e)return!1;const t=m.removeNonNumeric(e);if(fs(t)||ds(t))return!1;const s=P(t,10),n=P(t,11);return ys(t)===`${s}${n}`},gs=(e,t)=>{let s,n,r;const u=(t==null?void 0:t.inputFormat)||"DD/MM/YYYY",h=(t==null?void 0:t.minYear)||1900,l=(t==null?void 0:t.maxYear)||3e3;if(u==="DD/MM/YYYY"){const y=/^(\d{2})\/(\d{2})\/(\d{4})$/;if(!y.test(e))return!1;[,s,n,r]=e.match(y)||[]}else if(u==="MM-DD-YYYY"){const y=/^(\d{2})-(\d{2})-(\d{4})$/;if(!y.test(e))return!1;[,n,s,r]=e.match(y)||[]}else if(u==="YYYY-MM-DD"){const y=/^(\d{4})-(\d{2})-(\d{2})$/;if(!y.test(e))return!1;[,r,n,s]=e.match(y)||[]}else throw new Error("Invalid date format");const c=parseInt(s,10),f=parseInt(n,10),i=parseInt(r,10);if(c<1||c>31||f<1||f>12)return!1;const g=[31,28,31,30,31,30,31,31,30,31,30,31];if(f===2){const y=i%4===0&&i%100!==0||i%400===0;if(c>(y?29:28))return!1}else if(c>g[f-1])return!1;return i<h||i>l?!1:new Date(i,f-1,c).getDate()===c},ms=M.promises.resolve;function Ts(e){return/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(e)}function bs(e){return!(e.length===0||e.length>64||e.startsWith(".")||e.endsWith(".")||e.includes("..")||!/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+$/.test(e))}function Rs(e){return!(e.length===0||e.length>63||e.startsWith("-")||e.endsWith("-")||!/^[a-zA-Z0-9-]+$/.test(e))}function xs(e){if(e.length===0||e.length>253||e.startsWith(".")||e.endsWith(".")||e.startsWith("-")||e.endsWith("-"))return!1;const t=e.split(".");if(t.length<2)return!1;for(const n of t)if(!Rs(n))return!1;const s=t[t.length-1];return!(s.length<2||!/^[a-zA-Z]+$/.test(s))}function Ns(e){const t=e.split("@");if(t.length!==2)return!1;const[s,n]=t;return!(!bs(s)||!xs(n))}function Ss(e){const t=e.split("@");return t.length===2?t[1].toLowerCase():null}const Es=["MX","A","AAAA"];async function Ds(e,t){try{return await ms(e,t),!0}catch{return!1}}async function vs(e){for(const t of Es)if(await Ds(e,t))return!0;return!1}const Os=async e=>{if(!e||typeof e!="string")return!1;const t=e.trim();if(!Ts(t)||!Ns(t))return!1;const s=Ss(t);return s?await vs(s):!1},Is=e=>{if(!e)return!1;const t=e.length>=8,s=/[A-Z]/.test(e),n=/[a-z]/.test(e),r=/\d/.test(e),u=/[!@#$%^&*(),.?":{}|<>_\-+=~`[\]\\\/]/.test(e);return[t,s,n,r,u].every(h=>h)},$s=e=>{for(const t of Y.countries){const s=t.code,n=t.prefix?`-${t.prefix}`:"",r=t.mask.replace(/[^_]/g,"").length;if(t.iso==="BR"){if(new RegExp(`^\\${s} \\d{2}9?\\d{8}$`).test(e))return!0;continue}if(new RegExp(`^\\${s}${n} \\d{${r}}$`).test(e))return!0}return!1},Cs=e=>{if(!e||!/^[0-9a-zA-Z.-]+$/.test(e))return!1;const s=e.replace(/[^a-zA-Z0-9]/g,"");return s.length<7||s.length>9?!1:/^[0-9]{7,8}[0-9Xx]?$/.test(s)};a.ApiService=ss,a.ArkynLogService=O,a.BadGateway=I,a.BadRequest=S,a.Conflict=$,a.Created=w,a.DebugService=v,a.Forbidden=C,a.Found=j,a.NoContent=J,a.NotFound=A,a.NotImplemented=k,a.SchemaValidator=as,a.ServerError=E,a.Success=L,a.Unauthorized=U,a.UnprocessableEntity=D,a.Updated=B,a.decodeErrorMessageFromRequest=es,a.decodeRequestBody=ts,a.errorHandler=ns,a.flushDebugLogs=T,a.formAsyncParse=q,a.formParse=F,a.getCaller=N,a.getScopedParams=rs,a.validateCep=us,a.validateCnpj=ls,a.validateCpf=ps,a.validateDate=gs,a.validateEmail=Os,a.validatePassword=Is,a.validatePhone=$s,a.validateRg=Cs,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export { decodeErrorMessageFromRequest } from "./services/decodeErrorMessageFrom
|
|
|
19
19
|
export { decodeRequestBody } from "./services/decodeRequestBody";
|
|
20
20
|
export { errorHandler } from "./services/errorHandler";
|
|
21
21
|
export { flushDebugLogs } from "./services/flushDebugLogs";
|
|
22
|
+
export { formAsyncParse } from "./services/formAsyncParse";
|
|
22
23
|
export { formParse } from "./services/formParse";
|
|
23
24
|
export { getCaller } from "./services/getCaller";
|
|
24
25
|
export { getScopedParams } from "./services/getScopedParams";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAG9E,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,6BAA6B,EAAE,MAAM,0CAA0C,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAG9E,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,6BAA6B,EAAE,MAAM,0CAA0C,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export { decodeErrorMessageFromRequest } from "./services/decodeErrorMessageFrom
|
|
|
22
22
|
export { decodeRequestBody } from "./services/decodeRequestBody";
|
|
23
23
|
export { errorHandler } from "./services/errorHandler";
|
|
24
24
|
export { flushDebugLogs } from "./services/flushDebugLogs";
|
|
25
|
+
export { formAsyncParse } from "./services/formAsyncParse";
|
|
25
26
|
export { formParse } from "./services/formParse";
|
|
26
27
|
export { getCaller } from "./services/getCaller";
|
|
27
28
|
export { getScopedParams } from "./services/getScopedParams";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
type SuccessResponse<T extends FormParseProps> = {
|
|
3
|
+
success: true;
|
|
4
|
+
data: T[1] extends ZodType<infer U> ? U : never;
|
|
5
|
+
};
|
|
6
|
+
type ErrorResponse = {
|
|
7
|
+
success: false;
|
|
8
|
+
fields: {
|
|
9
|
+
[x: string]: string;
|
|
10
|
+
};
|
|
11
|
+
fieldErrors: {
|
|
12
|
+
[x: string]: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type FormParseProps = [formData: {
|
|
16
|
+
[k: string]: any;
|
|
17
|
+
}, schema: ZodType];
|
|
18
|
+
type FormParseReturnType<T extends FormParseProps> = SuccessResponse<T> | ErrorResponse;
|
|
19
|
+
/**
|
|
20
|
+
* Asynchronously parses form data using a Zod schema and returns the result.
|
|
21
|
+
*
|
|
22
|
+
* @template T - A type that extends `FormParseProps`.
|
|
23
|
+
*
|
|
24
|
+
* @param {T} param0 - An array containing the form data and the Zod schema.
|
|
25
|
+
* @param {T[0]} param0[0] - The form data to be validated.
|
|
26
|
+
* @param {T[1]} param0[1] - The Zod schema used for validation.
|
|
27
|
+
*
|
|
28
|
+
* @returns {Promise<FormParseReturnType<T>>} A promise that resolves to an object containing the validation result.
|
|
29
|
+
* - If validation fails, it includes:
|
|
30
|
+
* - `success`: A boolean indicating the validation status (false).
|
|
31
|
+
* - `fieldErrors`: An object mapping field names to their respective error messages.
|
|
32
|
+
* - `fields`: The original form data.
|
|
33
|
+
* - If validation succeeds, it includes:
|
|
34
|
+
* - `success`: A boolean indicating the validation status (true).
|
|
35
|
+
* - `data`: The parsed and validated data.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { z } from "zod";
|
|
40
|
+
*
|
|
41
|
+
* const schema = z.object({
|
|
42
|
+
* name: z.string().min(1, "Name is required"),
|
|
43
|
+
* age: z.number().min(18, "Must be at least 18"),
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* const formData = { name: "", age: 17 };
|
|
47
|
+
*
|
|
48
|
+
* const result = await formAsyncParse([formData, schema]);
|
|
49
|
+
*
|
|
50
|
+
* if (!result.success) {
|
|
51
|
+
* console.log(result.fieldErrors); // { name: "Name is required", age: "Must be at least 18" }
|
|
52
|
+
* } else {
|
|
53
|
+
* console.log(result.data); // Parsed data
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
declare function formAsyncParse<T extends FormParseProps>([formData, schema,]: T): Promise<FormParseReturnType<T>>;
|
|
58
|
+
export { formAsyncParse };
|
|
59
|
+
//# sourceMappingURL=formAsyncParse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formAsyncParse.d.ts","sourceRoot":"","sources":["../../src/services/formAsyncParse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,KAAK,eAAe,CAAC,CAAC,SAAS,cAAc,IAAI;IAC/C,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;CACjD,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAChC,WAAW,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACtC,CAAC;AAEF,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAExE,KAAK,mBAAmB,CAAC,CAAC,SAAS,cAAc,IAC7C,eAAe,CAAC,CAAC,CAAC,GAClB,aAAa,CAAC;AAElB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,iBAAe,cAAc,CAAC,CAAC,SAAS,cAAc,EAAE,CACtD,QAAQ,EACR,MAAM,EACP,EAAE,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAqBrC;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asynchronously parses form data using a Zod schema and returns the result.
|
|
3
|
+
*
|
|
4
|
+
* @template T - A type that extends `FormParseProps`.
|
|
5
|
+
*
|
|
6
|
+
* @param {T} param0 - An array containing the form data and the Zod schema.
|
|
7
|
+
* @param {T[0]} param0[0] - The form data to be validated.
|
|
8
|
+
* @param {T[1]} param0[1] - The Zod schema used for validation.
|
|
9
|
+
*
|
|
10
|
+
* @returns {Promise<FormParseReturnType<T>>} A promise that resolves to an object containing the validation result.
|
|
11
|
+
* - If validation fails, it includes:
|
|
12
|
+
* - `success`: A boolean indicating the validation status (false).
|
|
13
|
+
* - `fieldErrors`: An object mapping field names to their respective error messages.
|
|
14
|
+
* - `fields`: The original form data.
|
|
15
|
+
* - If validation succeeds, it includes:
|
|
16
|
+
* - `success`: A boolean indicating the validation status (true).
|
|
17
|
+
* - `data`: The parsed and validated data.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { z } from "zod";
|
|
22
|
+
*
|
|
23
|
+
* const schema = z.object({
|
|
24
|
+
* name: z.string().min(1, "Name is required"),
|
|
25
|
+
* age: z.number().min(18, "Must be at least 18"),
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* const formData = { name: "", age: 17 };
|
|
29
|
+
*
|
|
30
|
+
* const result = await formAsyncParse([formData, schema]);
|
|
31
|
+
*
|
|
32
|
+
* if (!result.success) {
|
|
33
|
+
* console.log(result.fieldErrors); // { name: "Name is required", age: "Must be at least 18" }
|
|
34
|
+
* } else {
|
|
35
|
+
* console.log(result.data); // Parsed data
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
async function formAsyncParse([formData, schema,]) {
|
|
40
|
+
const zodResponse = await schema.safeParseAsync(formData);
|
|
41
|
+
if (zodResponse.success === false) {
|
|
42
|
+
const errorsObject = Object.fromEntries(zodResponse.error.issues.map((item) => {
|
|
43
|
+
return [item.path.join("."), item.message];
|
|
44
|
+
}));
|
|
45
|
+
return {
|
|
46
|
+
success: zodResponse.success,
|
|
47
|
+
fieldErrors: errorsObject,
|
|
48
|
+
fields: formData,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
return {
|
|
53
|
+
success: zodResponse.success,
|
|
54
|
+
data: zodResponse.data,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export { formAsyncParse };
|
|
@@ -1,13 +1,158 @@
|
|
|
1
1
|
import { ZodType, z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* A schema validator class that provides multiple validation methods for Zod schemas.
|
|
4
|
+
*
|
|
5
|
+
* @template T - A type that extends ZodType.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { z } from "zod";
|
|
10
|
+
*
|
|
11
|
+
* const userSchema = z.object({
|
|
12
|
+
* name: z.string().min(1, "Name is required"),
|
|
13
|
+
* email: z.string().email("Invalid email"),
|
|
14
|
+
* age: z.number().min(18, "Must be at least 18")
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* const validator = new SchemaValidator(userSchema);
|
|
18
|
+
*
|
|
19
|
+
* // Check if data is valid without throwing
|
|
20
|
+
* const isValid = validator.isValid({ name: "John", email: "john@example.com", age: 25 });
|
|
21
|
+
*
|
|
22
|
+
* // Validate and throw ServerError on failure
|
|
23
|
+
* try {
|
|
24
|
+
* const validData = validator.validate({ name: "John", email: "john@example.com", age: 25 });
|
|
25
|
+
* } catch (error) {
|
|
26
|
+
* console.error(error.message);
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* // Form validation with UnprocessableEntity error
|
|
30
|
+
* try {
|
|
31
|
+
* const formData = validator.formValidate(requestBody);
|
|
32
|
+
* } catch (error) {
|
|
33
|
+
* // Returns structured error with fieldErrors for forms
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
2
37
|
declare class SchemaValidator<T extends ZodType> {
|
|
3
38
|
readonly schema: T;
|
|
4
39
|
functionName: string;
|
|
5
40
|
callerInfo: string;
|
|
41
|
+
/**
|
|
42
|
+
* Creates a new SchemaValidator instance.
|
|
43
|
+
*
|
|
44
|
+
* @param {T} schema - The Zod schema to use for validation.
|
|
45
|
+
*/
|
|
6
46
|
constructor(schema: T);
|
|
47
|
+
/**
|
|
48
|
+
* Checks if the provided data is valid according to the schema without throwing errors.
|
|
49
|
+
*
|
|
50
|
+
* @param {any} data - The data to validate.
|
|
51
|
+
*
|
|
52
|
+
* @returns {boolean} True if the data is valid, false otherwise.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const validator = new SchemaValidator(userSchema);
|
|
57
|
+
* const isValid = validator.isValid({ name: "John", email: "invalid-email" });
|
|
58
|
+
* console.log(isValid); // false
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
7
61
|
isValid(data: any): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Safely validates data and returns the complete parse result without throwing errors.
|
|
64
|
+
*
|
|
65
|
+
* @param {any} data - The data to validate.
|
|
66
|
+
*
|
|
67
|
+
* @returns {z.ZodSafeParseResult<z.infer<T>>} The Zod safe parse result containing success status and data or error.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const validator = new SchemaValidator(userSchema);
|
|
72
|
+
* const result = validator.safeValidate({ name: "", email: "john@example.com" });
|
|
73
|
+
*
|
|
74
|
+
* if (result.success) {
|
|
75
|
+
* console.log(result.data); // Validated data
|
|
76
|
+
* } else {
|
|
77
|
+
* console.log(result.error.issues); // Validation errors
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
8
81
|
safeValidate(data: any): z.ZodSafeParseResult<z.infer<T>>;
|
|
82
|
+
/**
|
|
83
|
+
* Validates data and returns the parsed result, throwing a ServerError on validation failure.
|
|
84
|
+
*
|
|
85
|
+
* @param {any} data - The data to validate.
|
|
86
|
+
*
|
|
87
|
+
* @returns {z.infer<T>} The validated and parsed data.
|
|
88
|
+
*
|
|
89
|
+
* @throws {ServerError} When validation fails, with a formatted error message.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const validator = new SchemaValidator(userSchema);
|
|
94
|
+
*
|
|
95
|
+
* try {
|
|
96
|
+
* const validUser = validator.validate({ name: "John", email: "john@example.com", age: 25 });
|
|
97
|
+
* console.log(validUser); // { name: "John", email: "john@example.com", age: 25 }
|
|
98
|
+
* } catch (error) {
|
|
99
|
+
* console.error(error.message); // "Error validating:\n-> name: String must contain at least 1 character(s)"
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
9
103
|
validate(data: any): z.infer<T>;
|
|
104
|
+
/**
|
|
105
|
+
* Validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
|
|
106
|
+
* This method is specifically designed for form validation in web applications.
|
|
107
|
+
*
|
|
108
|
+
* @param {any} data - The form data to validate.
|
|
109
|
+
* @param {string} [message] - Optional custom error message.
|
|
110
|
+
*
|
|
111
|
+
* @returns {z.infer<T>} The validated and parsed form data.
|
|
112
|
+
*
|
|
113
|
+
* @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const validator = new SchemaValidator(userSchema);
|
|
118
|
+
*
|
|
119
|
+
* try {
|
|
120
|
+
* const validFormData = validator.formValidate(requestBody, "User data is invalid");
|
|
121
|
+
* console.log(validFormData);
|
|
122
|
+
* } catch (error) {
|
|
123
|
+
* // UnprocessableEntity with fieldErrors, fields, and scrollTo data
|
|
124
|
+
* console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
|
|
125
|
+
* console.log(error.data.scrollTo); // "name" (first error field)
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
10
129
|
formValidate(data: any, message?: string): z.infer<T>;
|
|
130
|
+
/**
|
|
131
|
+
* Asynchronously validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
|
|
132
|
+
* This method is the async version of formValidate, designed for form validation with async schemas.
|
|
133
|
+
*
|
|
134
|
+
* @param {any} data - The form data to validate.
|
|
135
|
+
* @param {string} [message] - Optional custom error message.
|
|
136
|
+
*
|
|
137
|
+
* @returns {Promise<z.infer<T>>} A promise that resolves to the validated and parsed form data.
|
|
138
|
+
*
|
|
139
|
+
* @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const validator = new SchemaValidator(userSchemaWithAsyncValidation);
|
|
144
|
+
*
|
|
145
|
+
* try {
|
|
146
|
+
* const validFormData = await validator.formAsyncValidate(requestBody, "User data is invalid");
|
|
147
|
+
* console.log(validFormData);
|
|
148
|
+
* } catch (error) {
|
|
149
|
+
* // UnprocessableEntity with fieldErrors, fields, and scrollTo data
|
|
150
|
+
* console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
|
|
151
|
+
* console.log(error.data.scrollTo); // "name" (first error field)
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
formAsyncValidate(data: any, message?: string): Promise<z.infer<T>>;
|
|
11
156
|
}
|
|
12
157
|
export { SchemaValidator };
|
|
13
158
|
//# sourceMappingURL=schemaValidator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaValidator.d.ts","sourceRoot":"","sources":["../../src/services/schemaValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schemaValidator.d.ts","sourceRoot":"","sources":["../../src/services/schemaValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,cAAM,eAAe,CAAC,CAAC,SAAS,OAAO;IASzB,QAAQ,CAAC,MAAM,EAAE,CAAC;IAR9B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;gBACkB,MAAM,EAAE,CAAC;IAM9B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO;IAI3B;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAIzD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAQ/B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAiBrD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;CAgB1E;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ZodType, z } from "zod";
|
|
2
2
|
import { ServerError } from "../http/badResponses/serverError";
|
|
3
3
|
import { UnprocessableEntity } from "../http/badResponses/unprocessableEntity";
|
|
4
|
+
import { formAsyncParse } from "./formAsyncParse";
|
|
4
5
|
import { formParse } from "./formParse";
|
|
5
6
|
import { getCaller } from "./getCaller";
|
|
6
7
|
function formatErrorMessage(error) {
|
|
@@ -8,22 +9,116 @@ function formatErrorMessage(error) {
|
|
|
8
9
|
const lines = error.issues.map(({ path, message }) => `-> ${path.join(".")}: ${message}`);
|
|
9
10
|
return [title, ...lines].join("\n");
|
|
10
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* A schema validator class that provides multiple validation methods for Zod schemas.
|
|
14
|
+
*
|
|
15
|
+
* @template T - A type that extends ZodType.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { z } from "zod";
|
|
20
|
+
*
|
|
21
|
+
* const userSchema = z.object({
|
|
22
|
+
* name: z.string().min(1, "Name is required"),
|
|
23
|
+
* email: z.string().email("Invalid email"),
|
|
24
|
+
* age: z.number().min(18, "Must be at least 18")
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* const validator = new SchemaValidator(userSchema);
|
|
28
|
+
*
|
|
29
|
+
* // Check if data is valid without throwing
|
|
30
|
+
* const isValid = validator.isValid({ name: "John", email: "john@example.com", age: 25 });
|
|
31
|
+
*
|
|
32
|
+
* // Validate and throw ServerError on failure
|
|
33
|
+
* try {
|
|
34
|
+
* const validData = validator.validate({ name: "John", email: "john@example.com", age: 25 });
|
|
35
|
+
* } catch (error) {
|
|
36
|
+
* console.error(error.message);
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* // Form validation with UnprocessableEntity error
|
|
40
|
+
* try {
|
|
41
|
+
* const formData = validator.formValidate(requestBody);
|
|
42
|
+
* } catch (error) {
|
|
43
|
+
* // Returns structured error with fieldErrors for forms
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
11
47
|
class SchemaValidator {
|
|
12
48
|
schema;
|
|
13
49
|
functionName;
|
|
14
50
|
callerInfo;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new SchemaValidator instance.
|
|
53
|
+
*
|
|
54
|
+
* @param {T} schema - The Zod schema to use for validation.
|
|
55
|
+
*/
|
|
15
56
|
constructor(schema) {
|
|
16
57
|
this.schema = schema;
|
|
17
58
|
const { callerInfo, functionName } = getCaller();
|
|
18
59
|
this.callerInfo = callerInfo;
|
|
19
60
|
this.functionName = functionName;
|
|
20
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Checks if the provided data is valid according to the schema without throwing errors.
|
|
64
|
+
*
|
|
65
|
+
* @param {any} data - The data to validate.
|
|
66
|
+
*
|
|
67
|
+
* @returns {boolean} True if the data is valid, false otherwise.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const validator = new SchemaValidator(userSchema);
|
|
72
|
+
* const isValid = validator.isValid({ name: "John", email: "invalid-email" });
|
|
73
|
+
* console.log(isValid); // false
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
21
76
|
isValid(data) {
|
|
22
77
|
return this.schema.safeParse(data).success;
|
|
23
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Safely validates data and returns the complete parse result without throwing errors.
|
|
81
|
+
*
|
|
82
|
+
* @param {any} data - The data to validate.
|
|
83
|
+
*
|
|
84
|
+
* @returns {z.ZodSafeParseResult<z.infer<T>>} The Zod safe parse result containing success status and data or error.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const validator = new SchemaValidator(userSchema);
|
|
89
|
+
* const result = validator.safeValidate({ name: "", email: "john@example.com" });
|
|
90
|
+
*
|
|
91
|
+
* if (result.success) {
|
|
92
|
+
* console.log(result.data); // Validated data
|
|
93
|
+
* } else {
|
|
94
|
+
* console.log(result.error.issues); // Validation errors
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
24
98
|
safeValidate(data) {
|
|
25
99
|
return this.schema.safeParse(data);
|
|
26
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Validates data and returns the parsed result, throwing a ServerError on validation failure.
|
|
103
|
+
*
|
|
104
|
+
* @param {any} data - The data to validate.
|
|
105
|
+
*
|
|
106
|
+
* @returns {z.infer<T>} The validated and parsed data.
|
|
107
|
+
*
|
|
108
|
+
* @throws {ServerError} When validation fails, with a formatted error message.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const validator = new SchemaValidator(userSchema);
|
|
113
|
+
*
|
|
114
|
+
* try {
|
|
115
|
+
* const validUser = validator.validate({ name: "John", email: "john@example.com", age: 25 });
|
|
116
|
+
* console.log(validUser); // { name: "John", email: "john@example.com", age: 25 }
|
|
117
|
+
* } catch (error) {
|
|
118
|
+
* console.error(error.message); // "Error validating:\n-> name: String must contain at least 1 character(s)"
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
27
122
|
validate(data) {
|
|
28
123
|
try {
|
|
29
124
|
return this.schema.parse(data);
|
|
@@ -32,6 +127,31 @@ class SchemaValidator {
|
|
|
32
127
|
throw new ServerError(formatErrorMessage(error));
|
|
33
128
|
}
|
|
34
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
|
|
132
|
+
* This method is specifically designed for form validation in web applications.
|
|
133
|
+
*
|
|
134
|
+
* @param {any} data - The form data to validate.
|
|
135
|
+
* @param {string} [message] - Optional custom error message.
|
|
136
|
+
*
|
|
137
|
+
* @returns {z.infer<T>} The validated and parsed form data.
|
|
138
|
+
*
|
|
139
|
+
* @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const validator = new SchemaValidator(userSchema);
|
|
144
|
+
*
|
|
145
|
+
* try {
|
|
146
|
+
* const validFormData = validator.formValidate(requestBody, "User data is invalid");
|
|
147
|
+
* console.log(validFormData);
|
|
148
|
+
* } catch (error) {
|
|
149
|
+
* // UnprocessableEntity with fieldErrors, fields, and scrollTo data
|
|
150
|
+
* console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
|
|
151
|
+
* console.log(error.data.scrollTo); // "name" (first error field)
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
35
155
|
formValidate(data, message) {
|
|
36
156
|
const formParsed = formParse([data, this.schema]);
|
|
37
157
|
if (!formParsed.success) {
|
|
@@ -45,5 +165,43 @@ class SchemaValidator {
|
|
|
45
165
|
}
|
|
46
166
|
return formParsed.data;
|
|
47
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Asynchronously validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
|
|
170
|
+
* This method is the async version of formValidate, designed for form validation with async schemas.
|
|
171
|
+
*
|
|
172
|
+
* @param {any} data - The form data to validate.
|
|
173
|
+
* @param {string} [message] - Optional custom error message.
|
|
174
|
+
*
|
|
175
|
+
* @returns {Promise<z.infer<T>>} A promise that resolves to the validated and parsed form data.
|
|
176
|
+
*
|
|
177
|
+
* @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const validator = new SchemaValidator(userSchemaWithAsyncValidation);
|
|
182
|
+
*
|
|
183
|
+
* try {
|
|
184
|
+
* const validFormData = await validator.formAsyncValidate(requestBody, "User data is invalid");
|
|
185
|
+
* console.log(validFormData);
|
|
186
|
+
* } catch (error) {
|
|
187
|
+
* // UnprocessableEntity with fieldErrors, fields, and scrollTo data
|
|
188
|
+
* console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
|
|
189
|
+
* console.log(error.data.scrollTo); // "name" (first error field)
|
|
190
|
+
* }
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
async formAsyncValidate(data, message) {
|
|
194
|
+
const formParsed = await formAsyncParse([data, this.schema]);
|
|
195
|
+
if (!formParsed.success) {
|
|
196
|
+
const firstErrorKey = Object.keys(formParsed.fieldErrors)[0];
|
|
197
|
+
throw new UnprocessableEntity({
|
|
198
|
+
fields: formParsed.fields,
|
|
199
|
+
fieldErrors: formParsed.fieldErrors,
|
|
200
|
+
data: { scrollTo: firstErrorKey },
|
|
201
|
+
message,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return formParsed.data;
|
|
205
|
+
}
|
|
48
206
|
}
|
|
49
207
|
export { SchemaValidator };
|