valdex 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/LICENSE +21 -0
- package/README.md +151 -0
- package/dist/index.d.mts +101 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +138 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Jaewook Lee
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# valdex
|
|
2
|
+
|
|
3
|
+
Runtime type validation with TypeScript type inference.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install valdex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Runtime type validation for unknown data
|
|
14
|
+
- Automatic TypeScript type inference from schema
|
|
15
|
+
- Support for nested objects and arrays
|
|
16
|
+
- Optional and nullable field modifiers
|
|
17
|
+
- Zero dependencies
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Basic Validation
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { validate } from 'valdex';
|
|
25
|
+
|
|
26
|
+
const data: unknown = await fetchData();
|
|
27
|
+
|
|
28
|
+
validate(data, {
|
|
29
|
+
name: String,
|
|
30
|
+
age: Number,
|
|
31
|
+
active: Boolean
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// TypeScript now knows the exact type of data
|
|
35
|
+
data.name // string
|
|
36
|
+
data.age // number
|
|
37
|
+
data.active // boolean
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Nested Objects
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
validate(data, {
|
|
44
|
+
user: {
|
|
45
|
+
id: Number,
|
|
46
|
+
profile: {
|
|
47
|
+
name: String,
|
|
48
|
+
email: String
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
data.user.profile.name // string
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Arrays
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
validate(data, {
|
|
60
|
+
tags: [String], // string[]
|
|
61
|
+
items: [{ // { id: number, name: string }[]
|
|
62
|
+
id: Number,
|
|
63
|
+
name: String
|
|
64
|
+
}]
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
data.tags[0] // string
|
|
68
|
+
data.items[0].id // number
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Optional Fields
|
|
72
|
+
|
|
73
|
+
Use `Optional()` to allow `undefined` values:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { validate, Optional } from 'valdex';
|
|
77
|
+
|
|
78
|
+
validate(data, {
|
|
79
|
+
required: String,
|
|
80
|
+
optional: Optional(String), // string | undefined
|
|
81
|
+
optionalObject: Optional({ // { id: number } | undefined
|
|
82
|
+
id: Number
|
|
83
|
+
}),
|
|
84
|
+
optionalArray: Optional([Number]) // number[] | undefined
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Nullable Fields
|
|
89
|
+
|
|
90
|
+
Use `Nullable()` to allow `null` values:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { validate, Nullable } from 'valdex';
|
|
94
|
+
|
|
95
|
+
validate(data, {
|
|
96
|
+
required: String,
|
|
97
|
+
nullable: Nullable(String), // string | null
|
|
98
|
+
nullableObject: Nullable({ // { id: number } | null
|
|
99
|
+
id: Number
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Combining Optional and Nullable
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { validate, Optional, Nullable } from 'valdex';
|
|
108
|
+
|
|
109
|
+
validate(data, {
|
|
110
|
+
field: Optional(Nullable(String)) // string | undefined | null
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Supported Types
|
|
115
|
+
|
|
116
|
+
| Constructor | TypeScript Type |
|
|
117
|
+
|-------------|-----------------|
|
|
118
|
+
| `String` | `string` |
|
|
119
|
+
| `Number` | `number` |
|
|
120
|
+
| `Boolean` | `boolean` |
|
|
121
|
+
| `Array` | `any[]` |
|
|
122
|
+
| `Object` | `object` |
|
|
123
|
+
|
|
124
|
+
## Error Handling
|
|
125
|
+
|
|
126
|
+
When validation fails, a `RuntimeTypeError` is thrown:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { validate, RuntimeTypeError } from 'valdex';
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
validate(data, { count: Number });
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (error instanceof RuntimeTypeError) {
|
|
135
|
+
console.error(error.message);
|
|
136
|
+
// "count must be Number, but got String. Actual value: hello"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## How It Works
|
|
142
|
+
|
|
143
|
+
- Fields not declared in the schema but present in data are ignored
|
|
144
|
+
- All declared fields are required by default (no `undefined` or `null`)
|
|
145
|
+
- Use `Optional()` to allow `undefined`
|
|
146
|
+
- Use `Nullable()` to allow `null`
|
|
147
|
+
- `NaN` is not considered a valid `Number`
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
type OptionalMarker = {
|
|
2
|
+
__optional: true;
|
|
3
|
+
};
|
|
4
|
+
type NullableMarker = {
|
|
5
|
+
__nullable: true;
|
|
6
|
+
};
|
|
7
|
+
type ArraySchema = [PrimitiveType | Expression];
|
|
8
|
+
type Expression = {
|
|
9
|
+
[key: string | number]: PrimitiveType | (PrimitiveType & OptionalMarker) | (PrimitiveType & NullableMarker) | (PrimitiveType & OptionalMarker & NullableMarker) | Expression | (Expression & OptionalMarker) | (Expression & NullableMarker) | (Expression & OptionalMarker & NullableMarker) | ArraySchema | (ArraySchema & OptionalMarker) | (ArraySchema & NullableMarker) | (ArraySchema & OptionalMarker & NullableMarker);
|
|
10
|
+
};
|
|
11
|
+
type PrimitiveType = NumberConstructor | StringConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;
|
|
12
|
+
type InferPrimitiveType<T> = T extends NumberConstructor ? number : T extends StringConstructor ? string : T extends BooleanConstructor ? boolean : T extends ArrayConstructor ? any[] : T extends ObjectConstructor ? object : never;
|
|
13
|
+
type InferType<T> = T extends PrimitiveType & OptionalMarker & NullableMarker ? InferPrimitiveType<T> | undefined | null : T extends PrimitiveType & OptionalMarker ? InferPrimitiveType<T> | undefined : T extends PrimitiveType & NullableMarker ? InferPrimitiveType<T> | null : T extends PrimitiveType ? InferPrimitiveType<T> : T extends Expression & OptionalMarker & NullableMarker ? {
|
|
14
|
+
[K in keyof T]: InferType<T[K]>;
|
|
15
|
+
} | undefined | null : T extends Expression & OptionalMarker ? {
|
|
16
|
+
[K in keyof T]: InferType<T[K]>;
|
|
17
|
+
} | undefined : T extends Expression & NullableMarker ? {
|
|
18
|
+
[K in keyof T]: InferType<T[K]>;
|
|
19
|
+
} | null : T extends ArraySchema & OptionalMarker & NullableMarker ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined | null : T extends ArraySchema & OptionalMarker ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined : T extends ArraySchema & NullableMarker ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | null : T extends [infer U] ? U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never : T extends Expression ? {
|
|
20
|
+
[K in keyof T]: InferType<T[K]>;
|
|
21
|
+
} : never;
|
|
22
|
+
/**
|
|
23
|
+
* Marks a field as optional.
|
|
24
|
+
* Optional fields pass validation even if they are undefined.
|
|
25
|
+
* The type is inferred as T | undefined.
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* validate(data, {
|
|
29
|
+
* required_field: String, // string (required)
|
|
30
|
+
* optional_field: Optional(String), // string | undefined
|
|
31
|
+
* optional_object: Optional({ // { id: string } | undefined
|
|
32
|
+
* id: String
|
|
33
|
+
* }),
|
|
34
|
+
* optional_array: Optional([String]) // string[] | undefined
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
declare function Optional<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & OptionalMarker;
|
|
39
|
+
/**
|
|
40
|
+
* Marks a field as nullable.
|
|
41
|
+
* Nullable fields pass validation even if they are null.
|
|
42
|
+
* The type is inferred as T | null.
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* validate(data, {
|
|
46
|
+
* required_field: String, // string (required)
|
|
47
|
+
* nullable_field: Nullable(String), // string | null
|
|
48
|
+
* nullable_object: Nullable({ // { id: string } | null
|
|
49
|
+
* id: String
|
|
50
|
+
* }),
|
|
51
|
+
* nullable_array: Nullable([String]) // string[] | null
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
declare function Nullable<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & NullableMarker;
|
|
56
|
+
declare class RuntimeTypeError extends Error {
|
|
57
|
+
constructor(key: string, requiredType: string, actualType: string, actualValue: any, message?: string);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Asserts the type of target according to the expression schema.
|
|
61
|
+
* The expression should be represented using primitive type constructors.
|
|
62
|
+
* Supports nested types and array element type validation.
|
|
63
|
+
*
|
|
64
|
+
* Fields not declared in the expression but present in target are ignored.
|
|
65
|
+
*
|
|
66
|
+
* Fields declared in the expression do not allow undefined or null by default.
|
|
67
|
+
* Wrap with Optional() to allow undefined.
|
|
68
|
+
* Wrap with Nullable() to allow null.
|
|
69
|
+
*
|
|
70
|
+
* @param target - The value to validate
|
|
71
|
+
* @param expression - The schema expression to validate against
|
|
72
|
+
* @throws {RuntimeTypeError} When type mismatch occurs
|
|
73
|
+
* @throws {RuntimeTypeError} When value is undefined or null (unless optional/nullable)
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const data: unknown = getData();
|
|
77
|
+
*
|
|
78
|
+
* validate(data, {
|
|
79
|
+
* "a": Boolean,
|
|
80
|
+
* "b": {
|
|
81
|
+
* "c": Number,
|
|
82
|
+
* "d": Optional(String), // string | undefined
|
|
83
|
+
* "e": Nullable(String) // string | null
|
|
84
|
+
* },
|
|
85
|
+
* "items": [{
|
|
86
|
+
* "name": String,
|
|
87
|
+
* "value": Number
|
|
88
|
+
* }]
|
|
89
|
+
* });
|
|
90
|
+
*
|
|
91
|
+
* // From this point, data is type-asserted
|
|
92
|
+
* data.a // boolean
|
|
93
|
+
* data.b.c // number
|
|
94
|
+
* data.b.d // string | undefined
|
|
95
|
+
* data.b.e // string | null
|
|
96
|
+
* data.items[0].name // string
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function validate<T extends Expression>(target: any, expression: T, path?: string): asserts target is InferType<T>;
|
|
100
|
+
|
|
101
|
+
export { Nullable, Optional, RuntimeTypeError, validate };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
type OptionalMarker = {
|
|
2
|
+
__optional: true;
|
|
3
|
+
};
|
|
4
|
+
type NullableMarker = {
|
|
5
|
+
__nullable: true;
|
|
6
|
+
};
|
|
7
|
+
type ArraySchema = [PrimitiveType | Expression];
|
|
8
|
+
type Expression = {
|
|
9
|
+
[key: string | number]: PrimitiveType | (PrimitiveType & OptionalMarker) | (PrimitiveType & NullableMarker) | (PrimitiveType & OptionalMarker & NullableMarker) | Expression | (Expression & OptionalMarker) | (Expression & NullableMarker) | (Expression & OptionalMarker & NullableMarker) | ArraySchema | (ArraySchema & OptionalMarker) | (ArraySchema & NullableMarker) | (ArraySchema & OptionalMarker & NullableMarker);
|
|
10
|
+
};
|
|
11
|
+
type PrimitiveType = NumberConstructor | StringConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;
|
|
12
|
+
type InferPrimitiveType<T> = T extends NumberConstructor ? number : T extends StringConstructor ? string : T extends BooleanConstructor ? boolean : T extends ArrayConstructor ? any[] : T extends ObjectConstructor ? object : never;
|
|
13
|
+
type InferType<T> = T extends PrimitiveType & OptionalMarker & NullableMarker ? InferPrimitiveType<T> | undefined | null : T extends PrimitiveType & OptionalMarker ? InferPrimitiveType<T> | undefined : T extends PrimitiveType & NullableMarker ? InferPrimitiveType<T> | null : T extends PrimitiveType ? InferPrimitiveType<T> : T extends Expression & OptionalMarker & NullableMarker ? {
|
|
14
|
+
[K in keyof T]: InferType<T[K]>;
|
|
15
|
+
} | undefined | null : T extends Expression & OptionalMarker ? {
|
|
16
|
+
[K in keyof T]: InferType<T[K]>;
|
|
17
|
+
} | undefined : T extends Expression & NullableMarker ? {
|
|
18
|
+
[K in keyof T]: InferType<T[K]>;
|
|
19
|
+
} | null : T extends ArraySchema & OptionalMarker & NullableMarker ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined | null : T extends ArraySchema & OptionalMarker ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined : T extends ArraySchema & NullableMarker ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | null : T extends [infer U] ? U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never : T extends Expression ? {
|
|
20
|
+
[K in keyof T]: InferType<T[K]>;
|
|
21
|
+
} : never;
|
|
22
|
+
/**
|
|
23
|
+
* Marks a field as optional.
|
|
24
|
+
* Optional fields pass validation even if they are undefined.
|
|
25
|
+
* The type is inferred as T | undefined.
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* validate(data, {
|
|
29
|
+
* required_field: String, // string (required)
|
|
30
|
+
* optional_field: Optional(String), // string | undefined
|
|
31
|
+
* optional_object: Optional({ // { id: string } | undefined
|
|
32
|
+
* id: String
|
|
33
|
+
* }),
|
|
34
|
+
* optional_array: Optional([String]) // string[] | undefined
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
declare function Optional<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & OptionalMarker;
|
|
39
|
+
/**
|
|
40
|
+
* Marks a field as nullable.
|
|
41
|
+
* Nullable fields pass validation even if they are null.
|
|
42
|
+
* The type is inferred as T | null.
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* validate(data, {
|
|
46
|
+
* required_field: String, // string (required)
|
|
47
|
+
* nullable_field: Nullable(String), // string | null
|
|
48
|
+
* nullable_object: Nullable({ // { id: string } | null
|
|
49
|
+
* id: String
|
|
50
|
+
* }),
|
|
51
|
+
* nullable_array: Nullable([String]) // string[] | null
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
declare function Nullable<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & NullableMarker;
|
|
56
|
+
declare class RuntimeTypeError extends Error {
|
|
57
|
+
constructor(key: string, requiredType: string, actualType: string, actualValue: any, message?: string);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Asserts the type of target according to the expression schema.
|
|
61
|
+
* The expression should be represented using primitive type constructors.
|
|
62
|
+
* Supports nested types and array element type validation.
|
|
63
|
+
*
|
|
64
|
+
* Fields not declared in the expression but present in target are ignored.
|
|
65
|
+
*
|
|
66
|
+
* Fields declared in the expression do not allow undefined or null by default.
|
|
67
|
+
* Wrap with Optional() to allow undefined.
|
|
68
|
+
* Wrap with Nullable() to allow null.
|
|
69
|
+
*
|
|
70
|
+
* @param target - The value to validate
|
|
71
|
+
* @param expression - The schema expression to validate against
|
|
72
|
+
* @throws {RuntimeTypeError} When type mismatch occurs
|
|
73
|
+
* @throws {RuntimeTypeError} When value is undefined or null (unless optional/nullable)
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const data: unknown = getData();
|
|
77
|
+
*
|
|
78
|
+
* validate(data, {
|
|
79
|
+
* "a": Boolean,
|
|
80
|
+
* "b": {
|
|
81
|
+
* "c": Number,
|
|
82
|
+
* "d": Optional(String), // string | undefined
|
|
83
|
+
* "e": Nullable(String) // string | null
|
|
84
|
+
* },
|
|
85
|
+
* "items": [{
|
|
86
|
+
* "name": String,
|
|
87
|
+
* "value": Number
|
|
88
|
+
* }]
|
|
89
|
+
* });
|
|
90
|
+
*
|
|
91
|
+
* // From this point, data is type-asserted
|
|
92
|
+
* data.a // boolean
|
|
93
|
+
* data.b.c // number
|
|
94
|
+
* data.b.d // string | undefined
|
|
95
|
+
* data.b.e // string | null
|
|
96
|
+
* data.items[0].name // string
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function validate<T extends Expression>(target: any, expression: T, path?: string): asserts target is InferType<T>;
|
|
100
|
+
|
|
101
|
+
export { Nullable, Optional, RuntimeTypeError, validate };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
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
|
+
Nullable: () => Nullable,
|
|
24
|
+
Optional: () => Optional,
|
|
25
|
+
RuntimeTypeError: () => RuntimeTypeError,
|
|
26
|
+
validate: () => validate
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
function Optional(ctor) {
|
|
30
|
+
return {
|
|
31
|
+
...ctor,
|
|
32
|
+
__optional: true,
|
|
33
|
+
__type: ctor
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function Nullable(ctor) {
|
|
37
|
+
return {
|
|
38
|
+
...ctor,
|
|
39
|
+
__nullable: true,
|
|
40
|
+
__type: ctor
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
var RuntimeTypeError = class extends Error {
|
|
44
|
+
constructor(key, requiredType, actualType, actualValue, message) {
|
|
45
|
+
if (message) message += ": ";
|
|
46
|
+
super(`${message || ""}${key} must be ${requiredType}, but got ${actualType}. Actual value: ${actualValue}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function getTypeName(value) {
|
|
50
|
+
if (value === null) return "null";
|
|
51
|
+
if (value === void 0) return "undefined";
|
|
52
|
+
if (Array.isArray(value)) return "Array";
|
|
53
|
+
if (typeof value === "number" && Number.isNaN(value)) return "NaN";
|
|
54
|
+
if (typeof value === "object") return "Object";
|
|
55
|
+
const type = typeof value;
|
|
56
|
+
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
57
|
+
}
|
|
58
|
+
var TYPE_VALIDATORS = {
|
|
59
|
+
Number: (value) => typeof value === "number" && !Number.isNaN(value),
|
|
60
|
+
String: (value) => typeof value === "string",
|
|
61
|
+
Boolean: (value) => typeof value === "boolean",
|
|
62
|
+
Array: (value) => Array.isArray(value),
|
|
63
|
+
Object: (value) => typeof value === "object" && value !== null && !Array.isArray(value)
|
|
64
|
+
};
|
|
65
|
+
function isValidateExpression(ctor) {
|
|
66
|
+
return typeof ctor === "object" && !Array.isArray(ctor);
|
|
67
|
+
}
|
|
68
|
+
function isArraySchema(ctor) {
|
|
69
|
+
return Array.isArray(ctor) && ctor.length === 1;
|
|
70
|
+
}
|
|
71
|
+
function isOptional(ctor) {
|
|
72
|
+
return ctor.__optional === true;
|
|
73
|
+
}
|
|
74
|
+
function isNullable(ctor) {
|
|
75
|
+
return ctor.__nullable === true;
|
|
76
|
+
}
|
|
77
|
+
function isBothOptionalAndNullable(ctor) {
|
|
78
|
+
return ctor.__optional === true && ctor.__nullable === true;
|
|
79
|
+
}
|
|
80
|
+
function unwrapOptionalNullable(ctor) {
|
|
81
|
+
if (!ctor || typeof ctor !== "object") {
|
|
82
|
+
return ctor;
|
|
83
|
+
}
|
|
84
|
+
if (Array.isArray(ctor)) {
|
|
85
|
+
return ctor;
|
|
86
|
+
}
|
|
87
|
+
if (ctor.__type) {
|
|
88
|
+
return ctor.__type;
|
|
89
|
+
}
|
|
90
|
+
const unwrapped = {};
|
|
91
|
+
for (const key in ctor) {
|
|
92
|
+
if (key !== "__optional" && key !== "__nullable" && key !== "__type") {
|
|
93
|
+
unwrapped[key] = ctor[key];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (Object.keys(unwrapped).length === 0 && (ctor.__optional || ctor.__nullable)) {
|
|
97
|
+
return ctor;
|
|
98
|
+
}
|
|
99
|
+
return unwrapped;
|
|
100
|
+
}
|
|
101
|
+
function assertType(key, expectedType, value, isValid) {
|
|
102
|
+
if (!isValid) {
|
|
103
|
+
throw new RuntimeTypeError(key, expectedType, getTypeName(value), value);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function validate(target, expression, path = "") {
|
|
107
|
+
for (const [key, ctor] of Object.entries(expression)) {
|
|
108
|
+
const value = target[key];
|
|
109
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
110
|
+
if (isBothOptionalAndNullable(ctor)) {
|
|
111
|
+
if (value === void 0 || value === null) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
} else if (value === void 0 && isOptional(ctor)) {
|
|
115
|
+
continue;
|
|
116
|
+
} else if (value === null && isNullable(ctor)) {
|
|
117
|
+
continue;
|
|
118
|
+
} else {
|
|
119
|
+
assertType(currentPath, "not undefined or null", value, value !== void 0 && value !== null);
|
|
120
|
+
}
|
|
121
|
+
const unwrappedCtor = unwrapOptionalNullable(ctor);
|
|
122
|
+
if (isArraySchema(unwrappedCtor)) {
|
|
123
|
+
assertType(currentPath, "Array", value, Array.isArray(value));
|
|
124
|
+
const elementSchema = unwrappedCtor[0];
|
|
125
|
+
value.forEach((item, index) => {
|
|
126
|
+
const arrayPath = `${currentPath}[${index}]`;
|
|
127
|
+
if (isValidateExpression(elementSchema)) {
|
|
128
|
+
const objectValidator = TYPE_VALIDATORS["Object"];
|
|
129
|
+
assertType(arrayPath, "Object", item, objectValidator?.(item) ?? false);
|
|
130
|
+
validate(item, elementSchema, arrayPath);
|
|
131
|
+
} else {
|
|
132
|
+
const validator = TYPE_VALIDATORS[elementSchema.name];
|
|
133
|
+
if (!validator) {
|
|
134
|
+
throw new Error("Invalid array element expression.");
|
|
135
|
+
}
|
|
136
|
+
assertType(arrayPath, elementSchema.name, item, validator(item));
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (typeof unwrappedCtor === "function") {
|
|
142
|
+
const validator = TYPE_VALIDATORS[unwrappedCtor.name];
|
|
143
|
+
if (!validator) {
|
|
144
|
+
throw new Error("Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.");
|
|
145
|
+
}
|
|
146
|
+
assertType(currentPath, unwrappedCtor.name, value, validator(value));
|
|
147
|
+
} else if (isValidateExpression(unwrappedCtor)) {
|
|
148
|
+
const objectValidator = TYPE_VALIDATORS["Object"];
|
|
149
|
+
if (!objectValidator) {
|
|
150
|
+
throw new Error("Object validator not found");
|
|
151
|
+
}
|
|
152
|
+
assertType(currentPath, "Object", value, objectValidator(value));
|
|
153
|
+
validate(value, unwrappedCtor, currentPath);
|
|
154
|
+
} else {
|
|
155
|
+
throw new Error("Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
160
|
+
0 && (module.exports = {
|
|
161
|
+
Nullable,
|
|
162
|
+
Optional,
|
|
163
|
+
RuntimeTypeError,
|
|
164
|
+
validate
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["type OptionalMarker = { __optional: true };\ntype NullableMarker = { __nullable: true };\n\ntype ArraySchema = [PrimitiveType | Expression];\n\ntype Expression = {\n [key: string | number]: PrimitiveType | (PrimitiveType & OptionalMarker) | (PrimitiveType & NullableMarker) | (PrimitiveType & OptionalMarker & NullableMarker) | Expression | (Expression & OptionalMarker) | (Expression & NullableMarker) | (Expression & OptionalMarker & NullableMarker) | ArraySchema | (ArraySchema & OptionalMarker) | (ArraySchema & NullableMarker) | (ArraySchema & OptionalMarker & NullableMarker)\n}\n\ntype PrimitiveType = NumberConstructor | StringConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;\n\ntype InferPrimitiveType<T> =\n T extends NumberConstructor ? number :\n T extends StringConstructor ? string :\n T extends BooleanConstructor ? boolean :\n T extends ArrayConstructor ? any[] :\n T extends ObjectConstructor ? object :\n never;\n\ntype InferType<T> =\n T extends PrimitiveType & OptionalMarker & NullableMarker\n ? InferPrimitiveType<T> | undefined | null\n : T extends PrimitiveType & OptionalMarker\n ? InferPrimitiveType<T> | undefined\n : T extends PrimitiveType & NullableMarker\n ? InferPrimitiveType<T> | null\n : T extends PrimitiveType\n ? InferPrimitiveType<T>\n : T extends Expression & OptionalMarker & NullableMarker\n ? { [K in keyof T]: InferType<T[K]> } | undefined | null\n : T extends Expression & OptionalMarker\n ? { [K in keyof T]: InferType<T[K]> } | undefined\n : T extends Expression & NullableMarker\n ? { [K in keyof T]: InferType<T[K]> } | null\n : T extends ArraySchema & OptionalMarker & NullableMarker\n ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined | null\n : T extends ArraySchema & OptionalMarker\n ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined\n : T extends ArraySchema & NullableMarker\n ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | null\n : T extends [infer U]\n ? U extends Expression\n ? InferType<U>[]\n : U extends PrimitiveType\n ? InferPrimitiveType<U>[]\n : never\n : T extends Expression\n ? { [K in keyof T]: InferType<T[K]> }\n : never;\n\n/**\n * Marks a field as optional.\n * Optional fields pass validation even if they are undefined.\n * The type is inferred as T | undefined.\n * @example\n * ```ts\n * validate(data, {\n * required_field: String, // string (required)\n * optional_field: Optional(String), // string | undefined\n * optional_object: Optional({ // { id: string } | undefined\n * id: String\n * }),\n * optional_array: Optional([String]) // string[] | undefined\n * });\n * ```\n */\nexport function Optional<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & OptionalMarker {\n return {\n ...ctor as any,\n __optional: true,\n __type: ctor\n } as T & OptionalMarker;\n}\n\n/**\n * Marks a field as nullable.\n * Nullable fields pass validation even if they are null.\n * The type is inferred as T | null.\n * @example\n * ```ts\n * validate(data, {\n * required_field: String, // string (required)\n * nullable_field: Nullable(String), // string | null\n * nullable_object: Nullable({ // { id: string } | null\n * id: String\n * }),\n * nullable_array: Nullable([String]) // string[] | null\n * });\n * ```\n */\nexport function Nullable<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & NullableMarker {\n return {\n ...ctor as any,\n __nullable: true,\n __type: ctor\n } as T & NullableMarker;\n}\n\nexport class RuntimeTypeError extends Error {\n constructor(\n key: string,\n requiredType: string,\n actualType: string,\n actualValue: any,\n message?: string\n ) {\n if (message) message += \": \"\n super(`${message || \"\"}${key} must be ${requiredType}, but got ${actualType}. Actual value: ${actualValue}`);\n }\n}\n\nfunction getTypeName(value: any): string {\n if (value === null) return 'null';\n if (value === undefined) return 'undefined';\n if (Array.isArray(value)) return 'Array';\n if (typeof value === 'number' && Number.isNaN(value)) return 'NaN';\n if (typeof value === 'object') return 'Object';\n\n const type = typeof value;\n return type.charAt(0).toUpperCase() + type.slice(1);\n}\n\nconst TYPE_VALIDATORS: Record<string, (value: any) => boolean> = {\n Number: (value) => typeof value === 'number' && !Number.isNaN(value),\n String: (value) => typeof value === 'string',\n Boolean: (value) => typeof value === 'boolean',\n Array: (value) => Array.isArray(value),\n Object: (value) => typeof value === 'object' && value !== null && !Array.isArray(value)\n};\n\nfunction isValidateExpression(ctor: any): ctor is Expression {\n return typeof ctor === 'object' && !Array.isArray(ctor);\n}\n\nfunction isArraySchema(ctor: any): ctor is [PrimitiveType | Expression] {\n return Array.isArray(ctor) && ctor.length === 1;\n}\n\nfunction isOptional(ctor: any): boolean {\n return ctor.__optional === true;\n}\n\nfunction isNullable(ctor: any): boolean {\n return ctor.__nullable === true;\n}\n\nfunction isBothOptionalAndNullable(ctor: any): boolean {\n return ctor.__optional === true && ctor.__nullable === true;\n}\n\nfunction unwrapOptionalNullable(ctor: any): any {\n if (!ctor || typeof ctor !== 'object') {\n return ctor;\n }\n \n if (Array.isArray(ctor)) {\n return ctor;\n }\n \n if (ctor.__type) {\n return ctor.__type;\n }\n \n const unwrapped: any = {};\n for (const key in ctor) {\n if (key !== '__optional' && key !== '__nullable' && key !== '__type') {\n unwrapped[key] = ctor[key];\n }\n }\n \n if (Object.keys(unwrapped).length === 0 && (ctor.__optional || ctor.__nullable)) {\n return ctor;\n }\n \n return unwrapped;\n}\n\nfunction assertType(key: string, expectedType: string, value: any, isValid: boolean): void {\n if (!isValid) {\n throw new RuntimeTypeError(key, expectedType, getTypeName(value), value);\n }\n}\n\n/**\n * Asserts the type of target according to the expression schema.\n * The expression should be represented using primitive type constructors.\n * Supports nested types and array element type validation.\n *\n * Fields not declared in the expression but present in target are ignored.\n *\n * Fields declared in the expression do not allow undefined or null by default.\n * Wrap with Optional() to allow undefined.\n * Wrap with Nullable() to allow null.\n *\n * @param target - The value to validate\n * @param expression - The schema expression to validate against\n * @throws {RuntimeTypeError} When type mismatch occurs\n * @throws {RuntimeTypeError} When value is undefined or null (unless optional/nullable)\n * @example\n * ```ts\n * const data: unknown = getData();\n *\n * validate(data, {\n * \"a\": Boolean,\n * \"b\": {\n * \"c\": Number,\n * \"d\": Optional(String), // string | undefined\n * \"e\": Nullable(String) // string | null\n * },\n * \"items\": [{\n * \"name\": String,\n * \"value\": Number\n * }]\n * });\n *\n * // From this point, data is type-asserted\n * data.a // boolean\n * data.b.c // number\n * data.b.d // string | undefined\n * data.b.e // string | null\n * data.items[0].name // string\n * ```\n */\nexport function validate<T extends Expression>(\n target: any,\n expression: T,\n path: string = \"\"\n): asserts target is InferType<T> {\n for (const [key, ctor] of Object.entries(expression)) {\n const value = target[key];\n const currentPath = path ? `${path}.${key}` : key;\n\n if (isBothOptionalAndNullable(ctor)) {\n if (value === undefined || value === null) {\n continue\n }\n } else if (value === undefined && isOptional(ctor)) {\n continue;\n } else if (value === null && isNullable(ctor)) {\n continue;\n } else {\n assertType(currentPath, \"not undefined or null\", value, value !== undefined && value !== null);\n }\n\n const unwrappedCtor = unwrapOptionalNullable(ctor);\n\n if (isArraySchema(unwrappedCtor)) {\n assertType(currentPath, \"Array\", value, Array.isArray(value));\n const elementSchema = unwrappedCtor[0];\n\n (value as any[]).forEach((item, index) => {\n const arrayPath = `${currentPath}[${index}]`;\n if (isValidateExpression(elementSchema)) {\n const objectValidator = TYPE_VALIDATORS['Object'];\n assertType(arrayPath, \"Object\", item, objectValidator?.(item) ?? false);\n validate(item, elementSchema, arrayPath);\n } else {\n const validator = TYPE_VALIDATORS[elementSchema.name];\n if (!validator) {\n throw new Error(\"Invalid array element expression.\");\n }\n assertType(arrayPath, elementSchema.name, item, validator(item));\n }\n });\n continue;\n }\n\n if (typeof unwrappedCtor === 'function') {\n const validator = TYPE_VALIDATORS[unwrappedCtor.name];\n if (!validator) {\n throw new Error(\"Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.\");\n }\n assertType(currentPath, unwrappedCtor.name, value, validator(value));\n } else if (isValidateExpression(unwrappedCtor)) {\n const objectValidator = TYPE_VALIDATORS['Object'];\n if (!objectValidator) {\n throw new Error(\"Object validator not found\");\n }\n assertType(currentPath, \"Object\", value, objectValidator(value));\n validate(value, unwrappedCtor, currentPath);\n } else {\n throw new Error(\"Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.\");\n }\n }\n}"],"mappings":"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","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function Optional(ctor) {
|
|
3
|
+
return {
|
|
4
|
+
...ctor,
|
|
5
|
+
__optional: true,
|
|
6
|
+
__type: ctor
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function Nullable(ctor) {
|
|
10
|
+
return {
|
|
11
|
+
...ctor,
|
|
12
|
+
__nullable: true,
|
|
13
|
+
__type: ctor
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
var RuntimeTypeError = class extends Error {
|
|
17
|
+
constructor(key, requiredType, actualType, actualValue, message) {
|
|
18
|
+
if (message) message += ": ";
|
|
19
|
+
super(`${message || ""}${key} must be ${requiredType}, but got ${actualType}. Actual value: ${actualValue}`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function getTypeName(value) {
|
|
23
|
+
if (value === null) return "null";
|
|
24
|
+
if (value === void 0) return "undefined";
|
|
25
|
+
if (Array.isArray(value)) return "Array";
|
|
26
|
+
if (typeof value === "number" && Number.isNaN(value)) return "NaN";
|
|
27
|
+
if (typeof value === "object") return "Object";
|
|
28
|
+
const type = typeof value;
|
|
29
|
+
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
30
|
+
}
|
|
31
|
+
var TYPE_VALIDATORS = {
|
|
32
|
+
Number: (value) => typeof value === "number" && !Number.isNaN(value),
|
|
33
|
+
String: (value) => typeof value === "string",
|
|
34
|
+
Boolean: (value) => typeof value === "boolean",
|
|
35
|
+
Array: (value) => Array.isArray(value),
|
|
36
|
+
Object: (value) => typeof value === "object" && value !== null && !Array.isArray(value)
|
|
37
|
+
};
|
|
38
|
+
function isValidateExpression(ctor) {
|
|
39
|
+
return typeof ctor === "object" && !Array.isArray(ctor);
|
|
40
|
+
}
|
|
41
|
+
function isArraySchema(ctor) {
|
|
42
|
+
return Array.isArray(ctor) && ctor.length === 1;
|
|
43
|
+
}
|
|
44
|
+
function isOptional(ctor) {
|
|
45
|
+
return ctor.__optional === true;
|
|
46
|
+
}
|
|
47
|
+
function isNullable(ctor) {
|
|
48
|
+
return ctor.__nullable === true;
|
|
49
|
+
}
|
|
50
|
+
function isBothOptionalAndNullable(ctor) {
|
|
51
|
+
return ctor.__optional === true && ctor.__nullable === true;
|
|
52
|
+
}
|
|
53
|
+
function unwrapOptionalNullable(ctor) {
|
|
54
|
+
if (!ctor || typeof ctor !== "object") {
|
|
55
|
+
return ctor;
|
|
56
|
+
}
|
|
57
|
+
if (Array.isArray(ctor)) {
|
|
58
|
+
return ctor;
|
|
59
|
+
}
|
|
60
|
+
if (ctor.__type) {
|
|
61
|
+
return ctor.__type;
|
|
62
|
+
}
|
|
63
|
+
const unwrapped = {};
|
|
64
|
+
for (const key in ctor) {
|
|
65
|
+
if (key !== "__optional" && key !== "__nullable" && key !== "__type") {
|
|
66
|
+
unwrapped[key] = ctor[key];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (Object.keys(unwrapped).length === 0 && (ctor.__optional || ctor.__nullable)) {
|
|
70
|
+
return ctor;
|
|
71
|
+
}
|
|
72
|
+
return unwrapped;
|
|
73
|
+
}
|
|
74
|
+
function assertType(key, expectedType, value, isValid) {
|
|
75
|
+
if (!isValid) {
|
|
76
|
+
throw new RuntimeTypeError(key, expectedType, getTypeName(value), value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function validate(target, expression, path = "") {
|
|
80
|
+
for (const [key, ctor] of Object.entries(expression)) {
|
|
81
|
+
const value = target[key];
|
|
82
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
83
|
+
if (isBothOptionalAndNullable(ctor)) {
|
|
84
|
+
if (value === void 0 || value === null) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
} else if (value === void 0 && isOptional(ctor)) {
|
|
88
|
+
continue;
|
|
89
|
+
} else if (value === null && isNullable(ctor)) {
|
|
90
|
+
continue;
|
|
91
|
+
} else {
|
|
92
|
+
assertType(currentPath, "not undefined or null", value, value !== void 0 && value !== null);
|
|
93
|
+
}
|
|
94
|
+
const unwrappedCtor = unwrapOptionalNullable(ctor);
|
|
95
|
+
if (isArraySchema(unwrappedCtor)) {
|
|
96
|
+
assertType(currentPath, "Array", value, Array.isArray(value));
|
|
97
|
+
const elementSchema = unwrappedCtor[0];
|
|
98
|
+
value.forEach((item, index) => {
|
|
99
|
+
const arrayPath = `${currentPath}[${index}]`;
|
|
100
|
+
if (isValidateExpression(elementSchema)) {
|
|
101
|
+
const objectValidator = TYPE_VALIDATORS["Object"];
|
|
102
|
+
assertType(arrayPath, "Object", item, objectValidator?.(item) ?? false);
|
|
103
|
+
validate(item, elementSchema, arrayPath);
|
|
104
|
+
} else {
|
|
105
|
+
const validator = TYPE_VALIDATORS[elementSchema.name];
|
|
106
|
+
if (!validator) {
|
|
107
|
+
throw new Error("Invalid array element expression.");
|
|
108
|
+
}
|
|
109
|
+
assertType(arrayPath, elementSchema.name, item, validator(item));
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (typeof unwrappedCtor === "function") {
|
|
115
|
+
const validator = TYPE_VALIDATORS[unwrappedCtor.name];
|
|
116
|
+
if (!validator) {
|
|
117
|
+
throw new Error("Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.");
|
|
118
|
+
}
|
|
119
|
+
assertType(currentPath, unwrappedCtor.name, value, validator(value));
|
|
120
|
+
} else if (isValidateExpression(unwrappedCtor)) {
|
|
121
|
+
const objectValidator = TYPE_VALIDATORS["Object"];
|
|
122
|
+
if (!objectValidator) {
|
|
123
|
+
throw new Error("Object validator not found");
|
|
124
|
+
}
|
|
125
|
+
assertType(currentPath, "Object", value, objectValidator(value));
|
|
126
|
+
validate(value, unwrappedCtor, currentPath);
|
|
127
|
+
} else {
|
|
128
|
+
throw new Error("Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export {
|
|
133
|
+
Nullable,
|
|
134
|
+
Optional,
|
|
135
|
+
RuntimeTypeError,
|
|
136
|
+
validate
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["type OptionalMarker = { __optional: true };\ntype NullableMarker = { __nullable: true };\n\ntype ArraySchema = [PrimitiveType | Expression];\n\ntype Expression = {\n [key: string | number]: PrimitiveType | (PrimitiveType & OptionalMarker) | (PrimitiveType & NullableMarker) | (PrimitiveType & OptionalMarker & NullableMarker) | Expression | (Expression & OptionalMarker) | (Expression & NullableMarker) | (Expression & OptionalMarker & NullableMarker) | ArraySchema | (ArraySchema & OptionalMarker) | (ArraySchema & NullableMarker) | (ArraySchema & OptionalMarker & NullableMarker)\n}\n\ntype PrimitiveType = NumberConstructor | StringConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;\n\ntype InferPrimitiveType<T> =\n T extends NumberConstructor ? number :\n T extends StringConstructor ? string :\n T extends BooleanConstructor ? boolean :\n T extends ArrayConstructor ? any[] :\n T extends ObjectConstructor ? object :\n never;\n\ntype InferType<T> =\n T extends PrimitiveType & OptionalMarker & NullableMarker\n ? InferPrimitiveType<T> | undefined | null\n : T extends PrimitiveType & OptionalMarker\n ? InferPrimitiveType<T> | undefined\n : T extends PrimitiveType & NullableMarker\n ? InferPrimitiveType<T> | null\n : T extends PrimitiveType\n ? InferPrimitiveType<T>\n : T extends Expression & OptionalMarker & NullableMarker\n ? { [K in keyof T]: InferType<T[K]> } | undefined | null\n : T extends Expression & OptionalMarker\n ? { [K in keyof T]: InferType<T[K]> } | undefined\n : T extends Expression & NullableMarker\n ? { [K in keyof T]: InferType<T[K]> } | null\n : T extends ArraySchema & OptionalMarker & NullableMarker\n ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined | null\n : T extends ArraySchema & OptionalMarker\n ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | undefined\n : T extends ArraySchema & NullableMarker\n ? (T extends [infer U] ? (U extends Expression ? InferType<U>[] : U extends PrimitiveType ? InferPrimitiveType<U>[] : never) : never) | null\n : T extends [infer U]\n ? U extends Expression\n ? InferType<U>[]\n : U extends PrimitiveType\n ? InferPrimitiveType<U>[]\n : never\n : T extends Expression\n ? { [K in keyof T]: InferType<T[K]> }\n : never;\n\n/**\n * Marks a field as optional.\n * Optional fields pass validation even if they are undefined.\n * The type is inferred as T | undefined.\n * @example\n * ```ts\n * validate(data, {\n * required_field: String, // string (required)\n * optional_field: Optional(String), // string | undefined\n * optional_object: Optional({ // { id: string } | undefined\n * id: String\n * }),\n * optional_array: Optional([String]) // string[] | undefined\n * });\n * ```\n */\nexport function Optional<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & OptionalMarker {\n return {\n ...ctor as any,\n __optional: true,\n __type: ctor\n } as T & OptionalMarker;\n}\n\n/**\n * Marks a field as nullable.\n * Nullable fields pass validation even if they are null.\n * The type is inferred as T | null.\n * @example\n * ```ts\n * validate(data, {\n * required_field: String, // string (required)\n * nullable_field: Nullable(String), // string | null\n * nullable_object: Nullable({ // { id: string } | null\n * id: String\n * }),\n * nullable_array: Nullable([String]) // string[] | null\n * });\n * ```\n */\nexport function Nullable<T extends PrimitiveType | Expression | ArraySchema>(ctor: T): T & NullableMarker {\n return {\n ...ctor as any,\n __nullable: true,\n __type: ctor\n } as T & NullableMarker;\n}\n\nexport class RuntimeTypeError extends Error {\n constructor(\n key: string,\n requiredType: string,\n actualType: string,\n actualValue: any,\n message?: string\n ) {\n if (message) message += \": \"\n super(`${message || \"\"}${key} must be ${requiredType}, but got ${actualType}. Actual value: ${actualValue}`);\n }\n}\n\nfunction getTypeName(value: any): string {\n if (value === null) return 'null';\n if (value === undefined) return 'undefined';\n if (Array.isArray(value)) return 'Array';\n if (typeof value === 'number' && Number.isNaN(value)) return 'NaN';\n if (typeof value === 'object') return 'Object';\n\n const type = typeof value;\n return type.charAt(0).toUpperCase() + type.slice(1);\n}\n\nconst TYPE_VALIDATORS: Record<string, (value: any) => boolean> = {\n Number: (value) => typeof value === 'number' && !Number.isNaN(value),\n String: (value) => typeof value === 'string',\n Boolean: (value) => typeof value === 'boolean',\n Array: (value) => Array.isArray(value),\n Object: (value) => typeof value === 'object' && value !== null && !Array.isArray(value)\n};\n\nfunction isValidateExpression(ctor: any): ctor is Expression {\n return typeof ctor === 'object' && !Array.isArray(ctor);\n}\n\nfunction isArraySchema(ctor: any): ctor is [PrimitiveType | Expression] {\n return Array.isArray(ctor) && ctor.length === 1;\n}\n\nfunction isOptional(ctor: any): boolean {\n return ctor.__optional === true;\n}\n\nfunction isNullable(ctor: any): boolean {\n return ctor.__nullable === true;\n}\n\nfunction isBothOptionalAndNullable(ctor: any): boolean {\n return ctor.__optional === true && ctor.__nullable === true;\n}\n\nfunction unwrapOptionalNullable(ctor: any): any {\n if (!ctor || typeof ctor !== 'object') {\n return ctor;\n }\n \n if (Array.isArray(ctor)) {\n return ctor;\n }\n \n if (ctor.__type) {\n return ctor.__type;\n }\n \n const unwrapped: any = {};\n for (const key in ctor) {\n if (key !== '__optional' && key !== '__nullable' && key !== '__type') {\n unwrapped[key] = ctor[key];\n }\n }\n \n if (Object.keys(unwrapped).length === 0 && (ctor.__optional || ctor.__nullable)) {\n return ctor;\n }\n \n return unwrapped;\n}\n\nfunction assertType(key: string, expectedType: string, value: any, isValid: boolean): void {\n if (!isValid) {\n throw new RuntimeTypeError(key, expectedType, getTypeName(value), value);\n }\n}\n\n/**\n * Asserts the type of target according to the expression schema.\n * The expression should be represented using primitive type constructors.\n * Supports nested types and array element type validation.\n *\n * Fields not declared in the expression but present in target are ignored.\n *\n * Fields declared in the expression do not allow undefined or null by default.\n * Wrap with Optional() to allow undefined.\n * Wrap with Nullable() to allow null.\n *\n * @param target - The value to validate\n * @param expression - The schema expression to validate against\n * @throws {RuntimeTypeError} When type mismatch occurs\n * @throws {RuntimeTypeError} When value is undefined or null (unless optional/nullable)\n * @example\n * ```ts\n * const data: unknown = getData();\n *\n * validate(data, {\n * \"a\": Boolean,\n * \"b\": {\n * \"c\": Number,\n * \"d\": Optional(String), // string | undefined\n * \"e\": Nullable(String) // string | null\n * },\n * \"items\": [{\n * \"name\": String,\n * \"value\": Number\n * }]\n * });\n *\n * // From this point, data is type-asserted\n * data.a // boolean\n * data.b.c // number\n * data.b.d // string | undefined\n * data.b.e // string | null\n * data.items[0].name // string\n * ```\n */\nexport function validate<T extends Expression>(\n target: any,\n expression: T,\n path: string = \"\"\n): asserts target is InferType<T> {\n for (const [key, ctor] of Object.entries(expression)) {\n const value = target[key];\n const currentPath = path ? `${path}.${key}` : key;\n\n if (isBothOptionalAndNullable(ctor)) {\n if (value === undefined || value === null) {\n continue\n }\n } else if (value === undefined && isOptional(ctor)) {\n continue;\n } else if (value === null && isNullable(ctor)) {\n continue;\n } else {\n assertType(currentPath, \"not undefined or null\", value, value !== undefined && value !== null);\n }\n\n const unwrappedCtor = unwrapOptionalNullable(ctor);\n\n if (isArraySchema(unwrappedCtor)) {\n assertType(currentPath, \"Array\", value, Array.isArray(value));\n const elementSchema = unwrappedCtor[0];\n\n (value as any[]).forEach((item, index) => {\n const arrayPath = `${currentPath}[${index}]`;\n if (isValidateExpression(elementSchema)) {\n const objectValidator = TYPE_VALIDATORS['Object'];\n assertType(arrayPath, \"Object\", item, objectValidator?.(item) ?? false);\n validate(item, elementSchema, arrayPath);\n } else {\n const validator = TYPE_VALIDATORS[elementSchema.name];\n if (!validator) {\n throw new Error(\"Invalid array element expression.\");\n }\n assertType(arrayPath, elementSchema.name, item, validator(item));\n }\n });\n continue;\n }\n\n if (typeof unwrappedCtor === 'function') {\n const validator = TYPE_VALIDATORS[unwrappedCtor.name];\n if (!validator) {\n throw new Error(\"Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.\");\n }\n assertType(currentPath, unwrappedCtor.name, value, validator(value));\n } else if (isValidateExpression(unwrappedCtor)) {\n const objectValidator = TYPE_VALIDATORS['Object'];\n if (!objectValidator) {\n throw new Error(\"Object validator not found\");\n }\n assertType(currentPath, \"Object\", value, objectValidator(value));\n validate(value, unwrappedCtor, currentPath);\n } else {\n throw new Error(\"Invalid expression. Use 'Number' or 'String' or 'Boolean' or 'Array' or 'Object'.\");\n }\n }\n}"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "valdex",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Runtime type validation with TypeScript type inference",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"prepublishOnly": "npm run build",
|
|
26
|
+
"test": "tsx test.ts"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"typescript",
|
|
30
|
+
"validation",
|
|
31
|
+
"runtime",
|
|
32
|
+
"type-inference",
|
|
33
|
+
"schema",
|
|
34
|
+
"validator"
|
|
35
|
+
],
|
|
36
|
+
"author": "",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"tsup": "^8.3.5",
|
|
40
|
+
"typescript": "^5.7.2",
|
|
41
|
+
"tsx": "^4.19.2"
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/asheswook/valdex.git"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/asheswook/valdex/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/asheswook/valdex#readme"
|
|
51
|
+
}
|