@orchestr-sh/orchestr 1.4.0 → 1.4.2
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.md +61 -2
- package/dist/Foundation/Http/FormRequest.d.ts +119 -0
- package/dist/Foundation/Http/FormRequest.d.ts.map +1 -0
- package/dist/Foundation/Http/FormRequest.js +180 -0
- package/dist/Foundation/Http/FormRequest.js.map +1 -0
- package/dist/Foundation/Http/ValidationException.d.ts +39 -0
- package/dist/Foundation/Http/ValidationException.d.ts.map +1 -0
- package/dist/Foundation/Http/ValidationException.js +59 -0
- package/dist/Foundation/Http/ValidationException.js.map +1 -0
- package/dist/Foundation/Http/Validator.d.ts +80 -0
- package/dist/Foundation/Http/Validator.d.ts.map +1 -0
- package/dist/Foundation/Http/Validator.js +325 -0
- package/dist/Foundation/Http/Validator.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ Built from the ground up with Laravel's core components:
|
|
|
12
12
|
- **Request/Response** - Elegant HTTP abstractions
|
|
13
13
|
- **Middleware** - Global and route-level middleware pipeline
|
|
14
14
|
- **Controllers** - MVC architecture support
|
|
15
|
+
- **FormRequest** - Laravel-style validation and authorization
|
|
15
16
|
- **Facades** - Static proxy access to services (Route, DB)
|
|
16
17
|
- **Query Builder** - Fluent database query builder with full Laravel API
|
|
17
18
|
- **Ensemble ORM** - ActiveRecord ORM (Laravel's Eloquent equivalent) with relationships (HasOne, HasMany, BelongsTo), eager/lazy loading, soft deletes, and more
|
|
@@ -248,6 +249,64 @@ const authMiddleware = async (req, res, next) => {
|
|
|
248
249
|
Route.get('/profile', handler).addMiddleware(authMiddleware);
|
|
249
250
|
```
|
|
250
251
|
|
|
252
|
+
### FormRequest Validation
|
|
253
|
+
|
|
254
|
+
Laravel-style FormRequest for clean validation and authorization:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { FormRequest, ValidationRules, ValidationException, Route, Request, Response } from 'orchestr';
|
|
258
|
+
|
|
259
|
+
// Create a FormRequest class
|
|
260
|
+
export class StoreUserRequest extends FormRequest {
|
|
261
|
+
// Authorize the request
|
|
262
|
+
protected authorize(): boolean {
|
|
263
|
+
return this.request.header('authorization') !== undefined;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Define validation rules
|
|
267
|
+
protected rules(): ValidationRules {
|
|
268
|
+
return {
|
|
269
|
+
name: 'required|string|min:3|max:255',
|
|
270
|
+
email: 'required|email',
|
|
271
|
+
password: 'required|string|min:8|confirmed',
|
|
272
|
+
age: 'numeric|min:18|max:120',
|
|
273
|
+
role: 'required|in:user,admin,moderator',
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Custom error messages
|
|
278
|
+
protected messages(): Record<string, string> {
|
|
279
|
+
return {
|
|
280
|
+
'name.required': 'Please provide your full name.',
|
|
281
|
+
'email.email': 'Please provide a valid email address.',
|
|
282
|
+
'password.min': 'Password must be at least 8 characters.',
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Use in routes
|
|
288
|
+
Route.post('/users', async (req: Request, res: Response) => {
|
|
289
|
+
try {
|
|
290
|
+
// Validate request (checks authorization AND validation)
|
|
291
|
+
const formRequest = await StoreUserRequest.validate(StoreUserRequest, req, res);
|
|
292
|
+
|
|
293
|
+
// Get validated data only
|
|
294
|
+
const validated = formRequest.validated();
|
|
295
|
+
|
|
296
|
+
// Create user with safe, validated data
|
|
297
|
+
const user = await User.create(validated);
|
|
298
|
+
|
|
299
|
+
return res.status(201).json({ user });
|
|
300
|
+
} catch (error) {
|
|
301
|
+
// Validation/authorization errors already handled
|
|
302
|
+
if (error instanceof ValidationException) return;
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**See [FORM_REQUESTS.md](./FORM_REQUESTS.md) for complete documentation.**
|
|
309
|
+
|
|
251
310
|
### Controllers
|
|
252
311
|
|
|
253
312
|
MVC pattern with base controller and dependency injection:
|
|
@@ -832,12 +891,12 @@ Core components completed and in progress:
|
|
|
832
891
|
- [x] Model Attributes & Casting
|
|
833
892
|
- [x] Model Relationships (HasOne, HasMany, BelongsTo)
|
|
834
893
|
- [x] Eager/Lazy Loading
|
|
894
|
+
- [x] FormRequest Validation & Authorization
|
|
835
895
|
- [ ] Many-to-Many Relationships (BelongsToMany)
|
|
836
896
|
- [ ] Relationship Queries (has, whereHas, withCount)
|
|
837
897
|
- [ ] Polymorphic Relationships
|
|
838
898
|
- [ ] Database Migrations
|
|
839
899
|
- [ ] Database Seeding
|
|
840
|
-
- [ ] Validation System
|
|
841
900
|
- [ ] Authentication & Authorization
|
|
842
901
|
- [ ] Queue System
|
|
843
902
|
- [ ] Events & Listeners
|
|
@@ -870,7 +929,7 @@ Core components completed and in progress:
|
|
|
870
929
|
| Polymorphic Relations | ✅ | 🚧 |
|
|
871
930
|
| Migrations | ✅ | 🚧 |
|
|
872
931
|
| Seeding | ✅ | 🚧 |
|
|
873
|
-
| Validation | ✅ |
|
|
932
|
+
| FormRequest Validation | ✅ | ✅ |
|
|
874
933
|
| Authentication | ✅ | 🚧 |
|
|
875
934
|
| Authorization | ✅ | 🚧 |
|
|
876
935
|
| Events | ✅ | 🚧 |
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Request } from '../../Routing/Request';
|
|
2
|
+
import { Response } from '../../Routing/Response';
|
|
3
|
+
import { ValidationException } from './ValidationException';
|
|
4
|
+
import { Validator, ValidationRules } from './Validator';
|
|
5
|
+
/**
|
|
6
|
+
* FormRequest - Laravel's form request validation
|
|
7
|
+
* Illuminate\Foundation\Http\FormRequest
|
|
8
|
+
*
|
|
9
|
+
* Provides authorization and validation for incoming HTTP requests.
|
|
10
|
+
* Automatically validates data before reaching the controller.
|
|
11
|
+
*/
|
|
12
|
+
export declare abstract class FormRequest {
|
|
13
|
+
protected request: Request;
|
|
14
|
+
protected validator?: Validator;
|
|
15
|
+
protected validatedData?: Record<string, any>;
|
|
16
|
+
constructor(request: Request);
|
|
17
|
+
/**
|
|
18
|
+
* Determine if the user is authorized to make this request
|
|
19
|
+
* Laravel: public function authorize(): bool
|
|
20
|
+
*
|
|
21
|
+
* Override this method to implement authorization logic.
|
|
22
|
+
* Return false to deny access (403 response).
|
|
23
|
+
*
|
|
24
|
+
* @returns {boolean | Promise<boolean>}
|
|
25
|
+
*/
|
|
26
|
+
protected authorize(): boolean | Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Get the validation rules that apply to the request
|
|
29
|
+
* Laravel: public function rules(): array
|
|
30
|
+
*
|
|
31
|
+
* Override this method to define validation rules.
|
|
32
|
+
*
|
|
33
|
+
* @returns {ValidationRules | Promise<ValidationRules>}
|
|
34
|
+
*/
|
|
35
|
+
protected abstract rules(): ValidationRules | Promise<ValidationRules>;
|
|
36
|
+
/**
|
|
37
|
+
* Get custom messages for validator errors
|
|
38
|
+
* Laravel: public function messages(): array
|
|
39
|
+
*
|
|
40
|
+
* @returns {Record<string, string>}
|
|
41
|
+
*/
|
|
42
|
+
protected messages(): Record<string, string>;
|
|
43
|
+
/**
|
|
44
|
+
* Get custom attributes for validator errors
|
|
45
|
+
* Laravel: public function attributes(): array
|
|
46
|
+
*
|
|
47
|
+
* @returns {Record<string, string>}
|
|
48
|
+
*/
|
|
49
|
+
protected attributes(): Record<string, string>;
|
|
50
|
+
/**
|
|
51
|
+
* Validate the request
|
|
52
|
+
*
|
|
53
|
+
* @throws {ValidationException} If validation fails
|
|
54
|
+
* @throws {Error} If authorization fails
|
|
55
|
+
*/
|
|
56
|
+
validate(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Get the validated data from the request
|
|
59
|
+
* Laravel: $request->validated()
|
|
60
|
+
*
|
|
61
|
+
* @returns {Record<string, any>}
|
|
62
|
+
*/
|
|
63
|
+
validated(): Record<string, any>;
|
|
64
|
+
/**
|
|
65
|
+
* Get the validator instance
|
|
66
|
+
*
|
|
67
|
+
* @returns {Validator | undefined}
|
|
68
|
+
*/
|
|
69
|
+
getValidator(): Validator | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Get all input data
|
|
72
|
+
* Laravel: $request->all()
|
|
73
|
+
*/
|
|
74
|
+
all(): Record<string, any>;
|
|
75
|
+
/**
|
|
76
|
+
* Get an input value
|
|
77
|
+
* Laravel: $request->input('key')
|
|
78
|
+
*/
|
|
79
|
+
input(key: string, defaultValue?: any): any;
|
|
80
|
+
/**
|
|
81
|
+
* Get only specified inputs
|
|
82
|
+
* Laravel: $request->only(['name', 'email'])
|
|
83
|
+
*/
|
|
84
|
+
only(keys: string[]): Record<string, any>;
|
|
85
|
+
/**
|
|
86
|
+
* Get all inputs except specified
|
|
87
|
+
* Laravel: $request->except(['password'])
|
|
88
|
+
*/
|
|
89
|
+
except(keys: string[]): Record<string, any>;
|
|
90
|
+
/**
|
|
91
|
+
* Get a route parameter
|
|
92
|
+
* Laravel: $request->route('id')
|
|
93
|
+
*/
|
|
94
|
+
routeParam(key: string, defaultValue?: string): string | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Handle a failed authorization attempt
|
|
97
|
+
* Laravel: protected function failedAuthorization()
|
|
98
|
+
*
|
|
99
|
+
* @param {Response} res
|
|
100
|
+
*/
|
|
101
|
+
handleFailedAuthorization(res: Response): void;
|
|
102
|
+
/**
|
|
103
|
+
* Handle a failed validation attempt
|
|
104
|
+
* Laravel: protected function failedValidation(Validator $validator)
|
|
105
|
+
*
|
|
106
|
+
* @param {Response} res
|
|
107
|
+
* @param {ValidationException} exception
|
|
108
|
+
*/
|
|
109
|
+
handleFailedValidation(res: Response, exception: ValidationException): void;
|
|
110
|
+
/**
|
|
111
|
+
* Static factory method to create and validate a FormRequest
|
|
112
|
+
*
|
|
113
|
+
* @param {Request} request
|
|
114
|
+
* @param {Response} res
|
|
115
|
+
* @returns {Promise<T>} The validated FormRequest instance
|
|
116
|
+
*/
|
|
117
|
+
static validate<T extends FormRequest>(this: new (request: Request) => T, request: Request, res: Response): Promise<T>;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=FormRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRequest.d.ts","sourceRoot":"","sources":["../../../src/Foundation/Http/FormRequest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzD;;;;;;GAMG;AACH,8BAAsB,WAAW;IAC/B,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAChC,SAAS,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAElC,OAAO,EAAE,OAAO;IAI5B;;;;;;;;OAQG;IACH,SAAS,CAAC,SAAS,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjD;;;;;;;OAOG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAEtE;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAI5C;;;;;OAKG;IACH,SAAS,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAI9C;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B/B;;;;;OAKG;IACH,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAOhC;;;;OAIG;IACH,YAAY,IAAI,SAAS,GAAG,SAAS;IAIrC;;;OAGG;IACH,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI1B;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG;IAI3C;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIzC;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI3C;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIlE;;;;;OAKG;IACH,yBAAyB,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAM9C;;;;;;OAMG;IACH,sBAAsB,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,mBAAmB,GAAG,IAAI;IAO3E;;;;;;OAMG;WACU,QAAQ,CAAC,CAAC,SAAS,WAAW,EACzC,IAAI,EAAE,KAAK,OAAO,EAAE,OAAO,KAAK,CAAC,EACjC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,QAAQ,GACZ,OAAO,CAAC,CAAC,CAAC;CAoBd"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FormRequest = void 0;
|
|
4
|
+
const ValidationException_1 = require("./ValidationException");
|
|
5
|
+
const Validator_1 = require("./Validator");
|
|
6
|
+
/**
|
|
7
|
+
* FormRequest - Laravel's form request validation
|
|
8
|
+
* Illuminate\Foundation\Http\FormRequest
|
|
9
|
+
*
|
|
10
|
+
* Provides authorization and validation for incoming HTTP requests.
|
|
11
|
+
* Automatically validates data before reaching the controller.
|
|
12
|
+
*/
|
|
13
|
+
class FormRequest {
|
|
14
|
+
request;
|
|
15
|
+
validator;
|
|
16
|
+
validatedData;
|
|
17
|
+
constructor(request) {
|
|
18
|
+
this.request = request;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Determine if the user is authorized to make this request
|
|
22
|
+
* Laravel: public function authorize(): bool
|
|
23
|
+
*
|
|
24
|
+
* Override this method to implement authorization logic.
|
|
25
|
+
* Return false to deny access (403 response).
|
|
26
|
+
*
|
|
27
|
+
* @returns {boolean | Promise<boolean>}
|
|
28
|
+
*/
|
|
29
|
+
authorize() {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get custom messages for validator errors
|
|
34
|
+
* Laravel: public function messages(): array
|
|
35
|
+
*
|
|
36
|
+
* @returns {Record<string, string>}
|
|
37
|
+
*/
|
|
38
|
+
messages() {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get custom attributes for validator errors
|
|
43
|
+
* Laravel: public function attributes(): array
|
|
44
|
+
*
|
|
45
|
+
* @returns {Record<string, string>}
|
|
46
|
+
*/
|
|
47
|
+
attributes() {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate the request
|
|
52
|
+
*
|
|
53
|
+
* @throws {ValidationException} If validation fails
|
|
54
|
+
* @throws {Error} If authorization fails
|
|
55
|
+
*/
|
|
56
|
+
async validate() {
|
|
57
|
+
// Check authorization first
|
|
58
|
+
const authorized = await this.authorize();
|
|
59
|
+
if (!authorized) {
|
|
60
|
+
throw new Error('This action is unauthorized.');
|
|
61
|
+
}
|
|
62
|
+
// Get validation rules
|
|
63
|
+
const rules = await this.rules();
|
|
64
|
+
// Create validator
|
|
65
|
+
this.validator = new Validator_1.Validator(this.request.all(), rules, this.messages(), this.attributes());
|
|
66
|
+
// Run validation
|
|
67
|
+
const passes = await this.validator.validate();
|
|
68
|
+
if (!passes) {
|
|
69
|
+
throw new ValidationException_1.ValidationException(this.validator);
|
|
70
|
+
}
|
|
71
|
+
// Store validated data
|
|
72
|
+
this.validatedData = this.validator.validated();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the validated data from the request
|
|
76
|
+
* Laravel: $request->validated()
|
|
77
|
+
*
|
|
78
|
+
* @returns {Record<string, any>}
|
|
79
|
+
*/
|
|
80
|
+
validated() {
|
|
81
|
+
if (!this.validatedData) {
|
|
82
|
+
throw new Error('Validation has not been run yet.');
|
|
83
|
+
}
|
|
84
|
+
return this.validatedData;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the validator instance
|
|
88
|
+
*
|
|
89
|
+
* @returns {Validator | undefined}
|
|
90
|
+
*/
|
|
91
|
+
getValidator() {
|
|
92
|
+
return this.validator;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get all input data
|
|
96
|
+
* Laravel: $request->all()
|
|
97
|
+
*/
|
|
98
|
+
all() {
|
|
99
|
+
return this.request.all();
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get an input value
|
|
103
|
+
* Laravel: $request->input('key')
|
|
104
|
+
*/
|
|
105
|
+
input(key, defaultValue) {
|
|
106
|
+
return this.request.input(key, defaultValue);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get only specified inputs
|
|
110
|
+
* Laravel: $request->only(['name', 'email'])
|
|
111
|
+
*/
|
|
112
|
+
only(keys) {
|
|
113
|
+
return this.request.only(keys);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get all inputs except specified
|
|
117
|
+
* Laravel: $request->except(['password'])
|
|
118
|
+
*/
|
|
119
|
+
except(keys) {
|
|
120
|
+
return this.request.except(keys);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get a route parameter
|
|
124
|
+
* Laravel: $request->route('id')
|
|
125
|
+
*/
|
|
126
|
+
routeParam(key, defaultValue) {
|
|
127
|
+
return this.request.routeParam(key, defaultValue);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Handle a failed authorization attempt
|
|
131
|
+
* Laravel: protected function failedAuthorization()
|
|
132
|
+
*
|
|
133
|
+
* @param {Response} res
|
|
134
|
+
*/
|
|
135
|
+
handleFailedAuthorization(res) {
|
|
136
|
+
res.status(403).json({
|
|
137
|
+
message: 'This action is unauthorized.'
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Handle a failed validation attempt
|
|
142
|
+
* Laravel: protected function failedValidation(Validator $validator)
|
|
143
|
+
*
|
|
144
|
+
* @param {Response} res
|
|
145
|
+
* @param {ValidationException} exception
|
|
146
|
+
*/
|
|
147
|
+
handleFailedValidation(res, exception) {
|
|
148
|
+
res.status(422).json({
|
|
149
|
+
message: 'The given data was invalid.',
|
|
150
|
+
errors: exception.errors()
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Static factory method to create and validate a FormRequest
|
|
155
|
+
*
|
|
156
|
+
* @param {Request} request
|
|
157
|
+
* @param {Response} res
|
|
158
|
+
* @returns {Promise<T>} The validated FormRequest instance
|
|
159
|
+
*/
|
|
160
|
+
static async validate(request, res) {
|
|
161
|
+
const formRequest = new this(request);
|
|
162
|
+
try {
|
|
163
|
+
await formRequest.validate();
|
|
164
|
+
return formRequest;
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if (error instanceof ValidationException_1.ValidationException) {
|
|
168
|
+
formRequest.handleFailedValidation(res, error);
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
if (error instanceof Error && error.message === 'This action is unauthorized.') {
|
|
172
|
+
formRequest.handleFailedAuthorization(res);
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.FormRequest = FormRequest;
|
|
180
|
+
//# sourceMappingURL=FormRequest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRequest.js","sourceRoot":"","sources":["../../../src/Foundation/Http/FormRequest.ts"],"names":[],"mappings":";;;AAEA,+DAA4D;AAC5D,2CAAyD;AAEzD;;;;;;GAMG;AACH,MAAsB,WAAW;IACrB,OAAO,CAAU;IACjB,SAAS,CAAa;IACtB,aAAa,CAAuB;IAE9C,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;;;;;;OAQG;IACO,SAAS;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAYD;;;;;OAKG;IACO,QAAQ;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;OAKG;IACO,UAAU;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ;QACZ,4BAA4B;QAC5B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,uBAAuB;QACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEjC,mBAAmB;QACnB,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAS,CAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAClB,KAAK,EACL,IAAI,CAAC,QAAQ,EAAE,EACf,IAAI,CAAC,UAAU,EAAE,CAClB,CAAC;QAEF,iBAAiB;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAE/C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,yCAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;IAClD,CAAC;IAED;;;;;OAKG;IACH,SAAS;QACP,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAW,EAAE,YAAkB;QACnC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,IAAc;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAc;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAW,EAAE,YAAqB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACpD,CAAC;IAED;;;;;OAKG;IACH,yBAAyB,CAAC,GAAa;QACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,8BAA8B;SACxC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,sBAAsB,CAAC,GAAa,EAAE,SAA8B;QAClE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE;SAC3B,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAEnB,OAAgB,EAChB,GAAa;QAEb,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC7B,OAAO,WAAW,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,yCAAmB,EAAE,CAAC;gBACzC,WAAW,CAAC,sBAAsB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC/C,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,8BAA8B,EAAE,CAAC;gBAC/E,WAAW,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;gBAC3C,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AA9MD,kCA8MC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Validator } from './Validator';
|
|
2
|
+
/**
|
|
3
|
+
* ValidationException - Laravel's validation exception
|
|
4
|
+
* Illuminate\Validation\ValidationException
|
|
5
|
+
*
|
|
6
|
+
* Thrown when validation fails, contains error messages
|
|
7
|
+
*/
|
|
8
|
+
export declare class ValidationException extends Error {
|
|
9
|
+
private validator;
|
|
10
|
+
private status;
|
|
11
|
+
constructor(validator: Validator, message?: string);
|
|
12
|
+
/**
|
|
13
|
+
* Get the validation errors
|
|
14
|
+
* Laravel: $exception->errors()
|
|
15
|
+
*
|
|
16
|
+
* @returns {Record<string, string[]>}
|
|
17
|
+
*/
|
|
18
|
+
errors(): Record<string, string[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the HTTP status code
|
|
21
|
+
*
|
|
22
|
+
* @returns {number}
|
|
23
|
+
*/
|
|
24
|
+
getStatus(): number;
|
|
25
|
+
/**
|
|
26
|
+
* Set the HTTP status code
|
|
27
|
+
*
|
|
28
|
+
* @param {number} status
|
|
29
|
+
* @returns {this}
|
|
30
|
+
*/
|
|
31
|
+
setStatus(status: number): this;
|
|
32
|
+
/**
|
|
33
|
+
* Get the validator instance
|
|
34
|
+
*
|
|
35
|
+
* @returns {Validator}
|
|
36
|
+
*/
|
|
37
|
+
getValidator(): Validator;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=ValidationException.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationException.d.ts","sourceRoot":"","sources":["../../../src/Foundation/Http/ValidationException.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAe;gBAEjB,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM;IAWlD;;;;;OAKG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAIlC;;;;OAIG;IACH,SAAS,IAAI,MAAM;IAInB;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B;;;;OAIG;IACH,YAAY,IAAI,SAAS;CAG1B"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationException = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* ValidationException - Laravel's validation exception
|
|
6
|
+
* Illuminate\Validation\ValidationException
|
|
7
|
+
*
|
|
8
|
+
* Thrown when validation fails, contains error messages
|
|
9
|
+
*/
|
|
10
|
+
class ValidationException extends Error {
|
|
11
|
+
validator;
|
|
12
|
+
status = 422;
|
|
13
|
+
constructor(validator, message) {
|
|
14
|
+
super(message || 'The given data was invalid.');
|
|
15
|
+
this.name = 'ValidationException';
|
|
16
|
+
this.validator = validator;
|
|
17
|
+
// Maintains proper stack trace for where our error was thrown
|
|
18
|
+
if (Error.captureStackTrace) {
|
|
19
|
+
Error.captureStackTrace(this, ValidationException);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get the validation errors
|
|
24
|
+
* Laravel: $exception->errors()
|
|
25
|
+
*
|
|
26
|
+
* @returns {Record<string, string[]>}
|
|
27
|
+
*/
|
|
28
|
+
errors() {
|
|
29
|
+
return this.validator.errors();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the HTTP status code
|
|
33
|
+
*
|
|
34
|
+
* @returns {number}
|
|
35
|
+
*/
|
|
36
|
+
getStatus() {
|
|
37
|
+
return this.status;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Set the HTTP status code
|
|
41
|
+
*
|
|
42
|
+
* @param {number} status
|
|
43
|
+
* @returns {this}
|
|
44
|
+
*/
|
|
45
|
+
setStatus(status) {
|
|
46
|
+
this.status = status;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get the validator instance
|
|
51
|
+
*
|
|
52
|
+
* @returns {Validator}
|
|
53
|
+
*/
|
|
54
|
+
getValidator() {
|
|
55
|
+
return this.validator;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.ValidationException = ValidationException;
|
|
59
|
+
//# sourceMappingURL=ValidationException.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationException.js","sourceRoot":"","sources":["../../../src/Foundation/Http/ValidationException.ts"],"names":[],"mappings":";;;AAEA;;;;;GAKG;AACH,MAAa,mBAAoB,SAAQ,KAAK;IACpC,SAAS,CAAY;IACrB,MAAM,GAAW,GAAG,CAAC;IAE7B,YAAY,SAAoB,EAAE,OAAgB;QAChD,KAAK,CAAC,OAAO,IAAI,6BAA6B,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,8DAA8D;QAC9D,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,MAAc;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AArDD,kDAqDC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validator - Laravel's validation engine
|
|
3
|
+
* Illuminate\Validation\Validator
|
|
4
|
+
*
|
|
5
|
+
* Provides validation rules and error handling
|
|
6
|
+
*/
|
|
7
|
+
export type ValidationRule = string | string[] | ValidationRuleObject;
|
|
8
|
+
export type ValidationRules = Record<string, ValidationRule>;
|
|
9
|
+
export interface ValidationRuleObject {
|
|
10
|
+
rule: string;
|
|
11
|
+
message?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class Validator {
|
|
14
|
+
private data;
|
|
15
|
+
private rules;
|
|
16
|
+
private customMessages;
|
|
17
|
+
private customAttributes;
|
|
18
|
+
private errorMessages;
|
|
19
|
+
private validatedFields;
|
|
20
|
+
constructor(data: Record<string, any>, rules: ValidationRules, customMessages?: Record<string, string>, customAttributes?: Record<string, string>);
|
|
21
|
+
/**
|
|
22
|
+
* Validate the data against the rules
|
|
23
|
+
*
|
|
24
|
+
* @returns {Promise<boolean>} True if validation passes
|
|
25
|
+
*/
|
|
26
|
+
validate(): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Parse validation rules from various formats
|
|
29
|
+
*/
|
|
30
|
+
private parseRules;
|
|
31
|
+
/**
|
|
32
|
+
* Get field value from data, supporting dot notation
|
|
33
|
+
*/
|
|
34
|
+
private getFieldValue;
|
|
35
|
+
/**
|
|
36
|
+
* Validate a single rule
|
|
37
|
+
*/
|
|
38
|
+
private validateRule;
|
|
39
|
+
/**
|
|
40
|
+
* Validate email format
|
|
41
|
+
*/
|
|
42
|
+
private isValidEmail;
|
|
43
|
+
/**
|
|
44
|
+
* Validate URL format
|
|
45
|
+
*/
|
|
46
|
+
private isValidUrl;
|
|
47
|
+
/**
|
|
48
|
+
* Get custom message or default message
|
|
49
|
+
*/
|
|
50
|
+
private getMessage;
|
|
51
|
+
/**
|
|
52
|
+
* Get custom attribute name or use field name
|
|
53
|
+
*/
|
|
54
|
+
private getAttribute;
|
|
55
|
+
/**
|
|
56
|
+
* Add an error message for a field
|
|
57
|
+
*/
|
|
58
|
+
private addError;
|
|
59
|
+
/**
|
|
60
|
+
* Get all error messages
|
|
61
|
+
* Laravel: $validator->errors()
|
|
62
|
+
*/
|
|
63
|
+
errors(): Record<string, string[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Check if validation failed
|
|
66
|
+
* Laravel: $validator->fails()
|
|
67
|
+
*/
|
|
68
|
+
fails(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Check if validation passed
|
|
71
|
+
* Laravel: $validator->passes()
|
|
72
|
+
*/
|
|
73
|
+
passes(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Get the validated data
|
|
76
|
+
* Laravel: $validator->validated()
|
|
77
|
+
*/
|
|
78
|
+
validated(): Record<string, any>;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=Validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.d.ts","sourceRoot":"","sources":["../../../src/Foundation/Http/Validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,oBAAoB,CAAC;AACtE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE7D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,eAAe,CAA2B;gBAGhD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,eAAe,EACtB,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAC3C,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAQ/C;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IA0BlC;;OAEG;IACH,OAAO,CAAC,UAAU;IAgBlB;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;OAEG;YACW,YAAY;IAyM1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,UAAU;IASlB;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAOhB;;;OAGG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAIlC;;;OAGG;IACH,KAAK,IAAI,OAAO;IAIhB;;;OAGG;IACH,MAAM,IAAI,OAAO;IAIjB;;;OAGG;IACH,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAGjC"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Validator - Laravel's validation engine
|
|
4
|
+
* Illuminate\Validation\Validator
|
|
5
|
+
*
|
|
6
|
+
* Provides validation rules and error handling
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.Validator = void 0;
|
|
10
|
+
class Validator {
|
|
11
|
+
data;
|
|
12
|
+
rules;
|
|
13
|
+
customMessages;
|
|
14
|
+
customAttributes;
|
|
15
|
+
errorMessages = {};
|
|
16
|
+
validatedFields = {};
|
|
17
|
+
constructor(data, rules, customMessages = {}, customAttributes = {}) {
|
|
18
|
+
this.data = data;
|
|
19
|
+
this.rules = rules;
|
|
20
|
+
this.customMessages = customMessages;
|
|
21
|
+
this.customAttributes = customAttributes;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validate the data against the rules
|
|
25
|
+
*
|
|
26
|
+
* @returns {Promise<boolean>} True if validation passes
|
|
27
|
+
*/
|
|
28
|
+
async validate() {
|
|
29
|
+
this.errorMessages = {};
|
|
30
|
+
this.validatedFields = {};
|
|
31
|
+
for (const [field, rule] of Object.entries(this.rules)) {
|
|
32
|
+
const rules = this.parseRules(rule);
|
|
33
|
+
const value = this.getFieldValue(field);
|
|
34
|
+
for (const ruleName of rules) {
|
|
35
|
+
const [ruleKey, ...params] = ruleName.split(':');
|
|
36
|
+
const result = await this.validateRule(field, value, ruleKey, params);
|
|
37
|
+
if (!result.passes) {
|
|
38
|
+
this.addError(field, result.message);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// If no errors for this field, add to validated data
|
|
42
|
+
if (!this.errorMessages[field]) {
|
|
43
|
+
this.validatedFields[field] = value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return Object.keys(this.errorMessages).length === 0;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse validation rules from various formats
|
|
50
|
+
*/
|
|
51
|
+
parseRules(rule) {
|
|
52
|
+
if (typeof rule === 'string') {
|
|
53
|
+
return rule.split('|').map(r => r.trim());
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(rule)) {
|
|
56
|
+
return rule;
|
|
57
|
+
}
|
|
58
|
+
if (typeof rule === 'object' && 'rule' in rule) {
|
|
59
|
+
return [rule.rule];
|
|
60
|
+
}
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get field value from data, supporting dot notation
|
|
65
|
+
*/
|
|
66
|
+
getFieldValue(field) {
|
|
67
|
+
const keys = field.split('.');
|
|
68
|
+
let value = this.data;
|
|
69
|
+
for (const key of keys) {
|
|
70
|
+
if (value && typeof value === 'object' && key in value) {
|
|
71
|
+
value = value[key];
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validate a single rule
|
|
81
|
+
*/
|
|
82
|
+
async validateRule(field, value, rule, params) {
|
|
83
|
+
const attribute = this.getAttribute(field);
|
|
84
|
+
switch (rule) {
|
|
85
|
+
case 'required':
|
|
86
|
+
if (value === undefined || value === null || value === '') {
|
|
87
|
+
return {
|
|
88
|
+
passes: false,
|
|
89
|
+
message: this.getMessage(field, rule, `The ${attribute} field is required.`)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return { passes: true, message: '' };
|
|
93
|
+
case 'email':
|
|
94
|
+
if (value && !this.isValidEmail(value)) {
|
|
95
|
+
return {
|
|
96
|
+
passes: false,
|
|
97
|
+
message: this.getMessage(field, rule, `The ${attribute} must be a valid email address.`)
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return { passes: true, message: '' };
|
|
101
|
+
case 'string':
|
|
102
|
+
if (value && typeof value !== 'string') {
|
|
103
|
+
return {
|
|
104
|
+
passes: false,
|
|
105
|
+
message: this.getMessage(field, rule, `The ${attribute} must be a string.`)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return { passes: true, message: '' };
|
|
109
|
+
case 'numeric':
|
|
110
|
+
case 'number':
|
|
111
|
+
if (value && isNaN(Number(value))) {
|
|
112
|
+
return {
|
|
113
|
+
passes: false,
|
|
114
|
+
message: this.getMessage(field, rule, `The ${attribute} must be a number.`)
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return { passes: true, message: '' };
|
|
118
|
+
case 'integer':
|
|
119
|
+
if (value && (!Number.isInteger(Number(value)) || isNaN(Number(value)))) {
|
|
120
|
+
return {
|
|
121
|
+
passes: false,
|
|
122
|
+
message: this.getMessage(field, rule, `The ${attribute} must be an integer.`)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return { passes: true, message: '' };
|
|
126
|
+
case 'boolean':
|
|
127
|
+
if (value !== undefined && typeof value !== 'boolean' && value !== 'true' && value !== 'false' && value !== 1 && value !== 0) {
|
|
128
|
+
return {
|
|
129
|
+
passes: false,
|
|
130
|
+
message: this.getMessage(field, rule, `The ${attribute} must be true or false.`)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return { passes: true, message: '' };
|
|
134
|
+
case 'min':
|
|
135
|
+
const minValue = params[0];
|
|
136
|
+
if (typeof value === 'string' && value.length < parseInt(minValue)) {
|
|
137
|
+
return {
|
|
138
|
+
passes: false,
|
|
139
|
+
message: this.getMessage(field, rule, `The ${attribute} must be at least ${minValue} characters.`)
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (typeof value === 'number' && value < parseFloat(minValue)) {
|
|
143
|
+
return {
|
|
144
|
+
passes: false,
|
|
145
|
+
message: this.getMessage(field, rule, `The ${attribute} must be at least ${minValue}.`)
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return { passes: true, message: '' };
|
|
149
|
+
case 'max':
|
|
150
|
+
const maxValue = params[0];
|
|
151
|
+
if (typeof value === 'string' && value.length > parseInt(maxValue)) {
|
|
152
|
+
return {
|
|
153
|
+
passes: false,
|
|
154
|
+
message: this.getMessage(field, rule, `The ${attribute} may not be greater than ${maxValue} characters.`)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if (typeof value === 'number' && value > parseFloat(maxValue)) {
|
|
158
|
+
return {
|
|
159
|
+
passes: false,
|
|
160
|
+
message: this.getMessage(field, rule, `The ${attribute} may not be greater than ${maxValue}.`)
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return { passes: true, message: '' };
|
|
164
|
+
case 'between':
|
|
165
|
+
const [minBetween, maxBetween] = params;
|
|
166
|
+
const numValue = typeof value === 'string' ? value.length : Number(value);
|
|
167
|
+
if (numValue < parseFloat(minBetween) || numValue > parseFloat(maxBetween)) {
|
|
168
|
+
return {
|
|
169
|
+
passes: false,
|
|
170
|
+
message: this.getMessage(field, rule, `The ${attribute} must be between ${minBetween} and ${maxBetween}.`)
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return { passes: true, message: '' };
|
|
174
|
+
case 'in':
|
|
175
|
+
if (value && !params.includes(String(value))) {
|
|
176
|
+
return {
|
|
177
|
+
passes: false,
|
|
178
|
+
message: this.getMessage(field, rule, `The selected ${attribute} is invalid.`)
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return { passes: true, message: '' };
|
|
182
|
+
case 'not_in':
|
|
183
|
+
if (value && params.includes(String(value))) {
|
|
184
|
+
return {
|
|
185
|
+
passes: false,
|
|
186
|
+
message: this.getMessage(field, rule, `The selected ${attribute} is invalid.`)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
return { passes: true, message: '' };
|
|
190
|
+
case 'array':
|
|
191
|
+
if (value && !Array.isArray(value)) {
|
|
192
|
+
return {
|
|
193
|
+
passes: false,
|
|
194
|
+
message: this.getMessage(field, rule, `The ${attribute} must be an array.`)
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return { passes: true, message: '' };
|
|
198
|
+
case 'confirmed':
|
|
199
|
+
const confirmationField = `${field}_confirmation`;
|
|
200
|
+
const confirmationValue = this.data[confirmationField];
|
|
201
|
+
if (value !== confirmationValue) {
|
|
202
|
+
return {
|
|
203
|
+
passes: false,
|
|
204
|
+
message: this.getMessage(field, rule, `The ${attribute} confirmation does not match.`)
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return { passes: true, message: '' };
|
|
208
|
+
case 'url':
|
|
209
|
+
if (value && !this.isValidUrl(value)) {
|
|
210
|
+
return {
|
|
211
|
+
passes: false,
|
|
212
|
+
message: this.getMessage(field, rule, `The ${attribute} must be a valid URL.`)
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return { passes: true, message: '' };
|
|
216
|
+
case 'alpha':
|
|
217
|
+
if (value && !/^[a-zA-Z]+$/.test(value)) {
|
|
218
|
+
return {
|
|
219
|
+
passes: false,
|
|
220
|
+
message: this.getMessage(field, rule, `The ${attribute} may only contain letters.`)
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return { passes: true, message: '' };
|
|
224
|
+
case 'alpha_num':
|
|
225
|
+
if (value && !/^[a-zA-Z0-9]+$/.test(value)) {
|
|
226
|
+
return {
|
|
227
|
+
passes: false,
|
|
228
|
+
message: this.getMessage(field, rule, `The ${attribute} may only contain letters and numbers.`)
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return { passes: true, message: '' };
|
|
232
|
+
case 'alpha_dash':
|
|
233
|
+
if (value && !/^[a-zA-Z0-9_-]+$/.test(value)) {
|
|
234
|
+
return {
|
|
235
|
+
passes: false,
|
|
236
|
+
message: this.getMessage(field, rule, `The ${attribute} may only contain letters, numbers, dashes and underscores.`)
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return { passes: true, message: '' };
|
|
240
|
+
case 'regex':
|
|
241
|
+
const pattern = new RegExp(params.join(':'));
|
|
242
|
+
if (value && !pattern.test(value)) {
|
|
243
|
+
return {
|
|
244
|
+
passes: false,
|
|
245
|
+
message: this.getMessage(field, rule, `The ${attribute} format is invalid.`)
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
return { passes: true, message: '' };
|
|
249
|
+
default:
|
|
250
|
+
console.warn(`Unknown validation rule: ${rule}`);
|
|
251
|
+
return { passes: true, message: '' };
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Validate email format
|
|
256
|
+
*/
|
|
257
|
+
isValidEmail(email) {
|
|
258
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
259
|
+
return emailRegex.test(email);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Validate URL format
|
|
263
|
+
*/
|
|
264
|
+
isValidUrl(url) {
|
|
265
|
+
try {
|
|
266
|
+
new URL(url);
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get custom message or default message
|
|
275
|
+
*/
|
|
276
|
+
getMessage(field, rule, defaultMessage) {
|
|
277
|
+
const customKey = `${field}.${rule}`;
|
|
278
|
+
return this.customMessages[customKey] || this.customMessages[rule] || defaultMessage;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get custom attribute name or use field name
|
|
282
|
+
*/
|
|
283
|
+
getAttribute(field) {
|
|
284
|
+
return this.customAttributes[field] || field.replace(/_/g, ' ');
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Add an error message for a field
|
|
288
|
+
*/
|
|
289
|
+
addError(field, message) {
|
|
290
|
+
if (!this.errorMessages[field]) {
|
|
291
|
+
this.errorMessages[field] = [];
|
|
292
|
+
}
|
|
293
|
+
this.errorMessages[field].push(message);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Get all error messages
|
|
297
|
+
* Laravel: $validator->errors()
|
|
298
|
+
*/
|
|
299
|
+
errors() {
|
|
300
|
+
return this.errorMessages;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Check if validation failed
|
|
304
|
+
* Laravel: $validator->fails()
|
|
305
|
+
*/
|
|
306
|
+
fails() {
|
|
307
|
+
return Object.keys(this.errorMessages).length > 0;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Check if validation passed
|
|
311
|
+
* Laravel: $validator->passes()
|
|
312
|
+
*/
|
|
313
|
+
passes() {
|
|
314
|
+
return !this.fails();
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Get the validated data
|
|
318
|
+
* Laravel: $validator->validated()
|
|
319
|
+
*/
|
|
320
|
+
validated() {
|
|
321
|
+
return this.validatedFields;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
exports.Validator = Validator;
|
|
325
|
+
//# sourceMappingURL=Validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.js","sourceRoot":"","sources":["../../../src/Foundation/Http/Validator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
export { Application } from './Foundation/Application';
|
|
6
6
|
export { ServiceProvider } from './Foundation/ServiceProvider';
|
|
7
7
|
export { Kernel } from './Foundation/Http/Kernel';
|
|
8
|
+
export { FormRequest } from './Foundation/Http/FormRequest';
|
|
9
|
+
export { ValidationException } from './Foundation/Http/ValidationException';
|
|
10
|
+
export { Validator } from './Foundation/Http/Validator';
|
|
11
|
+
export type { ValidationRules, ValidationRule, ValidationRuleObject } from './Foundation/Http/Validator';
|
|
8
12
|
export { Container } from './Container/Container';
|
|
9
13
|
export { Router } from './Routing/Router';
|
|
10
14
|
export { Route as RouteClass } from './Routing/Route';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Main exports
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.HasRelationshipsMixin = exports.BelongsTo = exports.HasMany = exports.HasOne = exports.Relation = exports.softDeletes = exports.EnsembleCollection = exports.EnsembleBuilder = exports.Ensemble = exports.DB = exports.DrizzleAdapter = exports.raw = exports.Expression = exports.QueryBuilder = exports.Connection = exports.DatabaseManager = exports.DatabaseServiceProvider = exports.RouteServiceProvider = exports.Injectable = exports.routes_path = exports.base_path = exports.loadRoutes = exports.Route = exports.Facade = exports.Controller = exports.Response = exports.Request = exports.RouteClass = exports.Router = exports.Container = exports.Kernel = exports.ServiceProvider = exports.Application = void 0;
|
|
7
|
+
exports.HasRelationshipsMixin = exports.BelongsTo = exports.HasMany = exports.HasOne = exports.Relation = exports.softDeletes = exports.EnsembleCollection = exports.EnsembleBuilder = exports.Ensemble = exports.DB = exports.DrizzleAdapter = exports.raw = exports.Expression = exports.QueryBuilder = exports.Connection = exports.DatabaseManager = exports.DatabaseServiceProvider = exports.RouteServiceProvider = exports.Injectable = exports.routes_path = exports.base_path = exports.loadRoutes = exports.Route = exports.Facade = exports.Controller = exports.Response = exports.Request = exports.RouteClass = exports.Router = exports.Container = exports.Validator = exports.ValidationException = exports.FormRequest = exports.Kernel = exports.ServiceProvider = exports.Application = void 0;
|
|
8
8
|
// Foundation
|
|
9
9
|
var Application_1 = require("./Foundation/Application");
|
|
10
10
|
Object.defineProperty(exports, "Application", { enumerable: true, get: function () { return Application_1.Application; } });
|
|
@@ -12,6 +12,12 @@ var ServiceProvider_1 = require("./Foundation/ServiceProvider");
|
|
|
12
12
|
Object.defineProperty(exports, "ServiceProvider", { enumerable: true, get: function () { return ServiceProvider_1.ServiceProvider; } });
|
|
13
13
|
var Kernel_1 = require("./Foundation/Http/Kernel");
|
|
14
14
|
Object.defineProperty(exports, "Kernel", { enumerable: true, get: function () { return Kernel_1.Kernel; } });
|
|
15
|
+
var FormRequest_1 = require("./Foundation/Http/FormRequest");
|
|
16
|
+
Object.defineProperty(exports, "FormRequest", { enumerable: true, get: function () { return FormRequest_1.FormRequest; } });
|
|
17
|
+
var ValidationException_1 = require("./Foundation/Http/ValidationException");
|
|
18
|
+
Object.defineProperty(exports, "ValidationException", { enumerable: true, get: function () { return ValidationException_1.ValidationException; } });
|
|
19
|
+
var Validator_1 = require("./Foundation/Http/Validator");
|
|
20
|
+
Object.defineProperty(exports, "Validator", { enumerable: true, get: function () { return Validator_1.Validator; } });
|
|
15
21
|
// Container
|
|
16
22
|
var Container_1 = require("./Container/Container");
|
|
17
23
|
Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return Container_1.Container; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,aAAa;AACb,wDAAuD;AAA9C,0GAAA,WAAW,OAAA;AACpB,gEAA+D;AAAtD,kHAAA,eAAe,OAAA;AACxB,mDAAkD;AAAzC,gGAAA,MAAM,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,aAAa;AACb,wDAAuD;AAA9C,0GAAA,WAAW,OAAA;AACpB,gEAA+D;AAAtD,kHAAA,eAAe,OAAA;AACxB,mDAAkD;AAAzC,gGAAA,MAAM,OAAA;AACf,6DAA4D;AAAnD,0GAAA,WAAW,OAAA;AACpB,6EAA4E;AAAnE,0HAAA,mBAAmB,OAAA;AAC5B,yDAAwD;AAA/C,sGAAA,SAAS,OAAA;AAGlB,YAAY;AACZ,mDAAkD;AAAzC,sGAAA,SAAS,OAAA;AAElB,UAAU;AACV,2CAA0C;AAAjC,gGAAA,MAAM,OAAA;AACf,yCAAsD;AAA7C,mGAAA,KAAK,OAAc;AAC5B,6CAA4C;AAAnC,kGAAA,OAAO,OAAA;AAChB,+CAA8C;AAArC,oGAAA,QAAQ,OAAA;AACjB,mDAAkD;AAAzC,wGAAA,UAAU,OAAA;AAEnB,UAAU;AACV,2CAA0C;AAAjC,gGAAA,MAAM,OAAA;AACf,yCAAwC;AAA/B,8FAAA,KAAK,OAAA;AAEd,UAAU;AACV,6CAAuE;AAA9D,qGAAA,UAAU,OAAA;AAAE,oGAAA,SAAS,OAAA;AAAE,sGAAA,WAAW,OAAA;AAE3C,aAAa;AACb,mDAAkD;AAAzC,wGAAA,UAAU,OAAA;AAEnB,YAAY;AACZ,yEAAwE;AAA/D,4HAAA,oBAAoB,OAAA;AAC7B,8EAA6E;AAApE,kIAAA,uBAAuB,OAAA;AAEhC,WAAW;AACX,8DAA6D;AAApD,kHAAA,eAAe,OAAA;AACxB,oDAAmD;AAA1C,wGAAA,UAAU,OAAA;AACnB,oDAAmE;AAA1D,uGAAA,OAAO,OAAgB;AAChC,0DAA8D;AAArD,wGAAA,UAAU,OAAA;AAAE,iGAAA,GAAG,OAAA;AACxB,qEAAoE;AAA3D,gHAAA,cAAc,OAAA;AAEvB,mBAAmB;AACnB,mCAAkC;AAAzB,wFAAA,EAAE,OAAA;AAEX,eAAe;AACf,yDAAwD;AAA/C,oGAAA,QAAQ,OAAA;AACjB,uEAAsE;AAA7D,kHAAA,eAAe,OAAA;AACxB,6EAA4E;AAAnE,wHAAA,kBAAkB,OAAA;AAC3B,+DAA8D;AAArD,0GAAA,WAAW,OAAA;AAEpB,qBAAqB;AACrB,2DAAqF;AAA5E,qGAAA,QAAQ,OAAA;AAAE,mGAAA,MAAM,OAAA;AAAE,oGAAA,OAAO,OAAA;AAAE,sGAAA,SAAS,OAAA;AAE7C,oBAAoB;AACpB,kFAAsF;AAA7E,yHAAA,qBAAqB,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchestr-sh/orchestr",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "A 1:1 Laravel replica in TypeScript - Brings Laravel's elegant syntax and architecture to Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"prepublishOnly": "npm run build",
|
|
15
|
-
"dev": "tsx watch examples/basic-app/server.ts"
|
|
16
|
-
"example:basic": "tsx examples/basic-app/server.ts"
|
|
15
|
+
"dev": "tsx watch examples/basic-app/server.ts"
|
|
17
16
|
},
|
|
18
17
|
"keywords": [
|
|
19
18
|
"laravel",
|