@fluojs/validation 1.0.5 → 2.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/README.ko.md +47 -1
- package/README.md +48 -1
- package/dist/decorators.d.ts +71 -69
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +73 -133
- package/dist/internal/decorator-factories.d.ts +12 -0
- package/dist/internal/decorator-factories.d.ts.map +1 -0
- package/dist/internal/decorator-factories.js +32 -0
- package/dist/internal/decorator-metadata.d.ts +7 -0
- package/dist/internal/decorator-metadata.d.ts.map +1 -0
- package/dist/internal/decorator-metadata.js +38 -0
- package/dist/internal/dto-materialization.d.ts +45 -0
- package/dist/internal/dto-materialization.d.ts.map +1 -0
- package/dist/internal/dto-materialization.js +204 -0
- package/dist/internal/dto-metadata-cache.d.ts +17 -0
- package/dist/internal/dto-metadata-cache.d.ts.map +1 -0
- package/dist/internal/dto-metadata-cache.js +49 -0
- package/dist/internal/enum-values.d.ts +2 -0
- package/dist/internal/enum-values.d.ts.map +1 -0
- package/dist/internal/enum-values.js +16 -0
- package/dist/internal/object-utils.d.ts +30 -0
- package/dist/internal/object-utils.d.ts.map +1 -0
- package/dist/internal/object-utils.js +53 -0
- package/dist/internal/rule-handlers.d.ts +19 -0
- package/dist/internal/rule-handlers.d.ts.map +1 -0
- package/dist/internal/rule-handlers.js +209 -0
- package/dist/internal/validation-issues.d.ts +13 -0
- package/dist/internal/validation-issues.d.ts.map +1 -0
- package/dist/internal/validation-issues.js +44 -0
- package/dist/internal/validator-js-adapter.d.ts +5 -0
- package/dist/internal/validator-js-adapter.d.ts.map +1 -0
- package/dist/internal/validator-js-adapter.js +88 -0
- package/dist/mapped-types.d.ts +1 -1
- package/dist/mapped-types.d.ts.map +1 -1
- package/dist/mapped-types.js +1 -1
- package/dist/standard-schema.d.ts +1 -1
- package/dist/standard-schema.d.ts.map +1 -1
- package/dist/types.d.ts +18 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +2 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +24 -509
- package/package.json +4 -4
package/README.ko.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
<p><a href="./README.md"><kbd>English</kbd></a> <strong><kbd>한국어</kbd></strong></p>
|
|
4
4
|
|
|
5
|
+
Node.js 지원 범위는 `>=24.0.0 <27`입니다. 업그레이드 절차는 [Node.js 지원 및 마이그레이션](../../docs/reference/node-support.ko.md)을 참조하세요.
|
|
6
|
+
|
|
5
7
|
fluo를 위한 입력값 검증 데코레이터, Mapped DTO 헬퍼 및 검증 엔진입니다.
|
|
6
8
|
|
|
7
9
|
## 목차
|
|
@@ -74,12 +76,39 @@ class rule이 실행되기 전에 deterministic `DtoValidationError`로 거부
|
|
|
74
76
|
DTO 바인딩 메타데이터를 적용한 뒤 `@ValidateNested(...)` 필드를 재귀적으로
|
|
75
77
|
실체화합니다. 어떤 요청 소스를 선택하고 스칼라 값을 변환할지는 transport 또는
|
|
76
78
|
binder가 검증 전에 담당한다는 request-pipeline 계약을 유지합니다.
|
|
79
|
+
Plain 입력 객체를 materialize할 때 안전한 추가 own enumerable 속성은 기본적으로 유지됩니다. `__proto__`, `constructor`,
|
|
80
|
+
`prototype` 같은 위험한 key와 inherited 또는 non-enumerable 속성만 제외합니다.
|
|
81
|
+
세 번째 `materialize()` 인자로 `{ undeclaredProperties: 'reject' }`를 전달하면
|
|
82
|
+
초기화된 DTO field, validation 또는 binding metadata field, binding alias로 선언되지
|
|
83
|
+
않은 안전한 enumerable 속성을 거부합니다. 이 정책은 plain nested DTO 값에도
|
|
84
|
+
재귀적으로 적용되며 입력을 조용히 제거하지 않고 `UNDECLARED_PROPERTY` issue를
|
|
85
|
+
보고합니다. 기존 DTO instance는 undeclared-property 경계로 검사하지 않습니다.
|
|
77
86
|
선언된 중첩 DTO의 인스턴스인 기존 중첩 값은 그대로 보존하고, plain 중첩 값만
|
|
78
87
|
해당 필드 또는 collection entry 단위로 실체화합니다.
|
|
79
88
|
`materialize()`에 넘기는 루트 값은 plain 객체이거나 대상 DTO 인스턴스여야 합니다.
|
|
80
89
|
문자열, 배열, `null` 같은 잘못된 루트 값은 대상 DTO 생성자나 필드 initializer가
|
|
81
90
|
실행되기 전에 거부됩니다.
|
|
82
91
|
|
|
92
|
+
### 누락 값과 validation group
|
|
93
|
+
|
|
94
|
+
일반 field validator는 `null`과 `undefined`를 모두 건너뜁니다. 두 값 중 하나라도
|
|
95
|
+
누락된 필수 field로 실패해야 한다면 `@IsDefined()`를 추가하세요. Optional 계약을
|
|
96
|
+
명시하고 해당 field의 다른 validator를 short-circuit하려면 `@IsOptional()`을
|
|
97
|
+
사용할 수 있습니다.
|
|
98
|
+
|
|
99
|
+
Validation group은 지원되는 실행 surface가 아닙니다. Decorator option에는
|
|
100
|
+
class-validator 스타일의 `groups` 또는 `always`가 없고, `validate()`와
|
|
101
|
+
`materialize()`도 group 선택을 받지 않습니다. Group 기반 실행을 가정하지 말고
|
|
102
|
+
별도 DTO, mapped DTO helper, `@ValidateIf(...)`, 명시적 class-level validation으로
|
|
103
|
+
workflow 차이를 모델링하세요.
|
|
104
|
+
|
|
105
|
+
### DTO 상속
|
|
106
|
+
|
|
107
|
+
Derived DTO는 base DTO의 field-level 및 class-level validation rule을 상속합니다.
|
|
108
|
+
Derived DTO에 validation decorator를 추가하면 derived DTO가 소유하는 metadata가
|
|
109
|
+
생성되며 base DTO의 검증 동작은 바뀌지 않습니다. Mapped DTO helper가 반환한 class를
|
|
110
|
+
확장할 때도 같은 격리가 유지됩니다.
|
|
111
|
+
|
|
83
112
|
### 검증 이슈 형태
|
|
84
113
|
|
|
85
114
|
`DtoValidationError.issues`는 request-pipeline 오류 상세에 사용하는 안정적인 DTO입니다.
|
|
@@ -118,6 +147,11 @@ validation 및 binding metadata를 보존합니다. `PickType`, `OmitType`,
|
|
|
118
147
|
`PartialType`은 생략되었거나 optional이 된 필드에 의존할 수 있는 base
|
|
119
148
|
class-level validator를 derived DTO로 전달하지 않습니다.
|
|
120
149
|
|
|
150
|
+
`IntersectionType(...)` source가 같은 property에 서로 다른
|
|
151
|
+
`@ValidateNested(...)` target을 선언하면 모든 nested rule이 보존되고 검증됩니다.
|
|
152
|
+
공유 property의 plain value는 초기 실체화 중 plain 상태로 유지되므로 각 nested
|
|
153
|
+
target이 해당 value를 독립적으로 실체화하고 검증할 수 있습니다.
|
|
154
|
+
|
|
121
155
|
### Standard Schema 지원
|
|
122
156
|
|
|
123
157
|
Standard Schema adapter는 유효하지 않은 입력을 명시적인 issue로 보고해야 합니다. issue가 없는 검증 결과는 성공으로 처리합니다.
|
|
@@ -136,6 +170,14 @@ class RestrictedUserDto {
|
|
|
136
170
|
|
|
137
171
|
`ValidateClass(...)`는 custom class-level validator도 받을 수 있습니다. `Validate(...)`는 built-in decorator만으로 부족할 때 custom field-level validator를 붙이고, `ValidateIf(...)`는 predicate가 false를 반환하면 dependent validator를 short-circuit합니다.
|
|
138
172
|
|
|
173
|
+
### Custom field 검증
|
|
174
|
+
|
|
175
|
+
`Validate(callback)`는 callback을 `(value, context)`로 호출합니다. `context.dto`는
|
|
176
|
+
포함하는 DTO이고, `context.propertyKey`는 decorator가 적용된 field key입니다.
|
|
177
|
+
|
|
178
|
+
`@IsObject()`는 null-prototype record를 포함한 plain object만 허용합니다. Class
|
|
179
|
+
instance, `Date`, `Map`, `Set` 값은 거부합니다.
|
|
180
|
+
|
|
139
181
|
### 네트워크 검증기
|
|
140
182
|
|
|
141
183
|
`@IsIP()`는 기본적으로 IPv4와 IPv6 문자열을 모두 검증합니다. 한 IP 버전으로
|
|
@@ -146,6 +188,7 @@ IPv6 모두 허용" 계약을 명시하고 싶을 때 사용할 수 있습니다
|
|
|
146
188
|
### 중첩 검증
|
|
147
189
|
|
|
148
190
|
`@ValidateNested(...)`는 객체 필드, 배열, `Set`, `Map`을 지원합니다. 중첩 DTO path는 validation issue에서 dot/index 표기법을 사용하며, cycle은 안전하게 감지되고 shared reference는 허용됩니다.
|
|
191
|
+
Array, `Set`, `Map` member는 자동으로 검증되고 실체화되므로 nested collection 순회를 활성화하기 위해 `each: true`를 지정할 필요가 없습니다. 기존 DTO를 위해 이 option은 계속 허용됩니다.
|
|
149
192
|
중첩 타입을 지연 해석해야 할 때는 DTO 클래스 자체나 `() => ChildDto`, `function resolveChildDto() { return ChildDto; }` 같은 lazy constructor factory를 전달할 수 있습니다.
|
|
150
193
|
|
|
151
194
|
### 암묵적 scalar coercion 없음
|
|
@@ -153,9 +196,12 @@ IPv6 모두 허용" 계약을 명시하고 싶을 때 사용할 수 있습니다
|
|
|
153
196
|
`materialize()`는 의도적으로 엄격합니다. Transport가 `'42'`를 넘기고 DTO가 `number`를 기대한다면, transport나 binding layer가 먼저 변환해야 합니다.
|
|
154
197
|
`@IsLatitude()`, `@IsLongitude()`를 포함한 numeric validator는 numeric string을 이미 변환된 number처럼 취급하지 않고 DTO의 numeric 값을 검증합니다.
|
|
155
198
|
|
|
199
|
+
`@IsEnum(...)`은 선언된 enum 값만 허용합니다. 숫자형 TypeScript enum에서 생성된
|
|
200
|
+
reverse-map 멤버 이름은 값이 아니므로 거부됩니다.
|
|
201
|
+
|
|
156
202
|
## 공개 API
|
|
157
203
|
|
|
158
|
-
- **검증 엔진**: `DefaultValidator`, `DtoValidationError`, `ValidationIssue`, `Validator`
|
|
204
|
+
- **검증 엔진**: `DefaultValidator`, `DtoValidationError`, `MaterializeOptions`, `ValidationIssue`, `Validator`
|
|
159
205
|
- **핵심 데코레이터**: `IsString`, `IsNumber`, `IsBoolean`, `IsDate`, `IsArray`, `IsObject`, `IsEnum`, `IsInt`, `IsDefined`, `IsOptional`, `ValidateNested`, `ValidateIf`, `Validate`, `ValidateClass`
|
|
160
206
|
- **존재 및 비교 데코레이터**: `IsEmpty`, `IsNotEmpty`, `Equals`, `NotEquals`, `IsIn`, `IsNotIn`
|
|
161
207
|
- **문자열 및 네트워크 데코레이터**: `IsEmail`, `IsUrl`, `IsUUID`, `IsIP`, `IsAlpha`, `IsAlphanumeric`, `IsAscii`, `IsBase64`, `IsBooleanString`, `IsDataURI`, `IsDateString`, `IsDecimal`, `IsFQDN`, `IsHexColor`, `IsHexadecimal`, `IsJSON`, `IsJWT`, `IsLocale`, `IsLowercase`, `IsMagnetURI`, `IsMimeType`, `IsMongoId`, `IsNumberString`, `IsPort`, `IsRFC3339`, `IsSemVer`, `IsUppercase`, `IsISO8601`, `Matches`, `Length`, `MinLength`, `MaxLength`, `Contains`, `NotContains`
|
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
<p><strong><kbd>English</kbd></strong> <a href="./README.ko.md"><kbd>한국어</kbd></a></p>
|
|
4
4
|
|
|
5
|
+
Node.js support is `>=24.0.0 <27`. See [Node.js support and migration](../../docs/reference/node-support.md) before upgrading.
|
|
6
|
+
|
|
5
7
|
Input-side validation decorators, mapped DTO helpers, and the validation engine for fluo.
|
|
6
8
|
|
|
7
9
|
## Table of Contents
|
|
@@ -77,6 +79,14 @@ coercion.
|
|
|
77
79
|
applies DTO binding metadata, and recursively hydrates `@ValidateNested(...)`
|
|
78
80
|
fields. It preserves the request-pipeline contract that transports or binders own
|
|
79
81
|
source selection and scalar conversion before validation runs.
|
|
82
|
+
When materializing a plain input object, safe extra own enumerable properties are retained by default; only dangerous keys such as
|
|
83
|
+
`__proto__`, `constructor`, and `prototype`, plus inherited or non-enumerable
|
|
84
|
+
properties, are excluded. Pass `{ undeclaredProperties: 'reject' }` as the third
|
|
85
|
+
`materialize()` argument to reject safe enumerable properties that are not
|
|
86
|
+
initialized DTO fields, validation or binding metadata fields, or binding aliases.
|
|
87
|
+
The policy applies recursively to plain nested DTO values and reports
|
|
88
|
+
`UNDECLARED_PROPERTY` issues instead of silently stripping input. Existing DTO
|
|
89
|
+
instances are not an undeclared-property boundary.
|
|
80
90
|
Existing nested values that are already instances of the declared nested DTO are
|
|
81
91
|
preserved; plain nested values are hydrated only for the affected nested field or
|
|
82
92
|
collection entry.
|
|
@@ -84,6 +94,26 @@ The root value passed to `materialize()` must already be a plain object or an
|
|
|
84
94
|
instance of the target DTO; malformed roots such as strings, arrays, and `null`
|
|
85
95
|
are rejected before the target DTO constructor or field initializers run.
|
|
86
96
|
|
|
97
|
+
### Missing values and validation groups
|
|
98
|
+
|
|
99
|
+
Ordinary field validators skip both `null` and `undefined`. Add `@IsDefined()`
|
|
100
|
+
when either value must fail as a missing required field. `@IsOptional()` remains
|
|
101
|
+
useful when the optional contract should be explicit and should short-circuit the
|
|
102
|
+
other validators on that field.
|
|
103
|
+
|
|
104
|
+
Validation groups are not a supported execution surface. Decorator options do
|
|
105
|
+
not include class-validator-style `groups` or `always`, and `validate()` /
|
|
106
|
+
`materialize()` do not accept a group selection. Model different workflows with
|
|
107
|
+
separate DTOs, mapped DTO helpers, `@ValidateIf(...)`, or explicit class-level
|
|
108
|
+
validation instead of assuming group-based execution.
|
|
109
|
+
|
|
110
|
+
### DTO inheritance
|
|
111
|
+
|
|
112
|
+
Derived DTOs inherit field-level and class-level validation rules from their base
|
|
113
|
+
DTO. Adding validation decorators to the derived DTO creates derived-owned
|
|
114
|
+
metadata and does not change how the base DTO validates. The same isolation holds
|
|
115
|
+
when extending a class returned by a mapped DTO helper.
|
|
116
|
+
|
|
87
117
|
### Validation issue shape
|
|
88
118
|
|
|
89
119
|
`DtoValidationError.issues` is a stable DTO for request-pipeline error details:
|
|
@@ -122,6 +152,11 @@ the documented subclassing pattern shown above. `PickType`, `OmitType`, and
|
|
|
122
152
|
`PartialType` do not carry base class-level validators onto derived DTOs because
|
|
123
153
|
those validators can depend on fields that were omitted or made optional.
|
|
124
154
|
|
|
155
|
+
When `IntersectionType(...)` sources declare different `@ValidateNested(...)`
|
|
156
|
+
targets for the same property, every nested rule is preserved and validated.
|
|
157
|
+
Plain values for that shared property remain plain during the initial hydration
|
|
158
|
+
so each nested target can materialize and validate the value independently.
|
|
159
|
+
|
|
125
160
|
### Standard Schema support
|
|
126
161
|
|
|
127
162
|
Standard Schema adapters are expected to report invalid input through explicit issues. Validation results without issues are treated as successful.
|
|
@@ -140,6 +175,14 @@ class RestrictedUserDto {
|
|
|
140
175
|
|
|
141
176
|
`ValidateClass(...)` also accepts custom class-level validators. `Validate(...)` attaches custom field-level validators when built-in decorators are not enough, and `ValidateIf(...)` short-circuits dependent validators when its predicate returns false.
|
|
142
177
|
|
|
178
|
+
### Custom field validation
|
|
179
|
+
|
|
180
|
+
`Validate(callback)` invokes `callback(value, context)`. `context.dto` is the
|
|
181
|
+
containing DTO, and `context.propertyKey` is the decorated field key.
|
|
182
|
+
|
|
183
|
+
`@IsObject()` accepts only plain objects, including null-prototype records. It
|
|
184
|
+
rejects class instances, `Date`, `Map`, and `Set` values.
|
|
185
|
+
|
|
143
186
|
### Network validators
|
|
144
187
|
|
|
145
188
|
`@IsIP()` validates IPv4 and IPv6 strings by default. Pass `@IsIP('4')` or
|
|
@@ -150,6 +193,7 @@ contract explicitly while still using the same runtime behavior as `@IsIP()`.
|
|
|
150
193
|
### Nested validation
|
|
151
194
|
|
|
152
195
|
`@ValidateNested(...)` supports object fields, arrays, `Set`, and `Map`. Nested DTO paths use dot/index notation in validation issues, cycles are detected safely, and shared references are allowed.
|
|
196
|
+
Array, `Set`, and `Map` members are validated and materialized automatically; `each: true` is not required to enable nested collection traversal. The option remains accepted for existing DTOs.
|
|
153
197
|
Pass either a DTO class or a lazy constructor factory such as `() => ChildDto` or `function resolveChildDto() { return ChildDto; }` when nested types need deferred resolution.
|
|
154
198
|
|
|
155
199
|
### No implicit scalar coercion
|
|
@@ -157,9 +201,12 @@ Pass either a DTO class or a lazy constructor factory such as `() => ChildDto` o
|
|
|
157
201
|
`materialize()` is intentionally strict. If a transport gives you `'42'` and your DTO expects `number`, the transport or binding layer must convert it first.
|
|
158
202
|
Numeric validators, including `@IsLatitude()` and `@IsLongitude()`, validate numeric DTO values without treating numeric strings as already-converted numbers.
|
|
159
203
|
|
|
204
|
+
`@IsEnum(...)` accepts declared enum values. For numeric TypeScript enums, generated
|
|
205
|
+
reverse-map member names are not values and are rejected.
|
|
206
|
+
|
|
160
207
|
## Public API
|
|
161
208
|
|
|
162
|
-
- **Validator engine**: `DefaultValidator`, `DtoValidationError`, `ValidationIssue`, `Validator`
|
|
209
|
+
- **Validator engine**: `DefaultValidator`, `DtoValidationError`, `MaterializeOptions`, `ValidationIssue`, `Validator`
|
|
163
210
|
- **Core decorators**: `IsString`, `IsNumber`, `IsBoolean`, `IsDate`, `IsArray`, `IsObject`, `IsEnum`, `IsInt`, `IsDefined`, `IsOptional`, `ValidateNested`, `ValidateIf`, `Validate`, `ValidateClass`
|
|
164
211
|
- **Presence and comparison decorators**: `IsEmpty`, `IsNotEmpty`, `Equals`, `NotEquals`, `IsIn`, `IsNotIn`
|
|
165
212
|
- **String and network decorators**: `IsEmail`, `IsUrl`, `IsUUID`, `IsIP`, `IsAlpha`, `IsAlphanumeric`, `IsAscii`, `IsBase64`, `IsBooleanString`, `IsDataURI`, `IsDateString`, `IsDecimal`, `IsFQDN`, `IsHexColor`, `IsHexadecimal`, `IsJSON`, `IsJWT`, `IsLocale`, `IsLowercase`, `IsMagnetURI`, `IsMimeType`, `IsMongoId`, `IsNumberString`, `IsPort`, `IsRFC3339`, `IsSemVer`, `IsUppercase`, `IsISO8601`, `Matches`, `Length`, `MinLength`, `MaxLength`, `Contains`, `NotContains`
|