koatty_validation 1.4.0 → 1.6.1
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/CHANGELOG.md +16 -0
- package/README.md +106 -3
- package/dist/README.md +106 -3
- package/dist/index.d.ts +112 -67
- package/dist/index.js +1336 -1228
- package/dist/index.mjs +1336 -1230
- package/dist/package.json +2 -2
- package/examples/validated-async-sync-example.ts +213 -0
- package/package.json +2 -2
- package/.vscode/launch.json +0 -81
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koatty_validation",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Validation Util for Koatty and ThinkORM.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"koatty_container": "^1.x.x",
|
|
82
82
|
"koatty_lib": "^1.x.x",
|
|
83
83
|
"koatty_logger": "^2.x.x",
|
|
84
|
-
"lru-cache": "^11.
|
|
84
|
+
"lru-cache": "^11.2.2"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"koatty_container": "^1.x.x",
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validated Decorator Usage Example - Sync and Async Modes
|
|
3
|
+
* @author richen
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Validated, checkValidated, IsNotEmpty, IsCnName, IsMobile } from '../src/index';
|
|
7
|
+
|
|
8
|
+
// DTO class definition
|
|
9
|
+
class UserDTO {
|
|
10
|
+
@IsNotEmpty({ message: "Name cannot be empty" })
|
|
11
|
+
@IsCnName({ message: "Name must be a valid Chinese name" })
|
|
12
|
+
name: string;
|
|
13
|
+
|
|
14
|
+
@IsMobile({ message: "Invalid phone number format" })
|
|
15
|
+
phone: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Example 1: Async Mode (Default, suitable for framework scenarios)
|
|
20
|
+
*
|
|
21
|
+
* In the Koatty framework, controller method parameters are obtained asynchronously through requests.
|
|
22
|
+
* When using async mode, the @Validated() decorator saves validation metadata,
|
|
23
|
+
* and the framework's IOC container performs validation after asynchronously retrieving parameters.
|
|
24
|
+
*/
|
|
25
|
+
class AsyncController {
|
|
26
|
+
/**
|
|
27
|
+
* Async mode - Default behavior
|
|
28
|
+
* Decorator saves metadata to IOCContainer, validation handled by framework
|
|
29
|
+
*/
|
|
30
|
+
@Validated() // Equivalent to @Validated(true)
|
|
31
|
+
async createUser(userData: UserDTO) {
|
|
32
|
+
// Framework will automatically validate userData before calling this method
|
|
33
|
+
return { success: true, data: userData };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Explicitly specify async mode
|
|
38
|
+
*/
|
|
39
|
+
@Validated(true)
|
|
40
|
+
async updateUser(id: number, userData: UserDTO) {
|
|
41
|
+
return { success: true, id, data: userData };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Example 2: Sync Mode (Suitable for non-framework scenarios or when parameters are ready)
|
|
47
|
+
*
|
|
48
|
+
* If parameter values are already prepared (no need for async retrieval), you can use sync mode.
|
|
49
|
+
* Sync mode performs validation immediately when the method is called.
|
|
50
|
+
*/
|
|
51
|
+
class SyncController {
|
|
52
|
+
/**
|
|
53
|
+
* Sync mode - Immediate validation
|
|
54
|
+
* Decorator wraps the original method and performs validation on call
|
|
55
|
+
*/
|
|
56
|
+
@Validated(false)
|
|
57
|
+
async createUser(userData: UserDTO) {
|
|
58
|
+
// Validation completed before method execution
|
|
59
|
+
return { success: true, data: userData };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Sync mode - Multiple parameters
|
|
64
|
+
*/
|
|
65
|
+
@Validated(false)
|
|
66
|
+
async updateUser(id: number, userData: UserDTO) {
|
|
67
|
+
// Only validates class-type parameters (UserDTO), primitive types (number) are not validated
|
|
68
|
+
return { success: true, id, data: userData };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Example 3: Manually using checkValidated function
|
|
74
|
+
*
|
|
75
|
+
* If you need to manually perform validation in framework code, you can directly call the checkValidated function.
|
|
76
|
+
* This is particularly useful in framework interceptors or middleware.
|
|
77
|
+
*/
|
|
78
|
+
async function manualValidationExample() {
|
|
79
|
+
// Prepare parameters
|
|
80
|
+
const userData = {
|
|
81
|
+
name: 'Zhang San',
|
|
82
|
+
phone: '13812345678'
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Get parameter types
|
|
86
|
+
const paramTypes = [UserDTO];
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
// Manually perform validation
|
|
90
|
+
const { validatedArgs, validationTargets } = await checkValidated(
|
|
91
|
+
[userData],
|
|
92
|
+
paramTypes
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
console.log('Validation passed:', validationTargets);
|
|
96
|
+
return validationTargets[0];
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error('Validation failed:', error);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Example 4: Real-world application in Koatty framework
|
|
105
|
+
*
|
|
106
|
+
* This is a typical Koatty controller example demonstrating how to use async validation mode.
|
|
107
|
+
*/
|
|
108
|
+
class KoattyUserController {
|
|
109
|
+
/**
|
|
110
|
+
* User registration endpoint
|
|
111
|
+
*
|
|
112
|
+
* In Koatty framework:
|
|
113
|
+
* 1. Framework receives HTTP request
|
|
114
|
+
* 2. Framework parses request body asynchronously and constructs UserDTO instance
|
|
115
|
+
* 3. Framework detects @Validated() metadata
|
|
116
|
+
* 4. Framework calls checkValidated() to validate parameters
|
|
117
|
+
* 5. Calls register method after validation passes
|
|
118
|
+
*/
|
|
119
|
+
@Validated() // Async mode, handled by framework
|
|
120
|
+
async register(user: UserDTO) {
|
|
121
|
+
// User has been validated at this point
|
|
122
|
+
console.log('Registering user:', user.name, user.phone);
|
|
123
|
+
return {
|
|
124
|
+
code: 0,
|
|
125
|
+
message: 'Registration successful',
|
|
126
|
+
data: { userId: 123 }
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* User update endpoint
|
|
132
|
+
*/
|
|
133
|
+
@Validated()
|
|
134
|
+
async update(id: number, user: UserDTO) {
|
|
135
|
+
console.log('Updating user:', id, user.name);
|
|
136
|
+
return {
|
|
137
|
+
code: 0,
|
|
138
|
+
message: 'Update successful'
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Example 5: Decision guide for choosing sync or async mode
|
|
145
|
+
*/
|
|
146
|
+
class DecisionGuideController {
|
|
147
|
+
/**
|
|
148
|
+
* Scenarios for using async mode:
|
|
149
|
+
*
|
|
150
|
+
* ✅ In Koatty framework controllers (recommended)
|
|
151
|
+
* ✅ Parameter values need to be obtained asynchronously (e.g., parsed from request body)
|
|
152
|
+
* ✅ Validation handled uniformly by framework
|
|
153
|
+
* ✅ Validation needs to be performed after parameters are ready
|
|
154
|
+
*/
|
|
155
|
+
@Validated(true) // Or @Validated()
|
|
156
|
+
async frameworkMethod(dto: UserDTO) {
|
|
157
|
+
return { type: 'async' };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Scenarios for using sync mode:
|
|
162
|
+
*
|
|
163
|
+
* ✅ In unit tests
|
|
164
|
+
* ✅ Parameter values are already prepared
|
|
165
|
+
* ✅ Not running in a framework environment
|
|
166
|
+
* ✅ Need immediate validation and error return
|
|
167
|
+
*/
|
|
168
|
+
@Validated(false)
|
|
169
|
+
async standaloneMethod(dto: UserDTO) {
|
|
170
|
+
return { type: 'sync' };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Run examples
|
|
176
|
+
*/
|
|
177
|
+
async function runExamples() {
|
|
178
|
+
console.log('=== Example 1: Async Mode ===');
|
|
179
|
+
const asyncController = new AsyncController();
|
|
180
|
+
// Note: In actual framework, validation is handled by framework
|
|
181
|
+
// Here for demonstration, directly calling the method
|
|
182
|
+
|
|
183
|
+
console.log('\n=== Example 2: Sync Mode ===');
|
|
184
|
+
const syncController = new SyncController();
|
|
185
|
+
try {
|
|
186
|
+
const validUser = Object.assign(new UserDTO(), {
|
|
187
|
+
name: 'Li Si',
|
|
188
|
+
phone: '13912345678'
|
|
189
|
+
});
|
|
190
|
+
const result = await syncController.createUser(validUser);
|
|
191
|
+
console.log('Sync validation passed:', result);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error('Sync validation failed:', error);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
console.log('\n=== Example 3: Manual Validation ===');
|
|
197
|
+
await manualValidationExample();
|
|
198
|
+
|
|
199
|
+
console.log('\n=== Complete ===');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// If running this file directly
|
|
203
|
+
if (require.main === module) {
|
|
204
|
+
runExamples().catch(console.error);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export {
|
|
208
|
+
AsyncController,
|
|
209
|
+
SyncController,
|
|
210
|
+
KoattyUserController,
|
|
211
|
+
DecisionGuideController,
|
|
212
|
+
manualValidationExample
|
|
213
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koatty_validation",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Validation Util for Koatty and ThinkORM.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"koatty_container": "^1.x.x",
|
|
82
82
|
"koatty_lib": "^1.x.x",
|
|
83
83
|
"koatty_logger": "^2.x.x",
|
|
84
|
-
"lru-cache": "^11.
|
|
84
|
+
"lru-cache": "^11.2.2"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"koatty_container": "^1.x.x",
|
package/.vscode/launch.json
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"configurations": [
|
|
3
|
-
{
|
|
4
|
-
"name": "Launch Koatty Project",
|
|
5
|
-
"type": "node",
|
|
6
|
-
"request": "launch",
|
|
7
|
-
"args": [
|
|
8
|
-
"${workspaceRoot}/src/App.ts"
|
|
9
|
-
],
|
|
10
|
-
"runtimeArgs": [
|
|
11
|
-
"--nolazy",
|
|
12
|
-
"-r",
|
|
13
|
-
"ts-node/register"
|
|
14
|
-
],
|
|
15
|
-
"envFile": "/Users/richen/Workspace/.env",
|
|
16
|
-
"sourceMaps": true,
|
|
17
|
-
"cwd": "${workspaceRoot}",
|
|
18
|
-
"protocol": "inspector",
|
|
19
|
-
"internalConsoleOptions": "neverOpen"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"name": "Launch GoPackage",
|
|
23
|
-
"type": "go",
|
|
24
|
-
"request": "launch",
|
|
25
|
-
"mode": "auto",
|
|
26
|
-
"program": "${workspaceFolder}/main.go",
|
|
27
|
-
"envFile": "/Users/richen/Workspace/.env",
|
|
28
|
-
"args": []
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"name": "Launch Java Project",
|
|
32
|
-
"type": "java",
|
|
33
|
-
"request": "launch",
|
|
34
|
-
"mainClass": "",
|
|
35
|
-
"envFile": "/Users/richen/Workspace/.env"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"name": "Launch Node.js Project",
|
|
39
|
-
"type": "node",
|
|
40
|
-
"request": "launch",
|
|
41
|
-
"mode": "auto",
|
|
42
|
-
"program": "${workspaceFolder}/app.js",
|
|
43
|
-
"envFile": "/Users/richen/Workspace/.env",
|
|
44
|
-
"args": []
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"name": "Launch Typescript Project",
|
|
48
|
-
"type": "node",
|
|
49
|
-
"request": "launch",
|
|
50
|
-
"args": [
|
|
51
|
-
"${workspaceRoot}/src/index.ts"
|
|
52
|
-
],
|
|
53
|
-
"runtimeArgs": [
|
|
54
|
-
"--nolazy",
|
|
55
|
-
"-r",
|
|
56
|
-
"ts-node/register"
|
|
57
|
-
],
|
|
58
|
-
"envFile": "/Users/richen/Workspace/.env",
|
|
59
|
-
"sourceMaps": true,
|
|
60
|
-
"cwd": "${workspaceRoot}",
|
|
61
|
-
"protocol": "inspector",
|
|
62
|
-
"internalConsoleOptions": "neverOpen"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"type": "node",
|
|
66
|
-
"name": "vscode-jest-tests",
|
|
67
|
-
"request": "launch",
|
|
68
|
-
"console": "integratedTerminal",
|
|
69
|
-
"internalConsoleOptions": "neverOpen",
|
|
70
|
-
"disableOptimisticBPs": true,
|
|
71
|
-
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
|
72
|
-
"cwd": "${workspaceFolder}",
|
|
73
|
-
"args": [
|
|
74
|
-
"--config",
|
|
75
|
-
"jest.config.js",
|
|
76
|
-
"--runInBand",
|
|
77
|
-
"--watchAll=false"
|
|
78
|
-
]
|
|
79
|
-
}
|
|
80
|
-
]
|
|
81
|
-
}
|