@arkyn/server 3.0.1-beta.12 → 3.0.1-beta.121
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/README.md +368 -65
- package/dist/bundle.js +1518 -0
- package/dist/bundle.umd.cjs +5 -0
- package/dist/{api/arkynLogRequest.d.ts → http/api/_logRequest.d.ts} +22 -19
- package/dist/{api/arkynLogRequest.d.ts.map → http/api/_logRequest.d.ts.map} +1 -1
- package/dist/http/api/_logRequest.js +88 -0
- package/dist/http/api/_makeRequest.d.ts +61 -0
- package/dist/http/api/_makeRequest.d.ts.map +1 -0
- package/dist/{api/makeRequest.js → http/api/_makeRequest.js} +33 -20
- package/dist/http/api/deleteRequest.d.ts +17 -0
- package/dist/http/api/deleteRequest.d.ts.map +1 -0
- package/dist/http/api/deleteRequest.js +18 -0
- package/dist/http/api/getRequest.d.ts +16 -0
- package/dist/http/api/getRequest.d.ts.map +1 -0
- package/dist/http/api/getRequest.js +17 -0
- package/dist/http/api/patchRequest.d.ts +17 -0
- package/dist/http/api/patchRequest.d.ts.map +1 -0
- package/dist/http/api/patchRequest.js +18 -0
- package/dist/http/api/postRequest.d.ts +17 -0
- package/dist/http/api/postRequest.d.ts.map +1 -0
- package/dist/http/api/postRequest.js +18 -0
- package/dist/http/api/putRequest.d.ts +17 -0
- package/dist/http/api/putRequest.d.ts.map +1 -0
- package/dist/http/api/putRequest.js +18 -0
- package/dist/http/badResponses/_badResponse.d.ts +22 -0
- package/dist/http/badResponses/_badResponse.d.ts.map +1 -0
- package/dist/http/badResponses/_badResponse.js +51 -0
- package/dist/http/badResponses/badGateway.d.ts +6 -9
- package/dist/http/badResponses/badGateway.d.ts.map +1 -1
- package/dist/http/badResponses/badGateway.js +12 -14
- package/dist/http/badResponses/badRequest.d.ts +6 -9
- package/dist/http/badResponses/badRequest.d.ts.map +1 -1
- package/dist/http/badResponses/badRequest.js +12 -14
- package/dist/http/badResponses/conflict.d.ts +6 -9
- package/dist/http/badResponses/conflict.d.ts.map +1 -1
- package/dist/http/badResponses/conflict.js +12 -14
- package/dist/http/badResponses/forbidden.d.ts +6 -9
- package/dist/http/badResponses/forbidden.d.ts.map +1 -1
- package/dist/http/badResponses/forbidden.js +12 -14
- package/dist/http/badResponses/notFound.d.ts +6 -9
- package/dist/http/badResponses/notFound.d.ts.map +1 -1
- package/dist/http/badResponses/notFound.js +12 -14
- package/dist/http/badResponses/notImplemented.d.ts +6 -9
- package/dist/http/badResponses/notImplemented.d.ts.map +1 -1
- package/dist/http/badResponses/notImplemented.js +12 -14
- package/dist/http/badResponses/serverError.d.ts +6 -9
- package/dist/http/badResponses/serverError.d.ts.map +1 -1
- package/dist/http/badResponses/serverError.js +12 -14
- package/dist/http/badResponses/unauthorized.d.ts +4 -7
- package/dist/http/badResponses/unauthorized.d.ts.map +1 -1
- package/dist/http/badResponses/unauthorized.js +10 -12
- package/dist/http/badResponses/unprocessableEntity.d.ts +15 -19
- package/dist/http/badResponses/unprocessableEntity.d.ts.map +1 -1
- package/dist/http/badResponses/unprocessableEntity.js +18 -21
- package/dist/http/successResponses/_successResponse.d.ts +33 -0
- package/dist/http/successResponses/_successResponse.d.ts.map +1 -0
- package/dist/http/successResponses/_successResponse.js +66 -0
- package/dist/http/successResponses/created.d.ts +9 -19
- package/dist/http/successResponses/created.d.ts.map +1 -1
- package/dist/http/successResponses/created.js +16 -25
- package/dist/http/successResponses/found.d.ts +10 -23
- package/dist/http/successResponses/found.d.ts.map +1 -1
- package/dist/http/successResponses/found.js +17 -29
- package/dist/http/successResponses/noContent.d.ts +6 -13
- package/dist/http/successResponses/noContent.d.ts.map +1 -1
- package/dist/http/successResponses/noContent.js +12 -17
- package/dist/http/successResponses/success.d.ts +9 -19
- package/dist/http/successResponses/success.d.ts.map +1 -1
- package/dist/http/successResponses/success.js +16 -25
- package/dist/http/successResponses/updated.d.ts +9 -19
- package/dist/http/successResponses/updated.d.ts.map +1 -1
- package/dist/http/successResponses/updated.js +16 -25
- package/dist/index.d.ts +19 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -13
- package/dist/services/apiService.d.ts +63 -0
- package/dist/services/apiService.d.ts.map +1 -0
- package/dist/services/apiService.js +158 -0
- package/dist/services/debugService.d.ts +69 -0
- package/dist/services/debugService.d.ts.map +1 -0
- package/dist/services/debugService.js +114 -0
- package/dist/services/logMapperService.d.ts +86 -0
- package/dist/services/logMapperService.d.ts.map +1 -0
- package/dist/services/logMapperService.js +68 -0
- package/dist/services/logService.d.ts +38 -0
- package/dist/services/logService.d.ts.map +1 -0
- package/dist/services/logService.js +40 -0
- package/dist/{services → utilities}/decodeRequestBody.d.ts +3 -4
- package/dist/utilities/decodeRequestBody.d.ts.map +1 -0
- package/dist/{services → utilities}/decodeRequestBody.js +5 -5
- package/dist/{services/decodeErrorMessageFromRequest.d.ts → utilities/decodeRequestErrorMessage.d.ts} +6 -6
- package/dist/utilities/decodeRequestErrorMessage.d.ts.map +1 -0
- package/dist/{services/decodeErrorMessageFromRequest.js → utilities/decodeRequestErrorMessage.js} +5 -5
- package/dist/utilities/errorHandler.d.ts +50 -0
- package/dist/utilities/errorHandler.d.ts.map +1 -0
- package/dist/{services → utilities}/errorHandler.js +34 -28
- package/dist/utilities/flushDebugLogs.d.ts +46 -0
- package/dist/utilities/flushDebugLogs.d.ts.map +1 -0
- package/dist/utilities/flushDebugLogs.js +59 -0
- package/dist/utilities/formAsyncParse.d.ts +59 -0
- package/dist/utilities/formAsyncParse.d.ts.map +1 -0
- package/dist/utilities/formAsyncParse.js +58 -0
- package/dist/{services → utilities}/formParse.d.ts +6 -6
- package/dist/utilities/formParse.d.ts.map +1 -0
- package/dist/{services → utilities}/formParse.js +10 -8
- package/dist/{services → utilities}/getScopedParams.d.ts +3 -4
- package/dist/utilities/getScopedParams.d.ts.map +1 -0
- package/dist/{services → utilities}/getScopedParams.js +4 -4
- package/dist/utilities/schemaValidator.d.ts +146 -0
- package/dist/utilities/schemaValidator.d.ts.map +1 -0
- package/dist/utilities/schemaValidator.js +191 -0
- package/dist/validations/validateCep.d.ts +19 -0
- package/dist/validations/validateCep.d.ts.map +1 -0
- package/dist/validations/validateCep.js +27 -0
- package/dist/validations/validateCnpj.d.ts +21 -0
- package/dist/validations/validateCnpj.d.ts.map +1 -0
- package/dist/validations/validateCnpj.js +59 -0
- package/dist/validations/validateCpf.d.ts +23 -0
- package/dist/validations/validateCpf.d.ts.map +1 -0
- package/dist/validations/validateCpf.js +61 -0
- package/dist/validations/validateDate.d.ts +27 -0
- package/dist/validations/validateDate.d.ts.map +1 -0
- package/dist/validations/validateDate.js +55 -0
- package/dist/validations/validateEmail.d.ts +21 -0
- package/dist/validations/validateEmail.d.ts.map +1 -0
- package/dist/validations/validateEmail.js +111 -0
- package/dist/validations/validatePassword.d.ts +20 -0
- package/dist/validations/validatePassword.d.ts.map +1 -0
- package/dist/validations/validatePassword.js +34 -0
- package/dist/validations/validatePhone.d.ts +28 -0
- package/dist/validations/validatePhone.d.ts.map +1 -0
- package/dist/validations/validatePhone.js +44 -0
- package/dist/validations/validateRg.d.ts +21 -0
- package/dist/validations/validateRg.d.ts.map +1 -0
- package/dist/validations/validateRg.js +31 -0
- package/package.json +34 -18
- package/dist/api/arkynLogRequest.js +0 -82
- package/dist/api/deleteRequest.d.ts +0 -13
- package/dist/api/deleteRequest.d.ts.map +0 -1
- package/dist/api/deleteRequest.js +0 -14
- package/dist/api/getRequest.d.ts +0 -12
- package/dist/api/getRequest.d.ts.map +0 -1
- package/dist/api/getRequest.js +0 -13
- package/dist/api/makeRequest.d.ts +0 -38
- package/dist/api/makeRequest.d.ts.map +0 -1
- package/dist/api/patchRequest.d.ts +0 -13
- package/dist/api/patchRequest.d.ts.map +0 -1
- package/dist/api/patchRequest.js +0 -14
- package/dist/api/postRequest.d.ts +0 -13
- package/dist/api/postRequest.d.ts.map +0 -1
- package/dist/api/postRequest.js +0 -14
- package/dist/api/putRequest.d.ts +0 -13
- package/dist/api/putRequest.d.ts.map +0 -1
- package/dist/api/putRequest.js +0 -14
- package/dist/config/apiInstance.d.ts +0 -80
- package/dist/config/apiInstance.d.ts.map +0 -1
- package/dist/config/apiInstance.js +0 -111
- package/dist/config/arkynLogInstance.d.ts +0 -44
- package/dist/config/arkynLogInstance.d.ts.map +0 -1
- package/dist/config/arkynLogInstance.js +0 -49
- package/dist/mapper/arkynLogRequestMapper.d.ts +0 -30
- package/dist/mapper/arkynLogRequestMapper.d.ts.map +0 -1
- package/dist/mapper/arkynLogRequestMapper.js +0 -44
- package/dist/services/decodeErrorMessageFromRequest.d.ts.map +0 -1
- package/dist/services/decodeRequestBody.d.ts.map +0 -1
- package/dist/services/errorHandler.d.ts +0 -44
- package/dist/services/errorHandler.d.ts.map +0 -1
- package/dist/services/formParse.d.ts.map +0 -1
- package/dist/services/getCaller.d.ts +0 -17
- package/dist/services/getCaller.d.ts.map +0 -1
- package/dist/services/getCaller.js +0 -65
- package/dist/services/getScopedParams.d.ts.map +0 -1
- package/dist/services/httpDebug.d.ts +0 -35
- package/dist/services/httpDebug.d.ts.map +0 -1
- package/dist/services/httpDebug.js +0 -52
- package/dist/services/measureRouteExecution.d.ts +0 -3
- package/dist/services/measureRouteExecution.d.ts.map +0 -1
- package/dist/services/measureRouteExecution.js +0 -24
- package/dist/services/schemaValidator.d.ts +0 -13
- package/dist/services/schemaValidator.d.ts.map +0 -1
- package/dist/services/schemaValidator.js +0 -51
- package/dist/types/ApiResponseDTO.d.ts +0 -17
- package/dist/types/ApiResponseDTO.d.ts.map +0 -1
- package/dist/types/ApiResponseDTO.js +0 -1
- package/src/api/arkynLogRequest.ts +0 -118
- package/src/api/deleteRequest.ts +0 -22
- package/src/api/getRequest.ts +0 -20
- package/src/api/makeRequest.ts +0 -118
- package/src/api/patchRequest.ts +0 -22
- package/src/api/postRequest.ts +0 -22
- package/src/api/putRequest.ts +0 -22
- package/src/config/apiInstance.ts +0 -148
- package/src/config/arkynLogInstance.ts +0 -70
- package/src/http/badResponses/badGateway.ts +0 -63
- package/src/http/badResponses/badRequest.ts +0 -63
- package/src/http/badResponses/conflict.ts +0 -63
- package/src/http/badResponses/forbidden.ts +0 -63
- package/src/http/badResponses/notFound.ts +0 -63
- package/src/http/badResponses/notImplemented.ts +0 -63
- package/src/http/badResponses/serverError.ts +0 -63
- package/src/http/badResponses/unauthorized.ts +0 -63
- package/src/http/badResponses/unprocessableEntity.ts +0 -79
- package/src/http/successResponses/created.ts +0 -64
- package/src/http/successResponses/found.ts +0 -67
- package/src/http/successResponses/noContent.ts +0 -42
- package/src/http/successResponses/success.ts +0 -64
- package/src/http/successResponses/updated.ts +0 -64
- package/src/index.ts +0 -31
- package/src/mapper/arkynLogRequestMapper.ts +0 -73
- package/src/services/decodeErrorMessageFromRequest.ts +0 -36
- package/src/services/decodeRequestBody.ts +0 -43
- package/src/services/errorHandler.ts +0 -99
- package/src/services/formParse.ts +0 -83
- package/src/services/getCaller.ts +0 -82
- package/src/services/getScopedParams.ts +0 -43
- package/src/services/httpDebug.ts +0 -61
- package/src/services/measureRouteExecution.ts +0 -31
- package/src/services/schemaValidator.ts +0 -66
- package/src/types/ApiResponseDTO.ts +0 -19
- package/tsconfig.json +0 -21
- package/vitest.config.ts +0 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaValidator.d.ts","sourceRoot":"","sources":["../../src/utilities/schemaValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,cAAM,eAAe,CAAC,CAAC,SAAS,OAAO;IAKzB,QAAQ,CAAC,MAAM,EAAE,CAAC;IAJ9B;;;OAGG;gBACkB,MAAM,EAAE,CAAC;IAE9B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO;IAI3B;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAIzD;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAQ/B;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAiBrD;;;;;;;;;;;;;;;;;;;;;;OAsBG;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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { ZodType, z } from "zod";
|
|
2
|
+
import { ServerError } from "../http/badResponses/serverError";
|
|
3
|
+
import { UnprocessableEntity } from "../http/badResponses/unprocessableEntity";
|
|
4
|
+
import { formAsyncParse } from "./formAsyncParse";
|
|
5
|
+
import { formParse } from "./formParse";
|
|
6
|
+
function formatErrorMessage(error) {
|
|
7
|
+
const title = "Error validating:";
|
|
8
|
+
const lines = error.issues.map(({ path, message }) => `-> ${path.join(".")}: ${message}`);
|
|
9
|
+
return [title, ...lines].join("\n");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A schema validator class that provides multiple validation methods for Zod schemas.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { z } from "zod";
|
|
17
|
+
*
|
|
18
|
+
* const userSchema = z.object({
|
|
19
|
+
* name: z.string().min(1, "Name is required"),
|
|
20
|
+
* email: z.string().email("Invalid email"),
|
|
21
|
+
* age: z.number().min(18, "Must be at least 18")
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* const validator = new SchemaValidator(userSchema);
|
|
25
|
+
*
|
|
26
|
+
* // Check if data is valid without throwing
|
|
27
|
+
* const isValid = validator.isValid({ name: "John", email: "john@example.com", age: 25 });
|
|
28
|
+
*
|
|
29
|
+
* // Validate and throw ServerError on failure
|
|
30
|
+
* try {
|
|
31
|
+
* const validData = validator.validate({ name: "John", email: "john@example.com", age: 25 });
|
|
32
|
+
* } catch (error) {
|
|
33
|
+
* console.error(error.message);
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // Form validation with UnprocessableEntity error
|
|
37
|
+
* try {
|
|
38
|
+
* const formData = validator.formValidate(requestBody);
|
|
39
|
+
* } catch (error) {
|
|
40
|
+
* // Returns structured error with fieldErrors for forms
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
class SchemaValidator {
|
|
45
|
+
schema;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new SchemaValidator instance.
|
|
48
|
+
* @param {T} schema - The Zod schema to use for validation.
|
|
49
|
+
*/
|
|
50
|
+
constructor(schema) {
|
|
51
|
+
this.schema = schema;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Checks if the provided data is valid according to the schema without throwing errors.
|
|
55
|
+
*
|
|
56
|
+
* @param {any} data - The data to validate.
|
|
57
|
+
*
|
|
58
|
+
* @returns {boolean} True if the data is valid, false otherwise.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const validator = new SchemaValidator(userSchema);
|
|
63
|
+
* const isValid = validator.isValid({ name: "John", email: "invalid-email" });
|
|
64
|
+
* console.log(isValid); // false
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
isValid(data) {
|
|
68
|
+
return this.schema.safeParse(data).success;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Safely validates data and returns the complete parse result without throwing errors.
|
|
72
|
+
*
|
|
73
|
+
* @param {any} data - The data to validate.
|
|
74
|
+
* @returns {z.ZodSafeParseResult<z.infer<T>>} The Zod safe parse result containing success status and data or error.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const validator = new SchemaValidator(userSchema);
|
|
79
|
+
* const result = validator.safeValidate({ name: "", email: "john@example.com" });
|
|
80
|
+
*
|
|
81
|
+
* if (result.success) {
|
|
82
|
+
* console.log(result.data); // Validated data
|
|
83
|
+
* } else {
|
|
84
|
+
* console.log(result.error.issues); // Validation errors
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
safeValidate(data) {
|
|
89
|
+
return this.schema.safeParse(data);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validates data and returns the parsed result, throwing a ServerError on validation failure.
|
|
93
|
+
*
|
|
94
|
+
* @param {any} data - The data to validate.
|
|
95
|
+
* @throws {ServerError} When validation fails, with a formatted error message.
|
|
96
|
+
* @returns {z.infer<T>} The validated and parsed data.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const validator = new SchemaValidator(userSchema);
|
|
101
|
+
*
|
|
102
|
+
* try {
|
|
103
|
+
* const validUser = validator.validate({ name: "John", email: "john@example.com", age: 25 });
|
|
104
|
+
* console.log(validUser); // { name: "John", email: "john@example.com", age: 25 }
|
|
105
|
+
* } catch (error) {
|
|
106
|
+
* console.error(error.message); // "Error validating:\n-> name: String must contain at least 1 character(s)"
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
validate(data) {
|
|
111
|
+
try {
|
|
112
|
+
return this.schema.parse(data);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
throw new ServerError(formatErrorMessage(error));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
|
|
120
|
+
* This method is specifically designed for form validation in web applications.
|
|
121
|
+
*
|
|
122
|
+
* @param {any} data - The form data to validate.
|
|
123
|
+
* @param {string} [message] - Optional custom error message.
|
|
124
|
+
* @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
|
|
125
|
+
* @returns {z.infer<T>} The validated and parsed form data.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const validator = new SchemaValidator(userSchema);
|
|
130
|
+
*
|
|
131
|
+
* try {
|
|
132
|
+
* const validFormData = validator.formValidate(requestBody, "User data is invalid");
|
|
133
|
+
* console.log(validFormData);
|
|
134
|
+
* } catch (error) {
|
|
135
|
+
* // UnprocessableEntity with fieldErrors, fields, and scrollTo data
|
|
136
|
+
* console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
|
|
137
|
+
* console.log(error.data.scrollTo); // "name" (first error field)
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
formValidate(data, message) {
|
|
142
|
+
const formParsed = formParse([data, this.schema]);
|
|
143
|
+
if (!formParsed.success) {
|
|
144
|
+
const firstErrorKey = Object.keys(formParsed.fieldErrors)[0];
|
|
145
|
+
throw new UnprocessableEntity({
|
|
146
|
+
fields: formParsed.fields,
|
|
147
|
+
fieldErrors: formParsed.fieldErrors,
|
|
148
|
+
data: { scrollTo: firstErrorKey },
|
|
149
|
+
message,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return formParsed.data;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Asynchronously validates form data and returns the parsed result, throwing an UnprocessableEntity error on validation failure.
|
|
156
|
+
* This method is the async version of formValidate, designed for form validation with async schemas.
|
|
157
|
+
*
|
|
158
|
+
* @param {any} data - The form data to validate.
|
|
159
|
+
* @param {string} [message] - Optional custom error message.
|
|
160
|
+
* @throws {UnprocessableEntity} When validation fails, with structured field errors for form handling.
|
|
161
|
+
* @returns {Promise<z.infer<T>>} A promise that resolves to the validated and parsed form data.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const validator = new SchemaValidator(userSchemaWithAsyncValidation);
|
|
166
|
+
*
|
|
167
|
+
* try {
|
|
168
|
+
* const validFormData = await validator.formAsyncValidate(requestBody, "User data is invalid");
|
|
169
|
+
* console.log(validFormData);
|
|
170
|
+
* } catch (error) {
|
|
171
|
+
* // UnprocessableEntity with fieldErrors, fields, and scrollTo data
|
|
172
|
+
* console.log(error.fieldErrors); // { name: "Name is required", email: "Invalid email" }
|
|
173
|
+
* console.log(error.data.scrollTo); // "name" (first error field)
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
async formAsyncValidate(data, message) {
|
|
178
|
+
const formParsed = await formAsyncParse([data, this.schema]);
|
|
179
|
+
if (!formParsed.success) {
|
|
180
|
+
const firstErrorKey = Object.keys(formParsed.fieldErrors)[0];
|
|
181
|
+
throw new UnprocessableEntity({
|
|
182
|
+
fields: formParsed.fields,
|
|
183
|
+
fieldErrors: formParsed.fieldErrors,
|
|
184
|
+
data: { scrollTo: firstErrorKey },
|
|
185
|
+
message,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return formParsed.data;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
export { SchemaValidator };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates a Brazilian CEP (postal code).
|
|
3
|
+
*
|
|
4
|
+
* A valid CEP must contain exactly 8 numeric digits,
|
|
5
|
+
* optionally formatted as "12345-678".
|
|
6
|
+
*
|
|
7
|
+
* @param {string} rawCep - CEP value, with or without formatting.
|
|
8
|
+
* @returns {boolean} `true` if the CEP is valid, otherwise `false`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* validateCep("12345-678"); // true
|
|
13
|
+
* validateCep("12345678"); // true
|
|
14
|
+
* validateCep("ABCDE-123"); // false
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare function validateCep(rawCep: string): boolean;
|
|
18
|
+
export { validateCep };
|
|
19
|
+
//# sourceMappingURL=validateCep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateCep.d.ts","sourceRoot":"","sources":["../../src/validations/validateCep.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,iBAAS,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAU5C;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { removeNonNumeric } from "@arkyn/shared";
|
|
2
|
+
/**
|
|
3
|
+
* Validates a Brazilian CEP (postal code).
|
|
4
|
+
*
|
|
5
|
+
* A valid CEP must contain exactly 8 numeric digits,
|
|
6
|
+
* optionally formatted as "12345-678".
|
|
7
|
+
*
|
|
8
|
+
* @param {string} rawCep - CEP value, with or without formatting.
|
|
9
|
+
* @returns {boolean} `true` if the CEP is valid, otherwise `false`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* validateCep("12345-678"); // true
|
|
14
|
+
* validateCep("12345678"); // true
|
|
15
|
+
* validateCep("ABCDE-123"); // false
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
function validateCep(rawCep) {
|
|
19
|
+
const validFormat = /^\d{5}-\d{3}$/.test(rawCep) || /^\d{8}$/.test(rawCep);
|
|
20
|
+
if (!validFormat)
|
|
21
|
+
return false;
|
|
22
|
+
const cep = removeNonNumeric(rawCep);
|
|
23
|
+
const CEP_LENGTH = 8;
|
|
24
|
+
const isOnlyDigits = /^\d{8}$/.test(cep);
|
|
25
|
+
return cep.length === CEP_LENGTH && isOnlyDigits;
|
|
26
|
+
}
|
|
27
|
+
export { validateCep };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates a Brazilian CNPJ (Cadastro Nacional da Pessoa Jurídica) number.
|
|
3
|
+
*
|
|
4
|
+
* This function performs:
|
|
5
|
+
* - Sanitization (removes non-digit characters).
|
|
6
|
+
* - Length check (must be 14 digits).
|
|
7
|
+
* - Repeating digits check (invalid if all digits are the same).
|
|
8
|
+
* - Verifies the two check digits with the proper weights.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} rawCnpj - CNPJ string, possibly formatted.
|
|
11
|
+
* @returns {boolean} `true` if valid, otherwise `false`.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* validateCnpj("12.345.678/0001-95"); // false
|
|
16
|
+
* validateCnpj("11.444.777/0001-61"); // true
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
declare function validateCnpj(rawCnpj: string): boolean;
|
|
20
|
+
export { validateCnpj };
|
|
21
|
+
//# sourceMappingURL=validateCnpj.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateCnpj.d.ts","sourceRoot":"","sources":["../../src/validations/validateCnpj.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;;GAiBG;AAEH,iBAAS,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAqB9C;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { removeNonNumeric } from "@arkyn/shared";
|
|
2
|
+
function isInvalidLength(cnpj) {
|
|
3
|
+
const CNPJ_LENGTH = 14;
|
|
4
|
+
return cnpj.length !== CNPJ_LENGTH;
|
|
5
|
+
}
|
|
6
|
+
function hasAllDigitsEqual(cnpj) {
|
|
7
|
+
const [firstDigit] = cnpj;
|
|
8
|
+
return [...cnpj].every((digit) => digit === firstDigit);
|
|
9
|
+
}
|
|
10
|
+
function calculateDigit(cnpj, multipliers) {
|
|
11
|
+
let total = 0;
|
|
12
|
+
for (let i = 0; i < multipliers.length; i++) {
|
|
13
|
+
total += parseInt(cnpj[i]) * multipliers[i];
|
|
14
|
+
}
|
|
15
|
+
const rest = total % 11;
|
|
16
|
+
return rest < 2 ? 0 : 11 - rest;
|
|
17
|
+
}
|
|
18
|
+
function extractDigit(cnpj) {
|
|
19
|
+
return cnpj.slice(12);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validates a Brazilian CNPJ (Cadastro Nacional da Pessoa Jurídica) number.
|
|
23
|
+
*
|
|
24
|
+
* This function performs:
|
|
25
|
+
* - Sanitization (removes non-digit characters).
|
|
26
|
+
* - Length check (must be 14 digits).
|
|
27
|
+
* - Repeating digits check (invalid if all digits are the same).
|
|
28
|
+
* - Verifies the two check digits with the proper weights.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} rawCnpj - CNPJ string, possibly formatted.
|
|
31
|
+
* @returns {boolean} `true` if valid, otherwise `false`.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* validateCnpj("12.345.678/0001-95"); // false
|
|
36
|
+
* validateCnpj("11.444.777/0001-61"); // true
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function validateCnpj(rawCnpj) {
|
|
40
|
+
if (!rawCnpj)
|
|
41
|
+
return false;
|
|
42
|
+
if (rawCnpj.length > 18)
|
|
43
|
+
return false;
|
|
44
|
+
if (rawCnpj.length < 14)
|
|
45
|
+
return false;
|
|
46
|
+
const hasSpaces = /\s/.test(rawCnpj);
|
|
47
|
+
if (hasSpaces)
|
|
48
|
+
return false;
|
|
49
|
+
const cnpj = removeNonNumeric(rawCnpj);
|
|
50
|
+
if (isInvalidLength(cnpj))
|
|
51
|
+
return false;
|
|
52
|
+
if (hasAllDigitsEqual(cnpj))
|
|
53
|
+
return false;
|
|
54
|
+
const base = cnpj.slice(0, 12);
|
|
55
|
+
const digit1 = calculateDigit(base, [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]);
|
|
56
|
+
const digit2 = calculateDigit(base + digit1, [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]);
|
|
57
|
+
return extractDigit(cnpj) === `${digit1}${digit2}`;
|
|
58
|
+
}
|
|
59
|
+
export { validateCnpj };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates a Brazilian CPF (Cadastro de Pessoas Físicas) number.
|
|
3
|
+
*
|
|
4
|
+
* The CPF is a unique identifier assigned to Brazilian citizens and residents.
|
|
5
|
+
* This function checks if the provided CPF is valid by performing the following steps:
|
|
6
|
+
* - Removes any non-digit characters from the input.
|
|
7
|
+
* - Verifies if the CPF has the correct length (11 digits).
|
|
8
|
+
* - Ensures that all digits are not the same (e.g., "111.111.111-11" is invalid).
|
|
9
|
+
* - Calculates the first and second verification digits using the CPF algorithm.
|
|
10
|
+
* - Compares the calculated verification digits with the ones provided in the CPF.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} rawCpf - The raw CPF string, which may include formatting characters (e.g., dots or dashes).
|
|
13
|
+
* @returns {boolean} `true` if the CPF is valid, otherwise `false`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* validateCpf("123.456.789-09"); // false
|
|
18
|
+
* validateCpf("111.444.777-35"); // true
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare function validateCpf(rawCpf: string): boolean;
|
|
22
|
+
export { validateCpf };
|
|
23
|
+
//# sourceMappingURL=validateCpf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateCpf.d.ts","sourceRoot":"","sources":["../../src/validations/validateCpf.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,iBAAS,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAiB5C;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { removeNonNumeric } from "@arkyn/shared";
|
|
2
|
+
function isInvalidLength(cpf) {
|
|
3
|
+
const CPF_LENGTH = 11;
|
|
4
|
+
return cpf.length !== CPF_LENGTH;
|
|
5
|
+
}
|
|
6
|
+
function hasAllDigitsEqual(cpf) {
|
|
7
|
+
const [firstCpfDigit] = cpf;
|
|
8
|
+
return [...cpf].every((digit) => digit === firstCpfDigit);
|
|
9
|
+
}
|
|
10
|
+
function calculateDigit(cpf, factor) {
|
|
11
|
+
let total = 0;
|
|
12
|
+
for (const digit of cpf) {
|
|
13
|
+
if (factor > 1)
|
|
14
|
+
total += parseInt(digit) * factor--;
|
|
15
|
+
}
|
|
16
|
+
const rest = total % 11;
|
|
17
|
+
return rest < 2 ? 0 : 11 - rest;
|
|
18
|
+
}
|
|
19
|
+
function extractDigit(cpf) {
|
|
20
|
+
return cpf.slice(9);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validates a Brazilian CPF (Cadastro de Pessoas Físicas) number.
|
|
24
|
+
*
|
|
25
|
+
* The CPF is a unique identifier assigned to Brazilian citizens and residents.
|
|
26
|
+
* This function checks if the provided CPF is valid by performing the following steps:
|
|
27
|
+
* - Removes any non-digit characters from the input.
|
|
28
|
+
* - Verifies if the CPF has the correct length (11 digits).
|
|
29
|
+
* - Ensures that all digits are not the same (e.g., "111.111.111-11" is invalid).
|
|
30
|
+
* - Calculates the first and second verification digits using the CPF algorithm.
|
|
31
|
+
* - Compares the calculated verification digits with the ones provided in the CPF.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} rawCpf - The raw CPF string, which may include formatting characters (e.g., dots or dashes).
|
|
34
|
+
* @returns {boolean} `true` if the CPF is valid, otherwise `false`.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* validateCpf("123.456.789-09"); // false
|
|
39
|
+
* validateCpf("111.444.777-35"); // true
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function validateCpf(rawCpf) {
|
|
43
|
+
if (!rawCpf)
|
|
44
|
+
return false;
|
|
45
|
+
if (rawCpf.length > 14)
|
|
46
|
+
return false;
|
|
47
|
+
if (rawCpf.length < 11)
|
|
48
|
+
return false;
|
|
49
|
+
const hasSpaces = /\s/.test(rawCpf);
|
|
50
|
+
if (hasSpaces)
|
|
51
|
+
return false;
|
|
52
|
+
const cpf = removeNonNumeric(rawCpf);
|
|
53
|
+
if (isInvalidLength(cpf))
|
|
54
|
+
return false;
|
|
55
|
+
if (hasAllDigitsEqual(cpf))
|
|
56
|
+
return false;
|
|
57
|
+
const digit1 = calculateDigit(cpf, 10);
|
|
58
|
+
const digit2 = calculateDigit(cpf, 11);
|
|
59
|
+
return extractDigit(cpf) === `${digit1}${digit2}`;
|
|
60
|
+
}
|
|
61
|
+
export { validateCpf };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates a date string based on the provided format and configuration.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} date - The date string to validate.
|
|
5
|
+
* @param {object} config - Optional configuration object to customize validation.
|
|
6
|
+
* @param {number} config.minYear - The minimum allowed year for the date. Defaults to 1900.
|
|
7
|
+
* @param {number} config.maxYear - The maximum allowed year for the date. Defaults to 3000.
|
|
8
|
+
* @throws {Error} If an invalid input format is provided.
|
|
9
|
+
* @returns {boolean} `true` if the date is valid according to the specified format and configuration, otherwise `false`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* validateDate("31/12/2023"); // true
|
|
14
|
+
* validateDate("12-31-2023", { inputFormat: "isoDate" }); // true
|
|
15
|
+
* validateDate("2023-12-31", { inputFormat: "timestamp", minYear: 2000, maxYear: 2100 }); // true
|
|
16
|
+
* validateDate("29/02/2024", { inputFormat: "brazilianDate" }); // true (leap year)
|
|
17
|
+
* validateDate("29/02/2023", { inputFormat: "brazilianDate" }); // false (not a leap year)
|
|
18
|
+
* validateDate("31/04/2023", { inputFormat: "brazilianDate" }); // false (April has 30 days)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare function validateDate(date: string, config?: {
|
|
22
|
+
inputFormat?: "brazilianDate" | "isoDate" | "timestamp";
|
|
23
|
+
minYear?: number;
|
|
24
|
+
maxYear?: number;
|
|
25
|
+
}): boolean;
|
|
26
|
+
export { validateDate };
|
|
27
|
+
//# sourceMappingURL=validateDate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateDate.d.ts","sourceRoot":"","sources":["../../src/validations/validateDate.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,iBAAS,YAAY,CACnB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE;IACP,WAAW,CAAC,EAAE,eAAe,GAAG,SAAS,GAAG,WAAW,CAAC;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAiCT;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ValidateDateService } from "@arkyn/shared";
|
|
2
|
+
/**
|
|
3
|
+
* Validates a date string based on the provided format and configuration.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} date - The date string to validate.
|
|
6
|
+
* @param {object} config - Optional configuration object to customize validation.
|
|
7
|
+
* @param {number} config.minYear - The minimum allowed year for the date. Defaults to 1900.
|
|
8
|
+
* @param {number} config.maxYear - The maximum allowed year for the date. Defaults to 3000.
|
|
9
|
+
* @throws {Error} If an invalid input format is provided.
|
|
10
|
+
* @returns {boolean} `true` if the date is valid according to the specified format and configuration, otherwise `false`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* validateDate("31/12/2023"); // true
|
|
15
|
+
* validateDate("12-31-2023", { inputFormat: "isoDate" }); // true
|
|
16
|
+
* validateDate("2023-12-31", { inputFormat: "timestamp", minYear: 2000, maxYear: 2100 }); // true
|
|
17
|
+
* validateDate("29/02/2024", { inputFormat: "brazilianDate" }); // true (leap year)
|
|
18
|
+
* validateDate("29/02/2023", { inputFormat: "brazilianDate" }); // false (not a leap year)
|
|
19
|
+
* validateDate("31/04/2023", { inputFormat: "brazilianDate" }); // false (April has 30 days)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function validateDate(date, config) {
|
|
23
|
+
const inputFormat = config?.inputFormat || "brazilianDate";
|
|
24
|
+
const minYear = config?.minYear || 1900;
|
|
25
|
+
const maxYear = config?.maxYear || 3000;
|
|
26
|
+
const validateDateService = new ValidateDateService();
|
|
27
|
+
validateDateService.validateInputFormat(inputFormat);
|
|
28
|
+
let day, month, year;
|
|
29
|
+
const dateParts = date.split(/[-/]/).map(Number);
|
|
30
|
+
if (dateParts.length !== 3)
|
|
31
|
+
return false;
|
|
32
|
+
try {
|
|
33
|
+
switch (inputFormat) {
|
|
34
|
+
case "brazilianDate":
|
|
35
|
+
[day, month, year] = dateParts;
|
|
36
|
+
validateDateService.validateDateParts(year, month, day);
|
|
37
|
+
break;
|
|
38
|
+
case "isoDate":
|
|
39
|
+
[month, day, year] = dateParts;
|
|
40
|
+
validateDateService.validateDateParts(year, month, day);
|
|
41
|
+
break;
|
|
42
|
+
case "timestamp":
|
|
43
|
+
[year, month, day] = dateParts;
|
|
44
|
+
validateDateService.validateDateParts(year, month, day);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
if (year < minYear || year > maxYear)
|
|
48
|
+
return false;
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export { validateDate };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates if an email address is valid in all possible ways, including DNS validation.
|
|
3
|
+
*
|
|
4
|
+
* This function performs comprehensive email validation by:
|
|
5
|
+
* - Checking basic email format and syntax
|
|
6
|
+
* - Validating advanced RFC 5322 compliance rules
|
|
7
|
+
* - Verifying that the domain has valid MX or A records in DNS
|
|
8
|
+
*
|
|
9
|
+
* @param {string} rawEmail - The email address string to validate
|
|
10
|
+
* @returns {Promise<boolean>} A promise that resolves to `true` if the email is valid (including DNS), otherwise `false`
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* await validateEmail("user@gmail.com"); // true
|
|
15
|
+
* await validateEmail("user@gmil.com"); // false (invalid domain)
|
|
16
|
+
* await validateEmail("invalid-email"); // false (invalid format)
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
declare function validateEmail(rawEmail: string): Promise<boolean>;
|
|
20
|
+
export { validateEmail };
|
|
21
|
+
//# sourceMappingURL=validateEmail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateEmail.d.ts","sourceRoot":"","sources":["../../src/validations/validateEmail.ts"],"names":[],"mappings":"AAwFA;;;;;;;;;;;;;;;;;GAiBG;AAEH,iBAAe,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW/D;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import dns from "node:dns";
|
|
2
|
+
function isValidBasicFormat(email) {
|
|
3
|
+
const emailRegex = /^[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])?)*$/;
|
|
4
|
+
return emailRegex.test(email);
|
|
5
|
+
}
|
|
6
|
+
function isValidLocalPart(localPart) {
|
|
7
|
+
if (localPart.length === 0 || localPart.length > 64)
|
|
8
|
+
return false;
|
|
9
|
+
if (localPart.startsWith(".") || localPart.endsWith("."))
|
|
10
|
+
return false;
|
|
11
|
+
if (localPart.includes(".."))
|
|
12
|
+
return false;
|
|
13
|
+
const validLocalRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+$/;
|
|
14
|
+
if (!validLocalRegex.test(localPart))
|
|
15
|
+
return false;
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
function isValidDomainLabel(label) {
|
|
19
|
+
if (label.length === 0 || label.length > 63)
|
|
20
|
+
return false;
|
|
21
|
+
if (label.startsWith("-") || label.endsWith("-"))
|
|
22
|
+
return false;
|
|
23
|
+
if (!/^[a-zA-Z0-9-]+$/.test(label))
|
|
24
|
+
return false;
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
function isValidDomainPart(domainPart) {
|
|
28
|
+
if (domainPart.length === 0 || domainPart.length > 253)
|
|
29
|
+
return false;
|
|
30
|
+
if (domainPart.startsWith(".") ||
|
|
31
|
+
domainPart.endsWith(".") ||
|
|
32
|
+
domainPart.startsWith("-") ||
|
|
33
|
+
domainPart.endsWith("-")) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const labels = domainPart.split(".");
|
|
37
|
+
if (labels.length < 2)
|
|
38
|
+
return false;
|
|
39
|
+
for (const label of labels)
|
|
40
|
+
if (!isValidDomainLabel(label))
|
|
41
|
+
return false;
|
|
42
|
+
const tld = labels[labels.length - 1];
|
|
43
|
+
if (tld.length < 2 || !/^[a-zA-Z]+$/.test(tld))
|
|
44
|
+
return false;
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
function isValidAdvancedSyntax(email) {
|
|
48
|
+
const parts = email.split("@");
|
|
49
|
+
if (parts.length !== 2)
|
|
50
|
+
return false;
|
|
51
|
+
const [localPart, domainPart] = parts;
|
|
52
|
+
if (!isValidLocalPart(localPart))
|
|
53
|
+
return false;
|
|
54
|
+
if (!isValidDomainPart(domainPart))
|
|
55
|
+
return false;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
function extractDomain(email) {
|
|
59
|
+
const parts = email.split("@");
|
|
60
|
+
return parts.length === 2 ? parts[1].toLowerCase() : null;
|
|
61
|
+
}
|
|
62
|
+
const DNS_RECORD_TYPES = ["MX", "A", "AAAA"];
|
|
63
|
+
async function tryResolveDnsRecord(domain, recordType) {
|
|
64
|
+
try {
|
|
65
|
+
await dns?.promises?.resolve(domain, recordType);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function isValidDns(domain) {
|
|
73
|
+
for (const recordType of DNS_RECORD_TYPES) {
|
|
74
|
+
const hasRecord = await tryResolveDnsRecord(domain, recordType);
|
|
75
|
+
if (hasRecord)
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validates if an email address is valid in all possible ways, including DNS validation.
|
|
82
|
+
*
|
|
83
|
+
* This function performs comprehensive email validation by:
|
|
84
|
+
* - Checking basic email format and syntax
|
|
85
|
+
* - Validating advanced RFC 5322 compliance rules
|
|
86
|
+
* - Verifying that the domain has valid MX or A records in DNS
|
|
87
|
+
*
|
|
88
|
+
* @param {string} rawEmail - The email address string to validate
|
|
89
|
+
* @returns {Promise<boolean>} A promise that resolves to `true` if the email is valid (including DNS), otherwise `false`
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* await validateEmail("user@gmail.com"); // true
|
|
94
|
+
* await validateEmail("user@gmil.com"); // false (invalid domain)
|
|
95
|
+
* await validateEmail("invalid-email"); // false (invalid format)
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
async function validateEmail(rawEmail) {
|
|
99
|
+
if (!rawEmail || typeof rawEmail !== "string")
|
|
100
|
+
return false;
|
|
101
|
+
const email = rawEmail.trim();
|
|
102
|
+
if (!isValidBasicFormat(email))
|
|
103
|
+
return false;
|
|
104
|
+
if (!isValidAdvancedSyntax(email))
|
|
105
|
+
return false;
|
|
106
|
+
const domain = extractDomain(email);
|
|
107
|
+
if (!domain)
|
|
108
|
+
return false;
|
|
109
|
+
return await isValidDns(domain);
|
|
110
|
+
}
|
|
111
|
+
export { validateEmail };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates a password based on the following rules:
|
|
3
|
+
* - At least 8 characters
|
|
4
|
+
* - At least 1 uppercase letter
|
|
5
|
+
* - At least 1 letter (any case)
|
|
6
|
+
* - At least 1 number
|
|
7
|
+
* - At least 1 special character
|
|
8
|
+
*
|
|
9
|
+
* @param {string} rawPassword - The raw password string.
|
|
10
|
+
* @returns {boolean} `true` if password is valid, otherwise `false`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* validatePassword("Senha@123"); // true
|
|
15
|
+
* validatePassword("senha123"); // false (no uppercase, no special char)
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
declare function validatePassword(rawPassword: string): boolean;
|
|
19
|
+
export { validatePassword };
|
|
20
|
+
//# sourceMappingURL=validatePassword.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validatePassword.d.ts","sourceRoot":"","sources":["../../src/validations/validatePassword.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,iBAAS,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAkBtD;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|