perfect-payload 2.0.0-beta.3 → 2.0.0-beta.4

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/framework.js CHANGED
@@ -1,4 +1,4 @@
1
- import { perfectPayload, perfectPayloadAsync } from "./index.js";
1
+ import { perfectPayloadForFramework, perfectPayloadAsyncForFramework, } from "./index.js";
2
2
  const SUPPORTED_REQUEST_SOURCES = [
3
3
  "headers",
4
4
  "params",
@@ -44,7 +44,7 @@ export function validateFrameworkSources({ data = {}, rule, options = {}, } = {}
44
44
  const sourceData = data?.[source] !== undefined && data?.[source] !== null
45
45
  ? data[source]
46
46
  : {};
47
- const result = perfectPayload(sourceData, frameworkRule[source], options);
47
+ const result = perfectPayloadForFramework(sourceData, frameworkRule[source], options, source);
48
48
  if (result.valid === true) {
49
49
  validatedPayload[source] = result.validatedPayload;
50
50
  continue;
@@ -54,15 +54,7 @@ export function validateFrameworkSources({ data = {}, rule, options = {}, } = {}
54
54
  invalidResponse = response;
55
55
  }
56
56
  for (const error of result.errors ?? []) {
57
- if (typeof error === "string") {
58
- errors.push(error);
59
- }
60
- else {
61
- errors.push({
62
- ...error,
63
- path: `${source}.${error.path}`,
64
- });
65
- }
57
+ errors.push(error);
66
58
  }
67
59
  }
68
60
  if (errors.length > 0) {
@@ -86,7 +78,7 @@ export async function validateFrameworkSourcesAsync({ data = {}, rule, options =
86
78
  const sourceData = data?.[source] !== undefined && data?.[source] !== null
87
79
  ? data[source]
88
80
  : {};
89
- const result = await perfectPayloadAsync(sourceData, frameworkRule[source], options);
81
+ const result = await perfectPayloadAsyncForFramework(sourceData, frameworkRule[source], options, source);
90
82
  return {
91
83
  source,
92
84
  result,
@@ -105,15 +97,7 @@ export async function validateFrameworkSourcesAsync({ data = {}, rule, options =
105
97
  invalidResponse = response;
106
98
  }
107
99
  for (const error of result.errors ?? []) {
108
- if (typeof error === "string") {
109
- errors.push(error);
110
- }
111
- else {
112
- errors.push({
113
- ...error,
114
- path: `${source}.${error.path}`,
115
- });
116
- }
100
+ errors.push(error);
117
101
  }
118
102
  }
119
103
  if (errors.length > 0) {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ValidationRules } from "./types/rules.js";
2
- import type { PerfectPayloadOptions, StructuredErrorOptions, PrettyErrorOptions } from "./types/options.js";
2
+ import type { ValidationOptions, StructuredErrorOptions, PrettyErrorOptions } from "./types/options.js";
3
3
  import type { ValidationResult } from "./types/results.js";
4
4
  type LegacyPayload = Record<string, any>;
5
5
  type LegacyValidationRules = Record<string, Record<string, any>>;
@@ -25,8 +25,11 @@ interface LegacyValidationResult {
25
25
  export declare function perfectPayloadV1(data?: LegacyPayload, dataValidationRule?: LegacyValidationRules, validPayloadResponse?: LegacyValidResponse, inValidPayloadResponse?: LegacyInvalidResponse): LegacyValidationResult;
26
26
  export declare function perfectPayload<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: PrettyErrorOptions): ValidationResult<T, string>;
27
27
  export declare function perfectPayload<T extends object = Record<string, unknown>>(data?: Record<string, unknown>, dataValidationRule?: ValidationRules, options?: StructuredErrorOptions): ValidationResult<T>;
28
- export declare function perfectPayload<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: PerfectPayloadOptions): ValidationResult<T> | ValidationResult<T, string>;
28
+ export declare function perfectPayload<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: ValidationOptions): ValidationResult<T> | ValidationResult<T, string>;
29
+ export declare function perfectPayloadForFramework<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: ValidationOptions | undefined, source: string): ValidationResult<T> | ValidationResult<T, string>;
29
30
  export declare function perfectPayloadAsync<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: PrettyErrorOptions): Promise<ValidationResult<T, string>>;
30
31
  export declare function perfectPayloadAsync<T extends object = Record<string, unknown>>(data?: Record<string, unknown>, dataValidationRule?: ValidationRules, options?: StructuredErrorOptions): Promise<ValidationResult<T>>;
31
- export declare function perfectPayloadAsync<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: PerfectPayloadOptions): Promise<ValidationResult<T> | ValidationResult<T, string>>;
32
+ export declare function perfectPayloadAsync<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: ValidationOptions): Promise<ValidationResult<T> | ValidationResult<T, string>>;
33
+ export declare function perfectPayloadAsyncForFramework<T extends object = Record<string, unknown>>(data: Record<string, unknown>, dataValidationRule: ValidationRules, options: ValidationOptions | undefined, source: string): Promise<ValidationResult<T> | ValidationResult<T, string>>;
32
34
  export type { AttributeValidationRules, ValidationRules, ValidationValueType, TransformFunction, CustomValidator, DependencyRule, DependencyRules, } from "./types/rules.js";
