@excofy/utils 1.0.0

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/.eslintrc.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "root": true,
3
+ "parser": "@typescript-eslint/parser",
4
+ "plugins": ["@typescript-eslint"],
5
+ "extends": [
6
+ "eslint:recommended",
7
+ "plugin:@typescript-eslint/recommended"
8
+ ]
9
+ }
@@ -0,0 +1,32 @@
1
+ name: Publish Package
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ publish:
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - name: Checkout
12
+ uses: actions/checkout@v4
13
+
14
+ - name: Set up Node.js
15
+ uses: actions/setup-node@v3
16
+ with:
17
+ node-version: '20'
18
+ cache: 'npm'
19
+
20
+ - name: Install Dependencies
21
+ run: npm ci
22
+
23
+ - name: Lint Code
24
+ run: npm run lint
25
+
26
+ - name: Build Package
27
+ run: npm run build
28
+
29
+ - name: Publish to NPM
30
+ uses: JS-DevTools/npm-publish@v3
31
+ with:
32
+ token: ${{ secrets.NPM_TOKEN }}
package/.prettierrc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "singleQuote": true,
3
+ "semi": true
4
+ }
package/dist/index.cjs ADDED
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ createValidator: () => createValidator,
24
+ htmlEntityDecode: () => htmlEntityDecode
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/helpers/sanitize.ts
29
+ var import_xss = require("xss");
30
+ var allTags = [
31
+ "h1",
32
+ "h2",
33
+ "h3",
34
+ "h4",
35
+ "h5",
36
+ "h6",
37
+ "p",
38
+ "ul",
39
+ "ol",
40
+ "li",
41
+ "span",
42
+ "a",
43
+ "strong",
44
+ "em",
45
+ "i",
46
+ "br",
47
+ "img"
48
+ ];
49
+ var allAttributes = [
50
+ "data-lexical-text",
51
+ "style",
52
+ "dir",
53
+ "value",
54
+ "href",
55
+ "rel",
56
+ "target",
57
+ "alt",
58
+ "title",
59
+ "src",
60
+ "class"
61
+ ];
62
+ function sanitizeValue(value, allowedTags) {
63
+ let whiteList = {};
64
+ if (allowedTags === void 0) {
65
+ for (const tag of allTags) {
66
+ whiteList[tag] = [...allAttributes];
67
+ }
68
+ } else if (allowedTags.length === 0) {
69
+ whiteList = {};
70
+ } else {
71
+ for (const entry of allowedTags) {
72
+ if (typeof entry === "string") {
73
+ whiteList[entry] = [];
74
+ } else {
75
+ whiteList[entry.tag] = entry.attributes ?? [];
76
+ }
77
+ }
78
+ }
79
+ const filter = new import_xss.FilterXSS({
80
+ whiteList,
81
+ stripIgnoreTag: true,
82
+ stripIgnoreTagBody: ["script"]
83
+ });
84
+ return filter.process(value);
85
+ }
86
+ function htmlEntityDecode(value) {
87
+ if (!value) {
88
+ return "";
89
+ }
90
+ return value.replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&#39;/g, "'");
91
+ }
92
+
93
+ // src/helpers/video.ts
94
+ var video = {
95
+ youtube: {
96
+ isValid: (url) => {
97
+ const regex = /^(?:(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11}))/g;
98
+ return regex.test(url);
99
+ },
100
+ getId: (url) => {
101
+ const regex = /^(?:(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11}))/;
102
+ const match = url?.match(regex);
103
+ if (match && match.length >= 2 && match[1]) {
104
+ return match[1];
105
+ }
106
+ return null;
107
+ },
108
+ getEmbedUrl: (id) => {
109
+ return `https://www.youtube.com/embed/${id}`;
110
+ }
111
+ }
112
+ };
113
+
114
+ // src/helpers/validator.ts
115
+ function createValidator() {
116
+ const current = {
117
+ field: "",
118
+ value: void 0,
119
+ required: false,
120
+ inputs: {},
121
+ errors: {},
122
+ typeValid: false,
123
+ setInput(field, value) {
124
+ this.field = field;
125
+ this.value = value;
126
+ },
127
+ pushError(message) {
128
+ const key = String(this.field);
129
+ if (!this.errors[key]) this.errors[key] = [];
130
+ this.errors[key].push({ message });
131
+ }
132
+ };
133
+ const validatorRequired = {
134
+ isRequired(message) {
135
+ current.required = true;
136
+ if (current.value === void 0 || current.value === null) {
137
+ current.pushError(message);
138
+ }
139
+ return validatorType;
140
+ },
141
+ isNotRequired() {
142
+ current.required = false;
143
+ return validatorType;
144
+ }
145
+ };
146
+ const validatorType = {
147
+ type(type, message) {
148
+ if (shouldSkipValidation()) {
149
+ return validator;
150
+ }
151
+ const value = current.value;
152
+ let isValidType = false;
153
+ if (type === "array") {
154
+ isValidType = Array.isArray(value);
155
+ } else if (type === "object") {
156
+ isValidType = typeof value === "object" && value !== null && !Array.isArray(value);
157
+ } else if (type === "file") {
158
+ isValidType = value instanceof File;
159
+ } else if (type === "date") {
160
+ isValidType = typeof value === "string" && !Number.isNaN(new Date(value).getTime());
161
+ } else {
162
+ isValidType = type === "string" && typeof value === "string" || type === "number" && typeof value === "number" || type === "boolean" && typeof value === "boolean";
163
+ }
164
+ current.typeValid = isValidType;
165
+ if (!isValidType) {
166
+ current.pushError(message);
167
+ }
168
+ return validator;
169
+ }
170
+ };
171
+ const shouldSkipValidation = () => {
172
+ return !current.required && (current.value === void 0 || current.value === null || current.value === "");
173
+ };
174
+ const validator = {
175
+ each(callback) {
176
+ if (shouldSkipValidation()) {
177
+ return validator;
178
+ }
179
+ if (!Array.isArray(current.value)) return validator;
180
+ const fieldName = String(current.field);
181
+ for (let index = 0; index < current.value.length; index++) {
182
+ const item = current.value[index];
183
+ const subValidator = createValidator();
184
+ subValidator.setInputs(item);
185
+ callback(item, index, subValidator);
186
+ const subErrors = subValidator.getFlatErrors();
187
+ if (subErrors) {
188
+ for (const [subField, messages] of Object.entries(subErrors)) {
189
+ const path = `${fieldName}[${index}].${subField}`;
190
+ current.errors[path] = messages;
191
+ }
192
+ }
193
+ if (Array.isArray(current.value)) {
194
+ current.value[index] = subValidator.getSanitizedInputs();
195
+ }
196
+ }
197
+ current.inputs[current.field] = current.value;
198
+ return validator;
199
+ },
200
+ email: (message) => {
201
+ if (shouldSkipValidation()) {
202
+ return validator;
203
+ }
204
+ if (typeof current.value === "string") {
205
+ const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
206
+ if (!regex.test(current.value)) {
207
+ current.pushError(message);
208
+ }
209
+ } else {
210
+ current.pushError(message);
211
+ }
212
+ return validator;
213
+ },
214
+ fileMaxSize: (maxSize, message) => {
215
+ if (shouldSkipValidation()) {
216
+ return validator;
217
+ }
218
+ const value = current.value;
219
+ if (!(value instanceof File)) {
220
+ current.pushError("Arquivo inv\xE1lido");
221
+ return validator;
222
+ }
223
+ if (value.size > maxSize) {
224
+ current.pushError(message);
225
+ }
226
+ return validator;
227
+ },
228
+ fileType: (validTypes, message) => {
229
+ if (shouldSkipValidation()) {
230
+ return validator;
231
+ }
232
+ const value = current.value;
233
+ if (!(value instanceof File)) {
234
+ current.pushError("Arquivo inv\xE1lido");
235
+ return validator;
236
+ }
237
+ if (!validTypes.includes(value.type)) {
238
+ current.pushError(message);
239
+ }
240
+ return validator;
241
+ },
242
+ length(length, message) {
243
+ if (shouldSkipValidation()) {
244
+ return validator;
245
+ }
246
+ const value = current.value;
247
+ const isValid = (typeof value === "string" || Array.isArray(value)) && value.length === length;
248
+ if (!isValid) {
249
+ current.pushError(message);
250
+ }
251
+ return validator;
252
+ },
253
+ min(min, message) {
254
+ if (shouldSkipValidation()) {
255
+ return validator;
256
+ }
257
+ if (typeof current.value === "string" && current.value.length < min)
258
+ current.pushError(message);
259
+ else if (typeof current.value === "number" && current.value < min)
260
+ current.pushError(message);
261
+ else if (Array.isArray(current.value) && current.value.length < min)
262
+ current.pushError(message);
263
+ return validator;
264
+ },
265
+ max(max, message) {
266
+ if (shouldSkipValidation()) {
267
+ return validator;
268
+ }
269
+ if (typeof current.value === "string" && current.value.length > max)
270
+ current.pushError(message);
271
+ else if (typeof current.value === "number" && current.value > max)
272
+ current.pushError(message);
273
+ return validator;
274
+ },
275
+ transform(fn) {
276
+ if (shouldSkipValidation()) return validator;
277
+ const transformed = fn(current.value);
278
+ current.value = transformed;
279
+ current.inputs[current.field] = transformed;
280
+ return validator;
281
+ },
282
+ slug(message) {
283
+ if (shouldSkipValidation()) {
284
+ return validator;
285
+ }
286
+ if (typeof current.value === "string") {
287
+ const regex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
288
+ if (!regex.test(current.value)) current.pushError(message);
289
+ }
290
+ return validator;
291
+ },
292
+ sanitize() {
293
+ if (shouldSkipValidation()) {
294
+ return validator;
295
+ }
296
+ if (typeof current.value === "string") {
297
+ const newValue = sanitizeValue(current.value, []).replace(/\s+/g, " ").trim();
298
+ current.value = newValue;
299
+ current.inputs[current.field] = newValue;
300
+ }
301
+ return validator;
302
+ },
303
+ sanitizeHTML(tags) {
304
+ if (shouldSkipValidation()) {
305
+ return validator;
306
+ }
307
+ if (typeof current.value === "string") {
308
+ const newValue = sanitizeValue(current.value, tags);
309
+ current.value = newValue;
310
+ current.inputs[current.field] = newValue;
311
+ }
312
+ return validator;
313
+ },
314
+ uuid(message) {
315
+ if (shouldSkipValidation()) {
316
+ return validator;
317
+ }
318
+ if (typeof current.value === "string") {
319
+ const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
320
+ if (!regex.test(current.value)) current.pushError(message);
321
+ }
322
+ return validator;
323
+ },
324
+ oneOf: (types, message) => {
325
+ if (shouldSkipValidation()) {
326
+ return validator;
327
+ }
328
+ if (types.includes(String(current.value))) {
329
+ return validator;
330
+ }
331
+ current.pushError(message);
332
+ return validator;
333
+ },
334
+ videoUrl: {
335
+ youtube(message) {
336
+ if (shouldSkipValidation()) {
337
+ return validator;
338
+ }
339
+ if (typeof current.value === "string" && !video.youtube.isValid(current.value)) {
340
+ current.pushError(message);
341
+ }
342
+ return validator;
343
+ }
344
+ }
345
+ };
346
+ return {
347
+ getErrors() {
348
+ return Object.keys(current.errors).length > 0 ? current.errors : void 0;
349
+ },
350
+ getFlatErrors() {
351
+ const flatErrors = {};
352
+ function flatten(prefix, obj) {
353
+ if (!obj) return;
354
+ if (Array.isArray(obj)) {
355
+ if (obj.length > 0 && typeof obj[0] === "object" && "message" in obj[0]) {
356
+ flatErrors[prefix] = obj;
357
+ } else if (obj.length > 0 && typeof obj[0] === "object") {
358
+ for (let i = 0; i < obj.length; i++) {
359
+ flatten(`${prefix}[${i}]`, obj[i]);
360
+ }
361
+ }
362
+ } else {
363
+ for (const key in obj) {
364
+ flatten(prefix ? `${prefix}.${key}` : key, obj[key]);
365
+ }
366
+ }
367
+ }
368
+ flatten("", current.errors);
369
+ return Object.keys(flatErrors).length ? flatErrors : {};
370
+ },
371
+ getSanitizedInputs() {
372
+ return current.inputs;
373
+ },
374
+ hasErrors() {
375
+ return Object.keys(current.errors).length > 0;
376
+ },
377
+ setInputs(inputs) {
378
+ current.inputs = inputs;
379
+ current.errors = {};
380
+ },
381
+ unflattenErrors(flat) {
382
+ const result = {};
383
+ for (const flatKey in flat) {
384
+ const messages = flat[flatKey].map((m) => m.message).join("\n");
385
+ const pathParts = flatKey.replace(/\[(\d+)\]/g, ".$1").split(".");
386
+ let current2 = result;
387
+ for (let i = 0; i < pathParts.length; i++) {
388
+ const part = pathParts[i];
389
+ const nextIsIndex = /^\d+$/.test(pathParts[i + 1] || "");
390
+ if (i === pathParts.length - 1) {
391
+ current2[part] = messages;
392
+ } else {
393
+ if (!(part in current2)) {
394
+ current2[part] = nextIsIndex ? [] : {};
395
+ }
396
+ current2 = current2[part];
397
+ }
398
+ }
399
+ }
400
+ return result;
401
+ },
402
+ validate(field) {
403
+ current.setInput(field, current.inputs[field]);
404
+ return validatorRequired;
405
+ }
406
+ };
407
+ }
408
+ // Annotate the CommonJS export names for ESM import in node:
409
+ 0 && (module.exports = {
410
+ createValidator,
411
+ htmlEntityDecode
412
+ });
@@ -0,0 +1,88 @@
1
+ type Tag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'ul' | 'ol' | 'li' | 'span' | 'a' | 'strong' | 'em' | 'i' | 'br' | 'img';
2
+ type LexicalEditorAttributes = 'data-lexical-text' | 'style' | 'dir' | 'value';
3
+ type HTMLAttributes = 'href' | 'rel' | 'target' | 'alt' | 'title' | 'src' | 'class';
4
+ type Attributes = LexicalEditorAttributes | HTMLAttributes;
5
+ type AllowedTag = Tag | {
6
+ tag: Tag;
7
+ attributes?: Attributes[];
8
+ };
9
+ declare function htmlEntityDecode(value?: string): string;
10
+
11
+ type TMessage = {
12
+ message: string;
13
+ };
14
+ type TValue = string | number | boolean | File | object | null | undefined;
15
+ type TInputValue = TValue;
16
+ type TTypes = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'file' | 'date';
17
+ interface IInputErrors {
18
+ [key: string]: TMessage[] | IInputErrors[];
19
+ }
20
+ /**
21
+ * Cria um validador de inputs com suporte a validações encadeadas, transformação e sanitização.
22
+ *
23
+ * @template TRaw Tipo dos dados recebidos originalmente (geralmente string, vindo do query, body ou params).
24
+ * @template TParsed Tipo final retornado por `getValidatedInputs()` após transformações.
25
+ *
26
+ * @returns Um objeto com métodos para validação, transformação, sanitização e extração dos dados validados.
27
+ *
28
+ * @example
29
+ * type InputRaw = { limit?: string }
30
+ * type InputParsed = { limit?: number }
31
+ *
32
+ * const v = createValidator<InputRaw, InputParsed>()
33
+ * v.setInputs({ limit: '10' })
34
+ * v.validate('limit').type('string', 'Invalid').transform(Number)
35
+ * const inputs = v.getValidatedInputs() // { limit: 10 }
36
+ */
37
+ declare function createValidator<TRaw extends Record<string, TInputValue>, TParsed = TRaw>(): {
38
+ getErrors(): IInputErrors | undefined;
39
+ getFlatErrors(): Record<string, TMessage[]>;
40
+ getSanitizedInputs(): TParsed;
41
+ hasErrors(): boolean;
42
+ setInputs(inputs: TRaw): void;
43
+ unflattenErrors(flat: Record<string, TMessage[]>): Record<string, unknown>;
44
+ validate<K extends keyof TRaw>(field: K): {
45
+ isRequired(message: string): {
46
+ type(type: TTypes, message: string): {
47
+ each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
48
+ email: (message: string) => /*elided*/ any;
49
+ fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
50
+ fileType: (validTypes: string[], message: string) => /*elided*/ any;
51
+ length(length: number, message: string): /*elided*/ any;
52
+ min(min: number, message: string): /*elided*/ any;
53
+ max(max: number, message: string): /*elided*/ any;
54
+ transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
55
+ slug(message: string): /*elided*/ any;
56
+ sanitize(): /*elided*/ any;
57
+ sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
58
+ uuid(message: string): /*elided*/ any;
59
+ oneOf: (types: string[], message: string) => /*elided*/ any;
60
+ videoUrl: {
61
+ youtube(message: string): /*elided*/ any;
62
+ };
63
+ };
64
+ };
65
+ isNotRequired(): {
66
+ type(type: TTypes, message: string): {
67
+ each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
68
+ email: (message: string) => /*elided*/ any;
69
+ fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
70
+ fileType: (validTypes: string[], message: string) => /*elided*/ any;
71
+ length(length: number, message: string): /*elided*/ any;
72
+ min(min: number, message: string): /*elided*/ any;
73
+ max(max: number, message: string): /*elided*/ any;
74
+ transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
75
+ slug(message: string): /*elided*/ any;
76
+ sanitize(): /*elided*/ any;
77
+ sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
78
+ uuid(message: string): /*elided*/ any;
79
+ oneOf: (types: string[], message: string) => /*elided*/ any;
80
+ videoUrl: {
81
+ youtube(message: string): /*elided*/ any;
82
+ };
83
+ };
84
+ };
85
+ };
86
+ };
87
+
88
+ export { createValidator, htmlEntityDecode };
@@ -0,0 +1,88 @@
1
+ type Tag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'ul' | 'ol' | 'li' | 'span' | 'a' | 'strong' | 'em' | 'i' | 'br' | 'img';
2
+ type LexicalEditorAttributes = 'data-lexical-text' | 'style' | 'dir' | 'value';
3
+ type HTMLAttributes = 'href' | 'rel' | 'target' | 'alt' | 'title' | 'src' | 'class';
4
+ type Attributes = LexicalEditorAttributes | HTMLAttributes;
5
+ type AllowedTag = Tag | {
6
+ tag: Tag;
7
+ attributes?: Attributes[];
8
+ };
9
+ declare function htmlEntityDecode(value?: string): string;
10
+
11
+ type TMessage = {
12
+ message: string;
13
+ };
14
+ type TValue = string | number | boolean | File | object | null | undefined;
15
+ type TInputValue = TValue;
16
+ type TTypes = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'file' | 'date';
17
+ interface IInputErrors {
18
+ [key: string]: TMessage[] | IInputErrors[];
19
+ }
20
+ /**
21
+ * Cria um validador de inputs com suporte a validações encadeadas, transformação e sanitização.
22
+ *
23
+ * @template TRaw Tipo dos dados recebidos originalmente (geralmente string, vindo do query, body ou params).
24
+ * @template TParsed Tipo final retornado por `getValidatedInputs()` após transformações.
25
+ *
26
+ * @returns Um objeto com métodos para validação, transformação, sanitização e extração dos dados validados.
27
+ *
28
+ * @example
29
+ * type InputRaw = { limit?: string }
30
+ * type InputParsed = { limit?: number }
31
+ *
32
+ * const v = createValidator<InputRaw, InputParsed>()
33
+ * v.setInputs({ limit: '10' })
34
+ * v.validate('limit').type('string', 'Invalid').transform(Number)
35
+ * const inputs = v.getValidatedInputs() // { limit: 10 }
36
+ */
37
+ declare function createValidator<TRaw extends Record<string, TInputValue>, TParsed = TRaw>(): {
38
+ getErrors(): IInputErrors | undefined;
39
+ getFlatErrors(): Record<string, TMessage[]>;
40
+ getSanitizedInputs(): TParsed;
41
+ hasErrors(): boolean;
42
+ setInputs(inputs: TRaw): void;
43
+ unflattenErrors(flat: Record<string, TMessage[]>): Record<string, unknown>;
44
+ validate<K extends keyof TRaw>(field: K): {
45
+ isRequired(message: string): {
46
+ type(type: TTypes, message: string): {
47
+ each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
48
+ email: (message: string) => /*elided*/ any;
49
+ fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
50
+ fileType: (validTypes: string[], message: string) => /*elided*/ any;
51
+ length(length: number, message: string): /*elided*/ any;
52
+ min(min: number, message: string): /*elided*/ any;
53
+ max(max: number, message: string): /*elided*/ any;
54
+ transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
55
+ slug(message: string): /*elided*/ any;
56
+ sanitize(): /*elided*/ any;
57
+ sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
58
+ uuid(message: string): /*elided*/ any;
59
+ oneOf: (types: string[], message: string) => /*elided*/ any;
60
+ videoUrl: {
61
+ youtube(message: string): /*elided*/ any;
62
+ };
63
+ };
64
+ };
65
+ isNotRequired(): {
66
+ type(type: TTypes, message: string): {
67
+ each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
68
+ email: (message: string) => /*elided*/ any;
69
+ fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
70
+ fileType: (validTypes: string[], message: string) => /*elided*/ any;
71
+ length(length: number, message: string): /*elided*/ any;
72
+ min(min: number, message: string): /*elided*/ any;
73
+ max(max: number, message: string): /*elided*/ any;
74
+ transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
75
+ slug(message: string): /*elided*/ any;
76
+ sanitize(): /*elided*/ any;
77
+ sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
78
+ uuid(message: string): /*elided*/ any;
79
+ oneOf: (types: string[], message: string) => /*elided*/ any;
80
+ videoUrl: {
81
+ youtube(message: string): /*elided*/ any;
82
+ };
83
+ };
84
+ };
85
+ };
86
+ };
87
+
88
+ export { createValidator, htmlEntityDecode };