@ooneex/validation 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +468 -0
- package/dist/constraints/index.d.ts +17 -1
- package/dist/constraints/index.js +2 -2
- package/dist/constraints/index.js.map +7 -5
- package/dist/index.d.ts +8 -55
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/dist/shared/chunk-bn4vhq39.js +4 -0
- package/dist/shared/chunk-bn4vhq39.js.map +11 -0
- package/package.json +16 -8
package/README.md
CHANGED
|
@@ -1 +1,469 @@
|
|
|
1
1
|
# @ooneex/validation
|
|
2
|
+
|
|
3
|
+
A type-safe validation framework powered by ArkType for TypeScript applications. This package provides a robust foundation for data validation with built-in constraints, JSON schema support, and seamless integration with the Ooneex framework.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
✅ **ArkType Powered** - Built on the fast and type-safe ArkType validation library
|
|
14
|
+
|
|
15
|
+
✅ **Built-in Constraints** - Pre-built validators for common use cases (email, URL, port, etc.)
|
|
16
|
+
|
|
17
|
+
✅ **JSON Schema Support** - Convert schemas to JSON Schema format for documentation
|
|
18
|
+
|
|
19
|
+
✅ **Custom Error Messages** - Define user-friendly error messages for validation failures
|
|
20
|
+
|
|
21
|
+
✅ **Type-Safe** - Full TypeScript support with inferred types from schemas
|
|
22
|
+
|
|
23
|
+
✅ **Extensible** - Create custom validators by extending the base `Validation` class
|
|
24
|
+
|
|
25
|
+
✅ **Framework Integration** - Works seamlessly with Ooneex routing and controllers
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
### Bun
|
|
30
|
+
```bash
|
|
31
|
+
bun add @ooneex/validation
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### pnpm
|
|
35
|
+
```bash
|
|
36
|
+
pnpm add @ooneex/validation
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Yarn
|
|
40
|
+
```bash
|
|
41
|
+
yarn add @ooneex/validation
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### npm
|
|
45
|
+
```bash
|
|
46
|
+
npm install @ooneex/validation
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
### Basic Validation with ArkType
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { type } from '@ooneex/validation';
|
|
55
|
+
|
|
56
|
+
// Define a schema
|
|
57
|
+
const UserSchema = type({
|
|
58
|
+
name: 'string',
|
|
59
|
+
email: 'string.email',
|
|
60
|
+
age: 'number >= 0'
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Validate data
|
|
64
|
+
const result = UserSchema({ name: 'John', email: 'john@example.com', age: 25 });
|
|
65
|
+
|
|
66
|
+
if (result instanceof type.errors) {
|
|
67
|
+
console.error('Validation failed:', result.summary);
|
|
68
|
+
} else {
|
|
69
|
+
console.log('Valid user:', result);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Using the Validation Class
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { Validation, type } from '@ooneex/validation';
|
|
77
|
+
import type { AssertType, ValidationResultType } from '@ooneex/validation';
|
|
78
|
+
|
|
79
|
+
class EmailValidator extends Validation {
|
|
80
|
+
public getConstraint(): AssertType {
|
|
81
|
+
return type('string.email');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public getErrorMessage(): string | null {
|
|
85
|
+
return 'Please provide a valid email address';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const validator = new EmailValidator();
|
|
90
|
+
const result = validator.validate('not-an-email');
|
|
91
|
+
|
|
92
|
+
if (!result.isValid) {
|
|
93
|
+
console.error(result.message); // "Please provide a valid email address"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Using Built-in Constraints
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import {
|
|
101
|
+
AssertEmail,
|
|
102
|
+
AssertPort,
|
|
103
|
+
AssertHostname,
|
|
104
|
+
AssertAppEnv
|
|
105
|
+
} from '@ooneex/validation/constraints';
|
|
106
|
+
|
|
107
|
+
// Validate email
|
|
108
|
+
const emailValidator = new AssertEmail();
|
|
109
|
+
const emailResult = emailValidator.validate('user@example.com');
|
|
110
|
+
console.log(emailResult.isValid); // true
|
|
111
|
+
|
|
112
|
+
// Validate port number
|
|
113
|
+
const portValidator = new AssertPort();
|
|
114
|
+
const portResult = portValidator.validate(3000);
|
|
115
|
+
console.log(portResult.isValid); // true
|
|
116
|
+
|
|
117
|
+
// Validate hostname
|
|
118
|
+
const hostnameValidator = new AssertHostname();
|
|
119
|
+
const hostnameResult = hostnameValidator.validate('0.0.0.0');
|
|
120
|
+
console.log(hostnameResult.isValid); // true
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Route Validation
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { Route } from '@ooneex/routing';
|
|
127
|
+
import { type } from '@ooneex/validation';
|
|
128
|
+
import type { IController, ContextType } from '@ooneex/controller';
|
|
129
|
+
|
|
130
|
+
const CreateUserPayload = type({
|
|
131
|
+
name: 'string > 0',
|
|
132
|
+
email: 'string.email',
|
|
133
|
+
password: 'string >= 8'
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const UserIdParam = type({
|
|
137
|
+
id: 'string.uuid'
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
@Route.http({
|
|
141
|
+
name: 'api.users.create',
|
|
142
|
+
path: '/api/users',
|
|
143
|
+
method: 'POST',
|
|
144
|
+
payload: CreateUserPayload,
|
|
145
|
+
description: 'Create a new user'
|
|
146
|
+
})
|
|
147
|
+
class UserCreateController implements IController {
|
|
148
|
+
public async index(context: ContextType): Promise<IResponse> {
|
|
149
|
+
// Payload is already validated at this point
|
|
150
|
+
const { name, email, password } = context.payload;
|
|
151
|
+
|
|
152
|
+
return context.response.json({
|
|
153
|
+
user: { name, email }
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## API Reference
|
|
160
|
+
|
|
161
|
+
### Re-exports from ArkType
|
|
162
|
+
|
|
163
|
+
This package re-exports all types and utilities from ArkType:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { type, scope, union, intersection } from '@ooneex/validation';
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
See the [ArkType documentation](https://arktype.io/) for full API reference.
|
|
170
|
+
|
|
171
|
+
### Classes
|
|
172
|
+
|
|
173
|
+
#### `Validation`
|
|
174
|
+
|
|
175
|
+
Abstract base class for creating custom validators.
|
|
176
|
+
|
|
177
|
+
**Methods:**
|
|
178
|
+
|
|
179
|
+
##### `abstract getConstraint(): AssertType`
|
|
180
|
+
|
|
181
|
+
Returns the ArkType schema to validate against.
|
|
182
|
+
|
|
183
|
+
##### `abstract getErrorMessage(): string | null`
|
|
184
|
+
|
|
185
|
+
Returns a custom error message or `null` to use the default ArkType error.
|
|
186
|
+
|
|
187
|
+
##### `validate(data: unknown, constraint?: AssertType): ValidationResultType`
|
|
188
|
+
|
|
189
|
+
Validates data against the constraint.
|
|
190
|
+
|
|
191
|
+
**Parameters:**
|
|
192
|
+
- `data` - The data to validate
|
|
193
|
+
- `constraint` - Optional constraint override
|
|
194
|
+
|
|
195
|
+
**Returns:** Validation result object
|
|
196
|
+
|
|
197
|
+
**Example:**
|
|
198
|
+
```typescript
|
|
199
|
+
class PositiveNumberValidator extends Validation {
|
|
200
|
+
public getConstraint(): AssertType {
|
|
201
|
+
return type('number > 0');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public getErrorMessage(): string | null {
|
|
205
|
+
return 'Value must be a positive number';
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const validator = new PositiveNumberValidator();
|
|
210
|
+
const result = validator.validate(42);
|
|
211
|
+
console.log(result); // { isValid: true }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Functions
|
|
215
|
+
|
|
216
|
+
#### `Assert`
|
|
217
|
+
|
|
218
|
+
Utility for quick inline assertions.
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { Assert } from '@ooneex/validation';
|
|
222
|
+
|
|
223
|
+
const isValid = Assert(value, type('string.email'));
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### `jsonSchemaToTypeString(schema: object): string`
|
|
227
|
+
|
|
228
|
+
Converts a JSON Schema to a human-readable type string.
|
|
229
|
+
|
|
230
|
+
**Parameters:**
|
|
231
|
+
- `schema` - JSON Schema object
|
|
232
|
+
|
|
233
|
+
**Returns:** String representation of the type
|
|
234
|
+
|
|
235
|
+
**Example:**
|
|
236
|
+
```typescript
|
|
237
|
+
import { type, jsonSchemaToTypeString } from '@ooneex/validation';
|
|
238
|
+
|
|
239
|
+
const UserSchema = type({
|
|
240
|
+
name: 'string',
|
|
241
|
+
age: 'number'
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const jsonSchema = UserSchema.toJsonSchema();
|
|
245
|
+
const typeString = jsonSchemaToTypeString(jsonSchema);
|
|
246
|
+
console.log(typeString); // "{ name: string, age: number }"
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Types
|
|
250
|
+
|
|
251
|
+
#### `AssertType`
|
|
252
|
+
|
|
253
|
+
Type alias for ArkType's `Type` definition.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import type { AssertType } from '@ooneex/validation';
|
|
257
|
+
|
|
258
|
+
const schema: AssertType = type('string');
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
#### `IAssert`
|
|
262
|
+
|
|
263
|
+
Interface for validator classes.
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
interface IAssert {
|
|
267
|
+
getConstraint: () => AssertType;
|
|
268
|
+
getErrorMessage: () => string | null;
|
|
269
|
+
validate: (data: unknown, constraint?: AssertType) => ValidationResultType;
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### `ValidationResultType`
|
|
274
|
+
|
|
275
|
+
Result object returned from validation.
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
type ValidationResultType = {
|
|
279
|
+
isValid: boolean;
|
|
280
|
+
message?: string;
|
|
281
|
+
};
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### `ValidationClassType`
|
|
285
|
+
|
|
286
|
+
Type for validator class constructors.
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
type ValidationClassType = new (...args: any[]) => IAssert;
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Built-in Constraints
|
|
293
|
+
|
|
294
|
+
Import from `@ooneex/validation/constraints`:
|
|
295
|
+
|
|
296
|
+
| Constraint | Description |
|
|
297
|
+
|------------|-------------|
|
|
298
|
+
| `AssertEmail` | Validates email addresses |
|
|
299
|
+
| `AssertPort` | Validates port numbers (1-65535) |
|
|
300
|
+
| `AssertHostname` | Validates hostnames and IP addresses |
|
|
301
|
+
| `AssertAppEnv` | Validates application environment strings |
|
|
302
|
+
|
|
303
|
+
## Advanced Usage
|
|
304
|
+
|
|
305
|
+
### Creating Complex Schemas
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import { type, scope } from '@ooneex/validation';
|
|
309
|
+
|
|
310
|
+
// Define a scope for related types
|
|
311
|
+
const $ = scope({
|
|
312
|
+
user: {
|
|
313
|
+
id: 'string.uuid',
|
|
314
|
+
email: 'string.email',
|
|
315
|
+
profile: 'profile'
|
|
316
|
+
},
|
|
317
|
+
profile: {
|
|
318
|
+
firstName: 'string > 0',
|
|
319
|
+
lastName: 'string > 0',
|
|
320
|
+
age: 'number.integer >= 0',
|
|
321
|
+
bio: 'string | null'
|
|
322
|
+
}
|
|
323
|
+
}).export();
|
|
324
|
+
|
|
325
|
+
// Use the scoped types
|
|
326
|
+
const user = $.user({
|
|
327
|
+
id: '123e4567-e89b-12d3-a456-426614174000',
|
|
328
|
+
email: 'john@example.com',
|
|
329
|
+
profile: {
|
|
330
|
+
firstName: 'John',
|
|
331
|
+
lastName: 'Doe',
|
|
332
|
+
age: 30,
|
|
333
|
+
bio: null
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Union Types
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
import { type } from '@ooneex/validation';
|
|
342
|
+
|
|
343
|
+
const StatusSchema = type("'pending' | 'active' | 'inactive'");
|
|
344
|
+
|
|
345
|
+
const result = StatusSchema('active');
|
|
346
|
+
console.log(result); // "active"
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Array Validation
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
import { type } from '@ooneex/validation';
|
|
353
|
+
|
|
354
|
+
const TagsSchema = type('string[]');
|
|
355
|
+
const NumbersSchema = type('number[] >= 1'); // Array with at least 1 element
|
|
356
|
+
|
|
357
|
+
const tags = TagsSchema(['typescript', 'validation']);
|
|
358
|
+
const numbers = NumbersSchema([1, 2, 3]);
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Optional Fields
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { type } from '@ooneex/validation';
|
|
365
|
+
|
|
366
|
+
const UserSchema = type({
|
|
367
|
+
name: 'string',
|
|
368
|
+
email: 'string.email',
|
|
369
|
+
'phone?': 'string', // Optional field
|
|
370
|
+
'age?': 'number >= 0'
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const user = UserSchema({
|
|
374
|
+
name: 'John',
|
|
375
|
+
email: 'john@example.com'
|
|
376
|
+
// phone and age are optional
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Custom Validator with Translation
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
import { Validation, type } from '@ooneex/validation';
|
|
384
|
+
import type { LocaleType } from '@ooneex/translation';
|
|
385
|
+
|
|
386
|
+
class LocalizedEmailValidator extends Validation {
|
|
387
|
+
constructor(private readonly locale: LocaleType = 'en') {
|
|
388
|
+
super();
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
public getConstraint(): AssertType {
|
|
392
|
+
return type('string.email');
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
public getErrorMessage(): string | null {
|
|
396
|
+
const messages: Record<string, string> = {
|
|
397
|
+
en: 'Please enter a valid email address',
|
|
398
|
+
fr: 'Veuillez entrer une adresse email valide',
|
|
399
|
+
es: 'Por favor ingrese una dirección de correo válida'
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
return messages[this.locale] || messages.en;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Converting to JSON Schema
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import { type } from '@ooneex/validation';
|
|
411
|
+
|
|
412
|
+
const ProductSchema = type({
|
|
413
|
+
name: 'string',
|
|
414
|
+
price: 'number > 0',
|
|
415
|
+
category: "'electronics' | 'clothing' | 'food'"
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// Convert to JSON Schema for OpenAPI documentation
|
|
419
|
+
const jsonSchema = ProductSchema.toJsonSchema();
|
|
420
|
+
console.log(JSON.stringify(jsonSchema, null, 2));
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Integration with AI Output Validation
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
import { OpenAi } from '@ooneex/ai';
|
|
427
|
+
import { type } from '@ooneex/validation';
|
|
428
|
+
|
|
429
|
+
const ai = new OpenAi();
|
|
430
|
+
|
|
431
|
+
const ProductSchema = type({
|
|
432
|
+
name: 'string',
|
|
433
|
+
description: 'string',
|
|
434
|
+
price: 'number > 0'
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
const product = await ai.run('Generate a product', {
|
|
438
|
+
output: ProductSchema
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
// Product is guaranteed to match the schema
|
|
442
|
+
console.log(product.name, product.price);
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
## License
|
|
446
|
+
|
|
447
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
448
|
+
|
|
449
|
+
## Contributing
|
|
450
|
+
|
|
451
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
452
|
+
|
|
453
|
+
### Development Setup
|
|
454
|
+
|
|
455
|
+
1. Clone the repository
|
|
456
|
+
2. Install dependencies: `bun install`
|
|
457
|
+
3. Run tests: `bun run test`
|
|
458
|
+
4. Build the project: `bun run build`
|
|
459
|
+
|
|
460
|
+
### Guidelines
|
|
461
|
+
|
|
462
|
+
- Write tests for new features
|
|
463
|
+
- Follow the existing code style
|
|
464
|
+
- Update documentation for API changes
|
|
465
|
+
- Ensure all tests pass before submitting PR
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
Made with ❤️ by the Ooneex team
|
|
@@ -14,6 +14,10 @@ declare abstract class Validation implements IAssert {
|
|
|
14
14
|
abstract getErrorMessage(): string | null;
|
|
15
15
|
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
16
16
|
}
|
|
17
|
+
declare class AssertAppEnv extends Validation {
|
|
18
|
+
getConstraint(): AssertType;
|
|
19
|
+
getErrorMessage(): string | null;
|
|
20
|
+
}
|
|
17
21
|
declare class AssertChatQuery extends Validation {
|
|
18
22
|
getConstraint(): AssertType;
|
|
19
23
|
getErrorMessage(): string | null;
|
|
@@ -40,6 +44,10 @@ declare class AssertHexaColor extends Validation {
|
|
|
40
44
|
getErrorMessage(): string | null;
|
|
41
45
|
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
42
46
|
}
|
|
47
|
+
declare class AssertHostname extends Validation {
|
|
48
|
+
getConstraint(): AssertType;
|
|
49
|
+
getErrorMessage(): string | null;
|
|
50
|
+
}
|
|
43
51
|
declare class AssertId extends Validation {
|
|
44
52
|
getConstraint(): AssertType;
|
|
45
53
|
getErrorMessage(): string | null;
|
|
@@ -49,11 +57,19 @@ declare class AssertLastName extends Validation {
|
|
|
49
57
|
getConstraint(): AssertType;
|
|
50
58
|
getErrorMessage(): string | null;
|
|
51
59
|
}
|
|
60
|
+
declare class AssertLocale extends Validation {
|
|
61
|
+
getConstraint(): AssertType;
|
|
62
|
+
getErrorMessage(): string | null;
|
|
63
|
+
}
|
|
52
64
|
declare class AssertName extends Validation {
|
|
53
65
|
getConstraint(): AssertType;
|
|
54
66
|
getErrorMessage(): string | null;
|
|
55
67
|
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
56
68
|
}
|
|
69
|
+
declare class AssertPort extends Validation {
|
|
70
|
+
getConstraint(): AssertType;
|
|
71
|
+
getErrorMessage(): string | null;
|
|
72
|
+
}
|
|
57
73
|
declare class AssertUrl extends Validation {
|
|
58
74
|
getConstraint(): AssertType;
|
|
59
75
|
getErrorMessage(): string | null;
|
|
@@ -65,4 +81,4 @@ declare class AssertYoutubeUrl extends Validation {
|
|
|
65
81
|
getErrorMessage(): string | null;
|
|
66
82
|
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
67
83
|
}
|
|
68
|
-
export { AssertYoutubeUrl, AssertUrl, AssertName, AssertLastName, AssertId, AssertHexaColor, AssertFirstName, AssertEmail, AssertCurrency, AssertCountryCode, AssertChatQuery };
|
|
84
|
+
export { AssertYoutubeUrl, AssertUrl, AssertPort, AssertName, AssertLocale, AssertLastName, AssertId, AssertHostname, AssertHexaColor, AssertFirstName, AssertEmail, AssertCurrency, AssertCountryCode, AssertChatQuery, AssertAppEnv };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{a as e,c as r}from"../shared/chunk-bn4vhq39.js";import{Environment as I}from"@ooneex/app-env";var a=Object.values(I);class l extends r{getConstraint(){return e(`"${a.join('" | "')}"`)}getErrorMessage(){return`Must be a valid environment (${a.join(", ")})`}}var R=1,$=2000,M=[/<script[^>]*>.*?<\/script>/gi,/<\/?[a-zA-Z][^>]*>/g,/javascript:/gi,/data:/gi,/vbscript:/gi];class u extends r{getConstraint(){return e(`${R} <= string <= ${$}`)}getErrorMessage(){return"Chat query must be between 1 and 2000 characters and cannot contain HTML tags, scripts, or unsafe protocols"}validate(s,i){let o=super.validate(s,i);if(!o.isValid)return o;let t=s;for(let n of M)if(n.lastIndex=0,n.test(t))return{isValid:!1,message:this.getErrorMessage()||"Invalid chat query"};return{isValid:!0}}}class m extends r{getConstraint(){return e("2 <= string <= 2 & /^[A-Z]{2}$/")}getErrorMessage(){return"Country code must be a 2-character uppercase ISO 3166-1 alpha-2 code"}}import{CURRENCIES as _}from"@ooneex/currencies";var w=_.map((s)=>s.code);class c extends r{getConstraint(){return e(`"${w.join('" | "')}" & /^[A-Z]{3}$/`)}getErrorMessage(){return"Currency code must be a valid ISO 4217 currency code (3 uppercase letters)"}}class g extends r{getConstraint(){return e("string.email")}getErrorMessage(){return"Must be a valid email address"}}class f extends r{getConstraint(){return e("1 <= string <= 50 & /^[a-zA-Z\\s'-]+$/")}getErrorMessage(){return"First name must be between 1 and 50 characters and contain only letters, spaces, hyphens, and apostrophes"}}var D=/^#[0-9A-Fa-f]{3}$/,U=/^#[0-9A-Fa-f]{6}$/;class y extends r{getConstraint(){return e("string")}getErrorMessage(){return"Value must be a valid hexadecimal color (e.g., #fff, #ffffff, #A1B2C3)"}validate(s,i){let o=super.validate(s,i);if(!o.isValid)return o;let t=s,n=D.test(t),p=U.test(t);if(!n&&!p)return{isValid:!1,message:this.getErrorMessage()||"Invalid hexadecimal color"};return{isValid:!0}}}class A extends r{getConstraint(){return e(/^$|^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$|^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z]{2,})*$/)}getErrorMessage(){return"Must be a valid hostname or IP address"}}var Y=/^[0-9a-f]+$/,d=25;class b extends r{getConstraint(){return e(`${d} <= string <= ${d}`)}getErrorMessage(){return"ID must be exactly 25 characters long and contain only lowercase hexadecimal characters (0-9, a-f)"}validate(s,i){let o=super.validate(s,i);if(!o.isValid)return o;let t=s;if(!Y.test(t))return{isValid:!1,message:this.getErrorMessage()||"Invalid ID format"};return{isValid:!0}}}class T extends r{getConstraint(){return e("1 <= string <= 50 & /^[a-zA-Z\\s'-]+$/")}getErrorMessage(){return"Last name must be between 1 and 50 characters and contain only letters, spaces, hyphens, and apostrophes"}}import{locales as H}from"@ooneex/translation";class x extends r{getConstraint(){return e(`"${H.join('" | "')}"`)}getErrorMessage(){return"Locale must be a valid locale code"}}var O=1,L=50,Q=/^[a-zA-ZÀ-ÿĀ-žА-я\u4e00-\u9fff\s\-'0-9.]+$/;class C extends r{getConstraint(){return e(`${O} <= string <= ${L}`)}getErrorMessage(){return"Name must be between 1 and 50 characters and contain only letters, numbers, spaces, hyphens, apostrophes, and periods"}validate(s,i){let o=super.validate(s,i);if(!o.isValid)return o;let t=s;if(t.trim()!==t)return{isValid:!1,message:this.getErrorMessage()||"Invalid name format"};if(!Q.test(t))return{isValid:!1,message:this.getErrorMessage()||"Invalid name format"};if(t.includes(".")&&!t.match(/\.\s/))return{isValid:!1,message:this.getErrorMessage()||"Invalid name format"};return{isValid:!0}}}class v extends r{getConstraint(){return e("1 <= number.integer <= 65535")}getErrorMessage(){return"Must be a valid port number (1-65535)"}}var E=2083,F=/^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .~-]*)*\/?(\?[&a-z\d%_.~+=-]*)?(#[-a-z\d_]*)?$/i,Z=/^https?:\/\/(?:[-\w.])+(?::[0-9]+)?(?:\/(?:[\w/_.])*(?:\?(?:[\w&=%.])*)?(?:#(?:[\w.])*)?)?$/;class V extends r{getConstraint(){return e(`1 <= string <= ${E}`)}getErrorMessage(){return`URL must be between 1 and ${E} characters and follow a valid URL format (e.g., https://example.com, http://sub.domain.co.uk/path)`}validate(s,i){let o=super.validate(s,i);if(!o.isValid)return o;let t=s;if(t.match(/^(ftp|file|mailto|telnet|ssh|gopher):/i))return{isValid:!1,message:this.getErrorMessage()||"Invalid URL format"};if(t.includes("://")&&!t.match(/^https?:\/\//i))return{isValid:!1,message:this.getErrorMessage()||"Invalid URL format"};if(t.trim()!==t)return{isValid:!1,message:this.getErrorMessage()||"Invalid URL format"};if(t.includes("..")||t.startsWith(".")||t.includes("/.")||t.endsWith("."))return{isValid:!1,message:this.getErrorMessage()||"Invalid URL format"};if(!F.test(t))return{isValid:!1,message:this.getErrorMessage()||"Invalid URL format"};return{isValid:!0}}validateStrict(s){let i=super.validate(s);if(!i.isValid)return i;let o=s;if(!Z.test(o))return{isValid:!1,message:"URL must include protocol (http:// or https://) and follow strict URL format"};return{isValid:!0}}}var j=[/^https?:\/\/(www\.)?youtube\.com\/watch\?v=[A-Za-z0-9_-]+$/,/^https?:\/\/youtu\.be\/[A-Za-z0-9_-]+$/];class h extends r{getConstraint(){return e("string")}getErrorMessage(){return"Must be a valid YouTube URL (e.g., https://youtube.com/watch?v=dQw4w9WgXcQ or https://youtu.be/dQw4w9WgXcQ)"}validate(s,i){let o=super.validate(s,i);if(!o.isValid)return o;let t=s;if(!j.some((p)=>p.test(t)))return{isValid:!1,message:this.getErrorMessage()||"Invalid YouTube URL"};return{isValid:!0}}}export{h as AssertYoutubeUrl,V as AssertUrl,v as AssertPort,C as AssertName,x as AssertLocale,T as AssertLastName,b as AssertId,A as AssertHostname,y as AssertHexaColor,f as AssertFirstName,g as AssertEmail,c as AssertCurrency,m as AssertCountryCode,u as AssertChatQuery,l as AssertAppEnv};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=096598A61CDA96E264756E2164756E21
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["src/
|
|
3
|
+
"sources": ["src/constraints/AssertAppEnv.ts", "src/constraints/AssertChatQuery.ts", "src/constraints/AssertCountryCode.ts", "src/constraints/AssertCurrency.ts", "src/constraints/AssertEmail.ts", "src/constraints/AssertFirstName.ts", "src/constraints/AssertHexaColor.ts", "src/constraints/AssertHostname.ts", "src/constraints/AssertId.ts", "src/constraints/AssertLastName.ts", "src/constraints/AssertLocale.ts", "src/constraints/AssertName.ts", "src/constraints/AssertPort.ts", "src/constraints/AssertUrl.ts", "src/constraints/AssertYoutubeUrl.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import
|
|
6
|
-
"import { type } from \"arktype\";\nimport type { AssertType, IAssert, ValidationResultType } from \"./types\";\n\nexport abstract class Validation implements IAssert {\n public abstract getConstraint(): AssertType;\n public abstract getErrorMessage(): string | null;\n\n public validate(data: unknown, constraint?: AssertType): ValidationResultType {\n constraint = constraint || this.getConstraint();\n\n const out = constraint(data);\n\n if (out instanceof type.errors) {\n return {\n isValid: false,\n message: this.getErrorMessage() || out.summary,\n };\n }\n\n return {\n isValid: true,\n };\n }\n}\n",
|
|
5
|
+
"import { Environment } from \"@ooneex/app-env\";\nimport type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst environments = Object.values(Environment);\n\nexport class AssertAppEnv extends Validation {\n public getConstraint(): AssertType {\n return Assert(`\"${environments.join('\" | \"')}\"`);\n }\n\n public getErrorMessage(): string | null {\n return `Must be a valid environment (${environments.join(\", \")})`;\n }\n}\n",
|
|
7
6
|
"import type { AssertType, ValidationResultType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst CHAT_QUERY_MIN_LENGTH = 1;\nconst CHAT_QUERY_MAX_LENGTH = 2000;\nconst CHAT_QUERY_FORBIDDEN_PATTERNS = [\n /<script[^>]*>.*?<\\/script>/gi,\n /<\\/?[a-zA-Z][^>]*>/g,\n /javascript:/gi,\n /data:/gi,\n /vbscript:/gi,\n];\n\nexport class AssertChatQuery extends Validation {\n public getConstraint(): AssertType {\n return Assert(`${CHAT_QUERY_MIN_LENGTH} <= string <= ${CHAT_QUERY_MAX_LENGTH}`);\n }\n\n public getErrorMessage(): string | null {\n return \"Chat query must be between 1 and 2000 characters and cannot contain HTML tags, scripts, or unsafe protocols\";\n }\n\n public override validate(data: unknown, constraint?: AssertType): ValidationResultType {\n const basicValidation = super.validate(data, constraint);\n if (!basicValidation.isValid) {\n return basicValidation;\n }\n\n const query = data as string;\n\n for (const pattern of CHAT_QUERY_FORBIDDEN_PATTERNS) {\n pattern.lastIndex = 0;\n if (pattern.test(query)) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid chat query\",\n };\n }\n }\n\n return {\n isValid: true,\n };\n }\n}\n",
|
|
8
7
|
"import type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nexport class AssertCountryCode extends Validation {\n public getConstraint(): AssertType {\n return Assert(\"2 <= string <= 2 & /^[A-Z]{2}$/\");\n }\n\n public getErrorMessage(): string | null {\n return \"Country code must be a 2-character uppercase ISO 3166-1 alpha-2 code\";\n }\n}\n",
|
|
9
8
|
"import { CURRENCIES } from \"@ooneex/currencies\";\nimport type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst VALID_CURRENCY_CODES = CURRENCIES.map((currency) => currency.code);\n\nexport class AssertCurrency extends Validation {\n public getConstraint(): AssertType {\n return Assert(`\"${VALID_CURRENCY_CODES.join('\" | \"')}\" & /^[A-Z]{3}$/`);\n }\n\n public getErrorMessage(): string | null {\n return \"Currency code must be a valid ISO 4217 currency code (3 uppercase letters)\";\n }\n}\n",
|
|
10
9
|
"import type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nexport class AssertEmail extends Validation {\n public getConstraint(): AssertType {\n return Assert(\"string.email\");\n }\n\n public getErrorMessage(): string | null {\n return \"Must be a valid email address\";\n }\n}\n",
|
|
11
10
|
"import type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nexport class AssertFirstName extends Validation {\n public getConstraint(): AssertType {\n return Assert(\"1 <= string <= 50 & /^[a-zA-Z\\\\s'-]+$/\");\n }\n\n public getErrorMessage(): string | null {\n return \"First name must be between 1 and 50 characters and contain only letters, spaces, hyphens, and apostrophes\";\n }\n}\n",
|
|
12
11
|
"import type { AssertType, ValidationResultType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst HEXA_COLOR_3_DIGIT_REGEX = /^#[0-9A-Fa-f]{3}$/;\nconst HEXA_COLOR_6_DIGIT_REGEX = /^#[0-9A-Fa-f]{6}$/;\n\nexport class AssertHexaColor extends Validation {\n public getConstraint(): AssertType {\n return Assert(\"string\");\n }\n\n public getErrorMessage(): string | null {\n return \"Value must be a valid hexadecimal color (e.g., #fff, #ffffff, #A1B2C3)\";\n }\n\n public override validate(data: unknown, constraint?: AssertType): ValidationResultType {\n const basicValidation = super.validate(data, constraint);\n if (!basicValidation.isValid) {\n return basicValidation;\n }\n\n const color = data as string;\n\n const is3DigitHex = HEXA_COLOR_3_DIGIT_REGEX.test(color);\n const is6DigitHex = HEXA_COLOR_6_DIGIT_REGEX.test(color);\n\n if (!is3DigitHex && !is6DigitHex) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid hexadecimal color\",\n };\n }\n\n return {\n isValid: true,\n };\n }\n}\n",
|
|
12
|
+
"import type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nexport class AssertHostname extends Validation {\n public getConstraint(): AssertType {\n // Matches IP addresses (0.0.0.0, 127.0.0.1, etc.) or hostnames (localhost, example.com, etc.)\n // Also allows empty string for optional hostname\n return Assert(\n /^$|^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$|^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z]{2,})*$/,\n );\n }\n\n public getErrorMessage(): string | null {\n return \"Must be a valid hostname or IP address\";\n }\n}\n",
|
|
13
13
|
"import type { AssertType, ValidationResultType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst ID_REGEX = /^[0-9a-f]+$/;\nconst DEFAULT_ID_LENGTH = 25;\n\nexport class AssertId extends Validation {\n public getConstraint(): AssertType {\n return Assert(`${DEFAULT_ID_LENGTH} <= string <= ${DEFAULT_ID_LENGTH}`);\n }\n\n public getErrorMessage(): string | null {\n return \"ID must be exactly 25 characters long and contain only lowercase hexadecimal characters (0-9, a-f)\";\n }\n\n public override validate(data: unknown, constraint?: AssertType): ValidationResultType {\n const basicValidation = super.validate(data, constraint);\n if (!basicValidation.isValid) {\n return basicValidation;\n }\n\n const id = data as string;\n\n if (!ID_REGEX.test(id)) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid ID format\",\n };\n }\n\n return {\n isValid: true,\n };\n }\n}\n",
|
|
14
14
|
"import type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nexport class AssertLastName extends Validation {\n public getConstraint(): AssertType {\n return Assert(\"1 <= string <= 50 & /^[a-zA-Z\\\\s'-]+$/\");\n }\n\n public getErrorMessage(): string | null {\n return \"Last name must be between 1 and 50 characters and contain only letters, spaces, hyphens, and apostrophes\";\n }\n}\n",
|
|
15
|
+
"import { locales } from \"@ooneex/translation\";\nimport type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nexport class AssertLocale extends Validation {\n public getConstraint(): AssertType {\n return Assert(`\"${locales.join('\" | \"')}\"`);\n }\n\n public getErrorMessage(): string | null {\n return \"Locale must be a valid locale code\";\n }\n}\n",
|
|
15
16
|
"import type { AssertType, ValidationResultType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst NAME_MIN_LENGTH = 1;\nconst NAME_MAX_LENGTH = 50;\nconst NAME_REGEX = /^[a-zA-ZÀ-ÿĀ-žА-я\\u4e00-\\u9fff\\s\\-'0-9.]+$/;\n\nexport class AssertName extends Validation {\n public getConstraint(): AssertType {\n return Assert(`${NAME_MIN_LENGTH} <= string <= ${NAME_MAX_LENGTH}`);\n }\n\n public getErrorMessage(): string | null {\n return \"Name must be between 1 and 50 characters and contain only letters, numbers, spaces, hyphens, apostrophes, and periods\";\n }\n\n public override validate(data: unknown, constraint?: AssertType): ValidationResultType {\n const basicValidation = super.validate(data, constraint);\n if (!basicValidation.isValid) {\n return basicValidation;\n }\n\n const name = data as string;\n\n // Check for leading or trailing whitespace\n if (name.trim() !== name) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid name format\",\n };\n }\n\n if (!NAME_REGEX.test(name)) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid name format\",\n };\n }\n\n // Check for valid period usage (only allowed when followed by space like \"St. John\")\n if (name.includes(\".\") && !name.match(/\\.\\s/)) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid name format\",\n };\n }\n\n return {\n isValid: true,\n };\n }\n}\n",
|
|
17
|
+
"import type { AssertType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nexport class AssertPort extends Validation {\n public getConstraint(): AssertType {\n return Assert(\"1 <= number.integer <= 65535\");\n }\n\n public getErrorMessage(): string | null {\n return \"Must be a valid port number (1-65535)\";\n }\n}\n",
|
|
16
18
|
"import type { AssertType, ValidationResultType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst URL_MAX_LENGTH = 2083;\nconst URL_REGEX = /^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .~-]*)*\\/?(\\?[&a-z\\d%_.~+=-]*)?(#[-a-z\\d_]*)?$/i;\n\nconst STRICT_URL_REGEX = /^https?:\\/\\/(?:[-\\w.])+(?::[0-9]+)?(?:\\/(?:[\\w/_.])*(?:\\?(?:[\\w&=%.])*)?(?:#(?:[\\w.])*)?)?$/;\n\nexport class AssertUrl extends Validation {\n public getConstraint(): AssertType {\n return Assert(`1 <= string <= ${URL_MAX_LENGTH}`);\n }\n\n public getErrorMessage(): string | null {\n return `URL must be between 1 and ${URL_MAX_LENGTH} characters and follow a valid URL format (e.g., https://example.com, http://sub.domain.co.uk/path)`;\n }\n\n public override validate(data: unknown, constraint?: AssertType): ValidationResultType {\n const basicValidation = super.validate(data, constraint);\n if (!basicValidation.isValid) {\n return basicValidation;\n }\n\n const url = data as string;\n\n // Reject specific non-http/https protocols first\n if (url.match(/^(ftp|file|mailto|telnet|ssh|gopher):/i)) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid URL format\",\n };\n }\n\n // Reject malformed protocols\n if (url.includes(\"://\") && !url.match(/^https?:\\/\\//i)) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid URL format\",\n };\n }\n\n // Check for whitespace at start or end\n if (url.trim() !== url) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid URL format\",\n };\n }\n\n // Check for invalid domain patterns\n if (url.includes(\"..\") || url.startsWith(\".\") || url.includes(\"/.\") || url.endsWith(\".\")) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid URL format\",\n };\n }\n\n if (!URL_REGEX.test(url)) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid URL format\",\n };\n }\n\n return {\n isValid: true,\n };\n }\n\n public validateStrict(data: unknown): ValidationResultType {\n const basicValidation = super.validate(data);\n if (!basicValidation.isValid) {\n return basicValidation;\n }\n\n const url = data as string;\n\n if (!STRICT_URL_REGEX.test(url)) {\n return {\n isValid: false,\n message: \"URL must include protocol (http:// or https://) and follow strict URL format\",\n };\n }\n\n return {\n isValid: true,\n };\n }\n}\n",
|
|
17
19
|
"import type { AssertType, ValidationResultType } from \"../types\";\nimport { Assert } from \"../utils\";\nimport { Validation } from \"../Validation\";\n\nconst YOUTUBE_URL_PATTERNS = [\n /^https?:\\/\\/(www\\.)?youtube\\.com\\/watch\\?v=[A-Za-z0-9_-]+$/,\n /^https?:\\/\\/youtu\\.be\\/[A-Za-z0-9_-]+$/,\n];\n\nexport class AssertYoutubeUrl extends Validation {\n public getConstraint(): AssertType {\n return Assert(\"string\");\n }\n\n public getErrorMessage(): string | null {\n return \"Must be a valid YouTube URL (e.g., https://youtube.com/watch?v=dQw4w9WgXcQ or https://youtu.be/dQw4w9WgXcQ)\";\n }\n\n public override validate(data: unknown, constraint?: AssertType): ValidationResultType {\n const basicValidation = super.validate(data, constraint);\n if (!basicValidation.isValid) {\n return basicValidation;\n }\n\n const url = data as string;\n const isValidYouTubeUrl = YOUTUBE_URL_PATTERNS.some((pattern) => pattern.test(url));\n\n if (!isValidYouTubeUrl) {\n return {\n isValid: false,\n message: this.getErrorMessage() || \"Invalid YouTube URL\",\n };\n }\n\n return {\n isValid: true,\n };\n }\n}\n"
|
|
18
20
|
],
|
|
19
|
-
"mappings": "
|
|
20
|
-
"debugId": "
|
|
21
|
+
"mappings": "uDAAA,sBAAS,wBAKT,IAAM,EAAe,OAAO,OAAO,CAAW,EAEvC,MAAM,UAAqB,CAAW,CACpC,aAAa,EAAe,CACjC,OAAO,EAAO,IAAI,EAAa,KAAK,OAAO,IAAI,EAG1C,eAAe,EAAkB,CACtC,MAAO,gCAAgC,EAAa,KAAK,IAAI,KAEjE,CCXA,IAAM,EAAwB,EACxB,EAAwB,KACxB,EAAgC,CACpC,+BACA,sBACA,gBACA,UACA,aACF,EAEO,MAAM,UAAwB,CAAW,CACvC,aAAa,EAAe,CACjC,OAAO,EAAO,GAAG,kBAAsC,GAAuB,EAGzE,eAAe,EAAkB,CACtC,MAAO,8GAGO,QAAQ,CAAC,EAAe,EAA+C,CACrF,IAAM,EAAkB,MAAM,SAAS,EAAM,CAAU,EACvD,GAAI,CAAC,EAAgB,QACnB,OAAO,EAGT,IAAM,EAAQ,EAEd,QAAW,KAAW,EAEpB,GADA,EAAQ,UAAY,EAChB,EAAQ,KAAK,CAAK,EACpB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,oBACrC,EAIJ,MAAO,CACL,QAAS,EACX,EAEJ,CCzCO,MAAM,UAA0B,CAAW,CACzC,aAAa,EAAe,CACjC,OAAO,EAAO,iCAAiC,EAG1C,eAAe,EAAkB,CACtC,MAAO,uEAEX,CCZA,qBAAS,2BAKT,IAAM,EAAuB,EAAW,IAAI,CAAC,IAAa,EAAS,IAAI,EAEhE,MAAM,UAAuB,CAAW,CACtC,aAAa,EAAe,CACjC,OAAO,EAAO,IAAI,EAAqB,KAAK,OAAO,mBAAmB,EAGjE,eAAe,EAAkB,CACtC,MAAO,6EAEX,CCXO,MAAM,UAAoB,CAAW,CACnC,aAAa,EAAe,CACjC,OAAO,EAAO,cAAc,EAGvB,eAAe,EAAkB,CACtC,MAAO,gCAEX,CCRO,MAAM,UAAwB,CAAW,CACvC,aAAa,EAAe,CACjC,OAAO,EAAO,wCAAwC,EAGjD,eAAe,EAAkB,CACtC,MAAO,4GAEX,CCRA,IAAM,EAA2B,oBAC3B,EAA2B,oBAE1B,MAAM,UAAwB,CAAW,CACvC,aAAa,EAAe,CACjC,OAAO,EAAO,QAAQ,EAGjB,eAAe,EAAkB,CACtC,MAAO,yEAGO,QAAQ,CAAC,EAAe,EAA+C,CACrF,IAAM,EAAkB,MAAM,SAAS,EAAM,CAAU,EACvD,GAAI,CAAC,EAAgB,QACnB,OAAO,EAGT,IAAM,EAAQ,EAER,EAAc,EAAyB,KAAK,CAAK,EACjD,EAAc,EAAyB,KAAK,CAAK,EAEvD,GAAI,CAAC,GAAe,CAAC,EACnB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,2BACrC,EAGF,MAAO,CACL,QAAS,EACX,EAEJ,CClCO,MAAM,UAAuB,CAAW,CACtC,aAAa,EAAe,CAGjC,OAAO,EACL,iJACF,EAGK,eAAe,EAAkB,CACtC,MAAO,yCAEX,CCZA,IAAM,EAAW,cACX,EAAoB,GAEnB,MAAM,UAAiB,CAAW,CAChC,aAAa,EAAe,CACjC,OAAO,EAAO,GAAG,kBAAkC,GAAmB,EAGjE,eAAe,EAAkB,CACtC,MAAO,qGAGO,QAAQ,CAAC,EAAe,EAA+C,CACrF,IAAM,EAAkB,MAAM,SAAS,EAAM,CAAU,EACvD,GAAI,CAAC,EAAgB,QACnB,OAAO,EAGT,IAAM,EAAK,EAEX,GAAI,CAAC,EAAS,KAAK,CAAE,EACnB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,mBACrC,EAGF,MAAO,CACL,QAAS,EACX,EAEJ,CC/BO,MAAM,UAAuB,CAAW,CACtC,aAAa,EAAe,CACjC,OAAO,EAAO,wCAAwC,EAGjD,eAAe,EAAkB,CACtC,MAAO,2GAEX,CCZA,kBAAS,4BAKF,MAAM,UAAqB,CAAW,CACpC,aAAa,EAAe,CACjC,OAAO,EAAO,IAAI,EAAQ,KAAK,OAAO,IAAI,EAGrC,eAAe,EAAkB,CACtC,MAAO,qCAEX,CCTA,IAAM,EAAkB,EAClB,EAAkB,GAClB,EAAa,6CAEZ,MAAM,UAAmB,CAAW,CAClC,aAAa,EAAe,CACjC,OAAO,EAAO,GAAG,kBAAgC,GAAiB,EAG7D,eAAe,EAAkB,CACtC,MAAO,wHAGO,QAAQ,CAAC,EAAe,EAA+C,CACrF,IAAM,EAAkB,MAAM,SAAS,EAAM,CAAU,EACvD,GAAI,CAAC,EAAgB,QACnB,OAAO,EAGT,IAAM,EAAO,EAGb,GAAI,EAAK,KAAK,IAAM,EAClB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,qBACrC,EAGF,GAAI,CAAC,EAAW,KAAK,CAAI,EACvB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,qBACrC,EAIF,GAAI,EAAK,SAAS,GAAG,GAAK,CAAC,EAAK,MAAM,MAAM,EAC1C,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,qBACrC,EAGF,MAAO,CACL,QAAS,EACX,EAEJ,CChDO,MAAM,UAAmB,CAAW,CAClC,aAAa,EAAe,CACjC,OAAO,EAAO,8BAA8B,EAGvC,eAAe,EAAkB,CACtC,MAAO,wCAEX,CCRA,IAAM,EAAiB,KACjB,EAAY,kGAEZ,EAAmB,8FAElB,MAAM,UAAkB,CAAW,CACjC,aAAa,EAAe,CACjC,OAAO,EAAO,kBAAkB,GAAgB,EAG3C,eAAe,EAAkB,CACtC,MAAO,6BAA6B,uGAGtB,QAAQ,CAAC,EAAe,EAA+C,CACrF,IAAM,EAAkB,MAAM,SAAS,EAAM,CAAU,EACvD,GAAI,CAAC,EAAgB,QACnB,OAAO,EAGT,IAAM,EAAM,EAGZ,GAAI,EAAI,MAAM,wCAAwC,EACpD,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,oBACrC,EAIF,GAAI,EAAI,SAAS,KAAK,GAAK,CAAC,EAAI,MAAM,eAAe,EACnD,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,oBACrC,EAIF,GAAI,EAAI,KAAK,IAAM,EACjB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,oBACrC,EAIF,GAAI,EAAI,SAAS,IAAI,GAAK,EAAI,WAAW,GAAG,GAAK,EAAI,SAAS,IAAI,GAAK,EAAI,SAAS,GAAG,EACrF,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,oBACrC,EAGF,GAAI,CAAC,EAAU,KAAK,CAAG,EACrB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,oBACrC,EAGF,MAAO,CACL,QAAS,EACX,EAGK,cAAc,CAAC,EAAqC,CACzD,IAAM,EAAkB,MAAM,SAAS,CAAI,EAC3C,GAAI,CAAC,EAAgB,QACnB,OAAO,EAGT,IAAM,EAAM,EAEZ,GAAI,CAAC,EAAiB,KAAK,CAAG,EAC5B,MAAO,CACL,QAAS,GACT,QAAS,8EACX,EAGF,MAAO,CACL,QAAS,EACX,EAEJ,CCrFA,IAAM,EAAuB,CAC3B,6DACA,wCACF,EAEO,MAAM,UAAyB,CAAW,CACxC,aAAa,EAAe,CACjC,OAAO,EAAO,QAAQ,EAGjB,eAAe,EAAkB,CACtC,MAAO,8GAGO,QAAQ,CAAC,EAAe,EAA+C,CACrF,IAAM,EAAkB,MAAM,SAAS,EAAM,CAAU,EACvD,GAAI,CAAC,EAAgB,QACnB,OAAO,EAGT,IAAM,EAAM,EAGZ,GAAI,CAFsB,EAAqB,KAAK,CAAC,IAAY,EAAQ,KAAK,CAAG,CAAC,EAGhF,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,qBACrC,EAGF,MAAO,CACL,QAAS,EACX,EAEJ",
|
|
22
|
+
"debugId": "096598A61CDA96E264756E2164756E21",
|
|
21
23
|
"names": []
|
|
22
24
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from "arktype";
|
|
1
2
|
import * as A from "arktype";
|
|
2
3
|
type ValidationClassType = new (...args: any[]) => IAssert;
|
|
3
4
|
type AssertType = A.Type;
|
|
@@ -10,63 +11,15 @@ type ValidationResultType = {
|
|
|
10
11
|
isValid: boolean;
|
|
11
12
|
message?: string;
|
|
12
13
|
};
|
|
14
|
+
import { TypeParser } from "arktype/internal/type.ts";
|
|
15
|
+
declare const Assert: TypeParser<{}>;
|
|
16
|
+
/**
|
|
17
|
+
* Convert a JSON Schema type to TypeScript type string
|
|
18
|
+
*/
|
|
19
|
+
declare const jsonSchemaToTypeString: (schema: unknown) => string;
|
|
13
20
|
declare abstract class Validation implements IAssert {
|
|
14
21
|
abstract getConstraint(): AssertType;
|
|
15
22
|
abstract getErrorMessage(): string | null;
|
|
16
23
|
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
17
24
|
}
|
|
18
|
-
|
|
19
|
-
getConstraint(): AssertType;
|
|
20
|
-
getErrorMessage(): string | null;
|
|
21
|
-
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
22
|
-
}
|
|
23
|
-
declare class AssertCountryCode extends Validation {
|
|
24
|
-
getConstraint(): AssertType;
|
|
25
|
-
getErrorMessage(): string | null;
|
|
26
|
-
}
|
|
27
|
-
declare class AssertCurrency extends Validation {
|
|
28
|
-
getConstraint(): AssertType;
|
|
29
|
-
getErrorMessage(): string | null;
|
|
30
|
-
}
|
|
31
|
-
declare class AssertEmail extends Validation {
|
|
32
|
-
getConstraint(): AssertType;
|
|
33
|
-
getErrorMessage(): string | null;
|
|
34
|
-
}
|
|
35
|
-
declare class AssertFirstName extends Validation {
|
|
36
|
-
getConstraint(): AssertType;
|
|
37
|
-
getErrorMessage(): string | null;
|
|
38
|
-
}
|
|
39
|
-
declare class AssertHexaColor extends Validation {
|
|
40
|
-
getConstraint(): AssertType;
|
|
41
|
-
getErrorMessage(): string | null;
|
|
42
|
-
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
43
|
-
}
|
|
44
|
-
declare class AssertId extends Validation {
|
|
45
|
-
getConstraint(): AssertType;
|
|
46
|
-
getErrorMessage(): string | null;
|
|
47
|
-
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
48
|
-
}
|
|
49
|
-
declare class AssertLastName extends Validation {
|
|
50
|
-
getConstraint(): AssertType;
|
|
51
|
-
getErrorMessage(): string | null;
|
|
52
|
-
}
|
|
53
|
-
declare class AssertName extends Validation {
|
|
54
|
-
getConstraint(): AssertType;
|
|
55
|
-
getErrorMessage(): string | null;
|
|
56
|
-
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
57
|
-
}
|
|
58
|
-
declare class AssertUrl extends Validation {
|
|
59
|
-
getConstraint(): AssertType;
|
|
60
|
-
getErrorMessage(): string | null;
|
|
61
|
-
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
62
|
-
validateStrict(data: unknown): ValidationResultType;
|
|
63
|
-
}
|
|
64
|
-
declare class AssertYoutubeUrl extends Validation {
|
|
65
|
-
getConstraint(): AssertType;
|
|
66
|
-
getErrorMessage(): string | null;
|
|
67
|
-
validate(data: unknown, constraint?: AssertType): ValidationResultType;
|
|
68
|
-
}
|
|
69
|
-
export * from "arktype";
|
|
70
|
-
import { TypeParser } from "arktype/internal/type.ts";
|
|
71
|
-
declare const Assert: TypeParser<{}>;
|
|
72
|
-
export { ValidationResultType, ValidationClassType, Validation, IAssert, AssertYoutubeUrl, AssertUrl, AssertType, AssertName, AssertLastName, AssertId, AssertHexaColor, AssertFirstName, AssertEmail, AssertCurrency, AssertCountryCode, AssertChatQuery, Assert };
|
|
25
|
+
export { jsonSchemaToTypeString, ValidationResultType, ValidationClassType, Validation, IAssert, AssertType, Assert };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as r,b as o,c as e}from"./shared/chunk-bn4vhq39.js";export*from"arktype";export{o as jsonSchemaToTypeString,e as Validation,r as Assert};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=536857D002B4C57664756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export * from \"arktype\";\nexport * from \"./
|
|
5
|
+
"export * from \"arktype\";\nexport * from \"./types\";\nexport { Assert, jsonSchemaToTypeString } from \"./utils\";\nexport { Validation } from \"./Validation\";\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "6DAAA",
|
|
8
|
+
"debugId": "536857D002B4C57664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import*as V from"arktype";var p=V.type,l=(i)=>{if(!i||typeof i!=="object")return"unknown";let t=i;if(t.type)switch(t.type){case"string":return"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"null":return"null";case"array":if(t.items)return`${l(t.items)}[]`;return"unknown[]";case"object":if(t.properties&&typeof t.properties==="object"){let r=[],u=Array.isArray(t.required)?t.required:[];for(let[A,f]of Object.entries(t.properties)){let g=u.includes(A),d=l(f);r.push(`${A}${g?"":"?"}: ${d}`)}return`{ ${r.join("; ")} }`}return"Record<string, unknown>"}if(t.anyOf||t.oneOf){let r=t.anyOf||t.oneOf;if(Array.isArray(r))return r.map((u)=>l(u)).join(" | ")}if(t.allOf&&Array.isArray(t.allOf))return t.allOf.map((r)=>l(r)).join(" & ");return"unknown"};import{type as n}from"arktype";class o{validate(i,t){t=t||this.getConstraint();let r=t(i);if(r instanceof n.errors)return{isValid:!1,message:this.getErrorMessage()||r.summary};return{isValid:!0}}}
|
|
2
|
+
export{p as a,l as b,o as c};
|
|
3
|
+
|
|
4
|
+
//# debugId=74A74E5B17B5E66964756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/utils.ts", "src/Validation.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import * as A from \"arktype\";\nimport type { TypeParser } from \"arktype/internal/type.ts\";\n\n// biome-ignore lint/complexity/noBannedTypes: trust me\nexport const Assert: TypeParser<{}> = A.type;\n\n/**\n * Convert a JSON Schema type to TypeScript type string\n */\nexport const jsonSchemaToTypeString = (schema: unknown): string => {\n if (!schema || typeof schema !== \"object\") return \"unknown\";\n\n const schemaObj = schema as Record<string, unknown>;\n\n // Handle type property\n if (schemaObj.type) {\n switch (schemaObj.type) {\n case \"string\":\n return \"string\";\n case \"number\":\n case \"integer\":\n return \"number\";\n case \"boolean\":\n return \"boolean\";\n case \"null\":\n return \"null\";\n case \"array\":\n if (schemaObj.items) {\n return `${jsonSchemaToTypeString(schemaObj.items)}[]`;\n }\n return \"unknown[]\";\n case \"object\":\n if (schemaObj.properties && typeof schemaObj.properties === \"object\") {\n const props: string[] = [];\n const required = Array.isArray(schemaObj.required) ? schemaObj.required : [];\n\n for (const [key, value] of Object.entries(schemaObj.properties)) {\n const isRequired = required.includes(key);\n const propType = jsonSchemaToTypeString(value);\n props.push(`${key}${isRequired ? \"\" : \"?\"}: ${propType}`);\n }\n\n return `{ ${props.join(\"; \")} }`;\n }\n return \"Record<string, unknown>\";\n }\n }\n\n // Handle anyOf/oneOf (union types)\n if (schemaObj.anyOf || schemaObj.oneOf) {\n const schemas = schemaObj.anyOf || schemaObj.oneOf;\n if (Array.isArray(schemas)) {\n return schemas.map((s: unknown) => jsonSchemaToTypeString(s)).join(\" | \");\n }\n }\n\n // Handle allOf (intersection types)\n if (schemaObj.allOf && Array.isArray(schemaObj.allOf)) {\n return schemaObj.allOf.map((s: unknown) => jsonSchemaToTypeString(s)).join(\" & \");\n }\n\n return \"unknown\";\n};\n",
|
|
6
|
+
"import { type } from \"arktype\";\nimport type { AssertType, IAssert, ValidationResultType } from \"./types\";\n\nexport abstract class Validation implements IAssert {\n public abstract getConstraint(): AssertType;\n public abstract getErrorMessage(): string | null;\n\n public validate(data: unknown, constraint?: AssertType): ValidationResultType {\n constraint = constraint || this.getConstraint();\n\n const out = constraint(data);\n\n if (out instanceof type.errors) {\n return {\n isValid: false,\n message: this.getErrorMessage() || out.summary,\n };\n }\n\n return {\n isValid: true,\n };\n }\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "AAAA,0BAIO,IAAM,EAA2B,OAK3B,EAAyB,CAAC,IAA4B,CACjE,GAAI,CAAC,GAAU,OAAO,IAAW,SAAU,MAAO,UAElD,IAAM,EAAY,EAGlB,GAAI,EAAU,KACZ,OAAQ,EAAU,UACX,SACH,MAAO,aACJ,aACA,UACH,MAAO,aACJ,UACH,MAAO,cACJ,OACH,MAAO,WACJ,QACH,GAAI,EAAU,MACZ,MAAO,GAAG,EAAuB,EAAU,KAAK,MAElD,MAAO,gBACJ,SACH,GAAI,EAAU,YAAc,OAAO,EAAU,aAAe,SAAU,CACpE,IAAM,EAAkB,CAAC,EACnB,EAAW,MAAM,QAAQ,EAAU,QAAQ,EAAI,EAAU,SAAW,CAAC,EAE3E,QAAY,EAAK,KAAU,OAAO,QAAQ,EAAU,UAAU,EAAG,CAC/D,IAAM,EAAa,EAAS,SAAS,CAAG,EAClC,EAAW,EAAuB,CAAK,EAC7C,EAAM,KAAK,GAAG,IAAM,EAAa,GAAK,QAAQ,GAAU,EAG1D,MAAO,KAAK,EAAM,KAAK,IAAI,MAE7B,MAAO,0BAKb,GAAI,EAAU,OAAS,EAAU,MAAO,CACtC,IAAM,EAAU,EAAU,OAAS,EAAU,MAC7C,GAAI,MAAM,QAAQ,CAAO,EACvB,OAAO,EAAQ,IAAI,CAAC,IAAe,EAAuB,CAAC,CAAC,EAAE,KAAK,KAAK,EAK5E,GAAI,EAAU,OAAS,MAAM,QAAQ,EAAU,KAAK,EAClD,OAAO,EAAU,MAAM,IAAI,CAAC,IAAe,EAAuB,CAAC,CAAC,EAAE,KAAK,KAAK,EAGlF,MAAO,WC7DT,eAAS,gBAGF,MAAe,CAA8B,CAI3C,QAAQ,CAAC,EAAe,EAA+C,CAC5E,EAAa,GAAc,KAAK,cAAc,EAE9C,IAAM,EAAM,EAAW,CAAI,EAE3B,GAAI,aAAe,EAAK,OACtB,MAAO,CACL,QAAS,GACT,QAAS,KAAK,gBAAgB,GAAK,EAAI,OACzC,EAGF,MAAO,CACL,QAAS,EACX,EAEJ",
|
|
9
|
+
"debugId": "74A74E5B17B5E66964756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/validation",
|
|
3
|
-
"description": "",
|
|
4
|
-
"version": "0.0.
|
|
3
|
+
"description": "Type-safe validation framework powered by ArkType with built-in constraints and JSON schema support",
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -31,14 +31,22 @@
|
|
|
31
31
|
"test": "bun test tests",
|
|
32
32
|
"build": "bunup",
|
|
33
33
|
"lint": "tsgo --noEmit && bunx biome lint",
|
|
34
|
-
"publish
|
|
35
|
-
"publish:pack": "bun pm pack --destination ./dist",
|
|
36
|
-
"publish:dry": "bun publish --dry-run"
|
|
34
|
+
"publish": "bun publish --access public || true"
|
|
37
35
|
},
|
|
38
|
-
"devDependencies": {},
|
|
39
|
-
"peerDependencies": {},
|
|
40
36
|
"dependencies": {
|
|
37
|
+
"@ooneex/app-env": "0.0.1",
|
|
41
38
|
"@ooneex/currencies": "0.0.1",
|
|
39
|
+
"@ooneex/translation": "0.0.1",
|
|
42
40
|
"arktype": "^2.1.27"
|
|
43
|
-
}
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"arktype",
|
|
44
|
+
"bun",
|
|
45
|
+
"constraints",
|
|
46
|
+
"ooneex",
|
|
47
|
+
"schema",
|
|
48
|
+
"typescript",
|
|
49
|
+
"validation",
|
|
50
|
+
"validator"
|
|
51
|
+
]
|
|
44
52
|
}
|