35
+ export type { ValidationOptions, StructuredErrorOptions, PrettyErrorOptions, UnknownFieldsMode, } from "./types/options.js";
package/dist/index.js CHANGED
@@ -1,3 +1,22 @@
1
+ const VALIDATION_RULE_ORDER = [
2
+ "allowNull",
3
+ "type",
4
+ "allowEmptyObject",
5
+ "allowEmptyArray",
6
+ "objectAttr",
7
+ "elementConstraints",
8
+ "minItems",
9
+ "maxItems",
10
+ "regex",
11
+ "minLength",
12
+ "maxLength",
13
+ "preventDecimal",
14
+ "min",
15
+ "max",
16
+ "range",
17
+ "dependency",
18
+ "customValidator",
19
+ ];
1
20
  let perfectPayloadV1DeprecationWarningShown = false;
2
21
  function showPerfectPayloadV1DeprecationWarning() {
3
22
  if (perfectPayloadV1DeprecationWarningShown)
@@ -443,6 +462,28 @@ export function perfectPayload(data = {}, dataValidationRule = {}, options = {})
443
462
  }
444
463
  return validationResult;
445
464
  }
465
+ export function perfectPayloadForFramework(data, dataValidationRule, options = {}, source) {
466
+ const { unknownFields = "strip", prettyErrors = false, validPayloadResponse = {
467
+ statusCode: 200,
468
+ valid: true,
469
+ }, inValidPayloadResponse = {
470
+ statusCode: 400,
471
+ valid: false,
472
+ message: "One or more attribute values are invalid",
473
+ }, } = options ?? {};
474
+ const validationResult = perfectPayloadStructured(data, dataValidationRule, validPayloadResponse, inValidPayloadResponse, source, {
475
+ unknownFields,
476
+ });
477
+ if (prettyErrors &&
478
+ validationResult.valid === false &&
479
+ validationResult.errors.length) {
480
+ return {
481
+ ...validationResult,
482
+ errors: validationResult.errors.map((error) => error.message),
483
+ };
484
+ }
485
+ return validationResult;
486
+ }
446
487
  export async function perfectPayloadAsync(data = {}, dataValidationRule = {}, options = {}) {
447
488
  const { validPayloadResponse = {
448
489
  statusCode: 200,
@@ -486,6 +527,43 @@ export async function perfectPayloadAsync(data = {}, dataValidationRule = {}, op
486
527
  }
487
528
  return validationResult;
488
529
  }
530
+ export async function perfectPayloadAsyncForFramework(data, dataValidationRule, options = {}, source) {
531
+ const { validPayloadResponse = {
532
+ statusCode: 200,
533
+ valid: true,
534
+ }, inValidPayloadResponse = {
535
+ statusCode: 400,
536
+ valid: false,
537
+ message: "One or more attribute values are invalid",
538
+ }, unknownFields = "strip", prettyErrors = false, } = options ?? {};
539
+ const validationResult = perfectPayloadStructured(data, dataValidationRule, validPayloadResponse, inValidPayloadResponse, source, {
540
+ skipCustomValidator: true,
541
+ unknownFields,
542
+ });
543
+ if (validationResult.valid === false && validationResult.errors.length) {
544
+ if (prettyErrors) {
545
+ return {
546
+ ...validationResult,
547
+ errors: validationResult.errors.map((error) => error.message),
548
+ };
549
+ }
550
+ return validationResult;
551
+ }
552
+ const rowErrors = await runAsyncCustomValidators(validationResult.valid === true ? validationResult.validatedPayload : {}, dataValidationRule, source);
553
+ if (rowErrors.length > 0) {
554
+ if (prettyErrors) {
555
+ return {
556
+ ...inValidPayloadResponse,
557
+ errors: rowErrors.map((error) => error.message),
558
+ };
559
+ }
560
+ return {
561
+ ...inValidPayloadResponse,
562
+ errors: rowErrors,
563
+ };
564
+ }
565
+ return validationResult;
566
+ }
489
567
  function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPayloadResponse = {
490
568
  statusCode: 200,
491
569
  valid: true,
@@ -493,7 +571,7 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
493
571
  statusCode: 400,
494
572
  valid: false,
495
573
  message: "One or more attribute values are invalid",
496
- }, basePath = "", options = {}) {
574
+ }, basePath = "", options = {}, rootPayload = data) {
497
575
  let validatedPayload = {};
498
576
  let rowErrors = [];
499
577
  const skipCustomValidator = options?.skipCustomValidator === true;
@@ -506,6 +584,14 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
506
584
  const nullAllowed = dataValidationRule?.[attributeName]?.["allowNull"] ?? true;
507
585
  const isMandatoryField = attributeRules?.["mandatory"] ?? false;
508
586
  const attrExist = Object.keys(data ?? {}).includes(attributeName);
587
+ const mandatoryValidationFailed = isMandatoryField && (!attrExist || attributeValue === "");
588
+ if (mandatoryValidationFailed) {
589
+ addNextError = false;
590
+ addStructuredError(rowErrors, attributePath, "REQUIRED", attributeRules?.["mandatoryError"] || `${attributePath} is mandatory`);
591
+ }
592
+ else if (!attrExist) {
593
+ addNextError = false;
594
+ }
509
595
  // TRANSFORMATIONS START
510
596
  // NO MULTI TRANSFORMATION
511
597
  if (attributeRules?.lowercase === true &&
@@ -513,35 +599,41 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
513
599
  throw new Error(`perfect-payload:- lowercase and uppercase cannot both be enabled for attribute ${attributePath}`);
514
600
  }
515
601
  // TRIM
516
- if (attrExist &&
602
+ if (addNextError &&
603
+ attrExist &&
517
604
  attributeValue !== null &&
518
605
  attributeRules?.trim === true &&
519
606
  typeof attributeValue === "string") {
520
607
  attributeValue = attributeValue.trim();
521
608
  }
522
609
  // LOWERCASE
523
- if (attrExist &&
610
+ if (addNextError &&
611
+ attrExist &&
524
612
  attributeValue !== null &&
525
613
  attributeRules?.lowercase === true &&
526
614
  typeof attributeValue === "string") {
527
615
  attributeValue = attributeValue.toLowerCase();
528
616
  }
529
617
  // UPPERCASE
530
- if (attrExist &&
618
+ if (addNextError &&
619
+ attrExist &&
531
620
  attributeValue !== null &&
532
621
  attributeRules?.uppercase === true &&
533
622
  typeof attributeValue === "string") {
534
623
  attributeValue = attributeValue.toUpperCase();
535
624
  }
536
625
  // CUSTOM TRANSFORM
537
- if (attrExist &&
626
+ if (addNextError &&
627
+ attrExist &&
538
628
  attributeValue !== null &&
539
629
  attributeRules?.transform !== undefined) {
540
630
  const transformer = attributeRules.transform;
541
631
  if (typeof transformer !== "function") {
542
632
  throw new Error(`perfect-payload:- transform must be a function for attribute ${attributePath}`);
543
633
  }
544
- const transformedValue = transformer(attributeValue, data);
634
+ const transformedValue = options.elementIndex !== undefined
635
+ ? transformer(attributeValue, options.elementIndex, rootPayload)
636
+ : transformer(attributeValue, rootPayload);
545
637
  if (transformedValue &&
546
638
  typeof transformedValue === "object" &&
547
639
  "then" in transformedValue &&
@@ -554,24 +646,11 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
554
646
  attributeValue = transformedValue;
555
647
  }
556
648
  // TRANSFORMATIONS END
557
- for (const ruleName in attributeRules) {
649
+ for (const ruleName of VALIDATION_RULE_ORDER) {
650
+ if (!(ruleName in attributeRules)) {
651
+ continue;
652
+ }
558
653
  switch (ruleName) {
559
- // ==================================================
560
- // MANDATORY
561
- // ==================================================
562
- case "mandatory":
563
- if (isMandatoryField && (!attrExist || attributeValue === "")) {
564
- addNextError = false;
565
- addStructuredError(rowErrors, attributePath, "REQUIRED", attributeRules?.["mandatoryError"] ||
566
- `${attributePath} is mandatory`);
567
- }
568
- else if (!attrExist) {
569
- addNextError = false;
570
- }
571
- break;
572
- // ==================================================
573
- // NULL
574
- // ==================================================
575
654
  case "allowNull":
576
655
  if (addNextError && attributeValue === null) {
577
656
  if (!attributeRules?.[ruleName]) {
@@ -581,9 +660,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
581
660
  }
582
661
  }
583
662
  break;
584
- // ==================================================
585
- // EMPTY OBJECT
586
- // ==================================================
587
663
  case "allowEmptyObject":
588
664
  if (addNextError) {
589
665
  if (!attributeRules?.["allowEmptyObject"] &&
@@ -595,9 +671,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
595
671
  }
596
672
  }
597
673
  break;
598
- // ==================================================
599
- // EMPTY ARRAY
600
- // ==================================================
601
674
  case "allowEmptyArray":
602
675
  if (addNextError) {
603
676
  if (!attributeRules?.["allowEmptyArray"] &&
@@ -609,9 +682,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
609
682
  }
610
683
  }
611
684
  break;
612
- // ==================================================
613
- // ARRAY ELEMENT CONSTRAINTS
614
- // ==================================================
615
685
  case "elementConstraints":
616
686
  if (addNextError) {
617
687
  if (isArray(attributeValue) && attributeValue.length > 0) {
@@ -632,7 +702,10 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
632
702
  statusCode: 400,
633
703
  valid: false,
634
704
  message: "One or more attribute values are invalid",
635
- }, "", options);
705
+ }, "", {
706
+ ...options,
707
+ elementIndex,
708
+ }, rootPayload);
636
709
  if (elementResult.valid === false &&
637
710
  elementResult.errors.length > 0) {
638
711
  const firstElementError = elementResult.errors[0];
@@ -698,9 +771,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
698
771
  }
699
772
  break;
700
773
  }
701
- // ==================================================
702
- // REGEX
703
- // ==================================================
704
774
  case "regex":
705
775
  if (addNextError) {
706
776
  if (!isPassedRegex(attributeRules[ruleName], attributeValue)) {
@@ -710,9 +780,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
710
780
  }
711
781
  }
712
782
  break;
713
- // ==================================================
714
- // TYPE
715
- // ==================================================
716
783
  case "type":
717
784
  if (addNextError) {
718
785
  if (attributeValue == null && nullAllowed) {
@@ -828,9 +895,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
828
895
  }
829
896
  }
830
897
  break;
831
- // ==================================================
832
- // MIN LENGTH
833
- // ==================================================
834
898
  case "minLength": {
835
899
  const minLength = attributeRules.minLength;
836
900
  if (addNextError) {
@@ -852,9 +916,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
852
916
  }
853
917
  break;
854
918
  }
855
- // ==================================================
856
- // MAX LENGTH
857
- // ==================================================
858
919
  case "maxLength": {
859
920
  const maxLength = attributeRules.maxLength;
860
921
  if (addNextError) {
@@ -876,9 +937,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
876
937
  }
877
938
  break;
878
939
  }
879
- // ==================================================
880
- // PREVENT DECIMAL
881
- // ==================================================
882
940
  case "preventDecimal":
883
941
  if (addNextError) {
884
942
  if (attributeValue == null && nullAllowed) {
@@ -895,9 +953,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
895
953
  }
896
954
  }
897
955
  break;
898
- // ==================================================
899
- // MIN
900
- // ==================================================
901
956
  case "min": {
902
957
  const min = attributeRules.min;
903
958
  if (addNextError) {
@@ -916,9 +971,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
916
971
  }
917
972
  break;
918
973
  }
919
- // ==================================================
920
- // MAX
921
- // ==================================================
922
974
  case "max": {
923
975
  const max = attributeRules.max;
924
976
  if (addNextError) {
@@ -937,9 +989,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
937
989
  }
938
990
  break;
939
991
  }
940
- // ==================================================
941
- // RANGE
942
- // ==================================================
943
992
  case "range": {
944
993
  const range = attributeRules.range;
945
994
  if (addNextError) {
@@ -961,9 +1010,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
961
1010
  }
962
1011
  break;
963
1012
  }
964
- // ==================================================
965
- // NESTED OBJECT
966
- // ==================================================
967
1013
  case "objectAttr": {
968
1014
  const objectAttr = attributeRules.objectAttr;
969
1015
  if (addNextError &&
@@ -975,7 +1021,7 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
975
1021
  statusCode: 400,
976
1022
  valid: false,
977
1023
  message: "One or more attribute values are invalid",
978
- }, attributePath, options);
1024
+ }, attributePath, options, rootPayload);
979
1025
  if (nestedResult.valid === true) {
980
1026
  attributeValue = nestedResult.validatedPayload;
981
1027
  }
@@ -985,9 +1031,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
985
1031
  }
986
1032
  break;
987
1033
  }
988
- // ==================================================
989
- // DEPENDENCY
990
- // ==================================================
991
1034
  case "dependency": {
992
1035
  const dependency = attributeRules.dependency;
993
1036
  if (addNextError && dependency !== undefined) {
@@ -1024,9 +1067,6 @@ function perfectPayloadStructured(data = {}, dataValidationRule = {}, validPaylo
1024
1067
  }
1025
1068
  break;
1026
1069
  }
1027
- // ==================================================
1028
- // CUSTOM VALIDATOR
1029
- // ==================================================
1030
1070
  case "customValidator":
1031
1071
  if (!skipCustomValidator &&
1032
1072
  addNextError &&
@@ -1179,7 +1219,7 @@ function isObjectId(id) {
1179
1219
  function isPassedRegex(reExpression, value) {
1180
1220
  return reExpression?.test(String(value)) ?? false;
1181
1221
  }
1182
- async function runAsyncCustomValidators(data = {}, dataValidationRule = {}, basePath = "") {
1222
+ async function runAsyncCustomValidators(data, dataValidationRule, basePath = "") {
1183
1223
  const errors = [];
1184
1224
  for (const attributeName in dataValidationRule) {
1185
1225
  const attributeRules = dataValidationRule?.[attributeName];
@@ -1,12 +1,12 @@
1
1
  import type { ValidationRules } from "./rules.js";
2
- import type { PerfectPayloadOptions } from "./options.js";
2
+ import type { ValidationOptions } from "./options.js";
3
3
  import type { ValidationError } from "./errors.js";
4
4
  export type RequestSource = "headers" | "params" | "query" | "body";
5
5
  export type FrameworkRule = Partial<Record<RequestSource, ValidationRules>>;
6
6
  export type FrameworkData = Partial<Record<RequestSource, Record<string, unknown>>>;
7
7
  export interface FrameworkConfig {
8
8
  rule?: FrameworkRule;
9
- options?: PerfectPayloadOptions;
9
+ options?: ValidationOptions;
10
10
  }
11
11
  export interface FrameworkValidationInput extends FrameworkConfig {
12
12
  data?: FrameworkData;
@@ -1,14 +1,14 @@
1
1
  import type { InvalidPayloadResponse, ValidPayloadResponse } from "./results.js";
2
2
  export type UnknownFieldsMode = "strip" | "allow" | "reject";
3
- export interface PerfectPayloadOptions {
3
+ export interface ValidationOptions {
4
4
  unknownFields?: UnknownFieldsMode;
5
5
  prettyErrors?: boolean;
6
6
  validPayloadResponse?: ValidPayloadResponse;
7
7
  inValidPayloadResponse?: InvalidPayloadResponse;
8
8
  }
9
- export interface StructuredErrorOptions extends PerfectPayloadOptions {
9
+ export interface StructuredErrorOptions extends ValidationOptions {
10
10
  prettyErrors?: false;
11
11
  }
12
- export interface PrettyErrorOptions extends PerfectPayloadOptions {
12
+ export interface PrettyErrorOptions extends ValidationOptions {
13
13
  prettyErrors: true;
14
14
  }
@@ -1,11 +1,12 @@
1
1
  export type ValidationValueType = "number" | "string" | "boolean" | "email" | "url" | "enum" | "uuid" | "uuidv1" | "uuidv3" | "uuidv4" | "uuidv5" | "objectId" | "array" | "object";
2
2
  export type TransformFunction = (value: unknown, payload: Record<string, unknown>) => unknown;
3
+ export type ArrayElementTransformFunction = (value: unknown, index: number, payload: Record<string, unknown>) => unknown;
3
4
  export type CustomValidator = (value: unknown, payload: Record<string, unknown>) => boolean | Promise<boolean>;
4
5
  export interface DependencyRule {
5
6
  setDependencyRule: (value: unknown, dependencyValue: unknown) => AttributeValidationRules;
6
7
  }
7
8
  export type DependencyRules = Record<string, DependencyRule>;
8
- export interface AttributeValidationRules {
9
+ export interface AttributeValidationRules<TTransform extends (...args: any[]) => unknown = TransformFunction> {
9
10
  mandatory?: boolean;
10
11
  allowNull?: boolean;
11
12
  allowEmptyObject?: boolean;
@@ -37,11 +38,11 @@ export interface AttributeValidationRules {
37
38
  minItems?: number;
38
39
  maxItems?: number;
39
40
  regex?: RegExp;
41
+ transform?: TTransform;
40
42
  objectAttr?: ValidationRules;
41
- elementConstraints?: AttributeValidationRules;
43
+ elementConstraints?: AttributeValidationRules<ArrayElementTransformFunction>;
42
44
  dependency?: DependencyRules;
43
45
  customValidator?: CustomValidator;
44
- transform?: TransformFunction;
45
46
  trim?: boolean;
46
47
  lowercase?: boolean;
47
48
  uppercase?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perfect-payload",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.4",
4
4
  "type": "module",
5
5
  "description": "Lightweight JSON payload validation library with structured errors, nested validation, field paths, and customizable validation rules.",
6
6
  "main": "./dist/index.js",