valrs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # valrs
2
+
3
+ [![npm](https://img.shields.io/npm/v/valrs)](https://www.npmjs.com/package/valrs)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](../../LICENSE)
5
+
6
+ High-performance schema validation powered by Rust and WebAssembly. Implements the [Standard Schema](https://standardschema.dev/) specification.
7
+
8
+ ## Features
9
+
10
+ - Full Standard Schema v1 compliance
11
+ - WASM-powered validation for high performance
12
+ - JSON Schema generation (Draft 2020-12, Draft 07, OpenAPI 3.0)
13
+ - Type-safe TypeScript API
14
+ - Pure JS fallback when WASM is unavailable
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install valrs
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import { init, StringSchema, Int32Schema, isValidationSuccess } from 'valrs';
26
+
27
+ async function main() {
28
+ // Initialize the WASM module (required before validation)
29
+ await init();
30
+
31
+ // Validate values
32
+ const stringResult = StringSchema['~standard'].validate('hello');
33
+ if (isValidationSuccess(stringResult)) {
34
+ console.log(stringResult.value); // 'hello'
35
+ }
36
+
37
+ const intResult = Int32Schema['~standard'].validate(42);
38
+ if (isValidationSuccess(intResult)) {
39
+ console.log(intResult.value); // 42
40
+ }
41
+
42
+ // Handle validation errors
43
+ const invalidResult = Int32Schema['~standard'].validate('not a number');
44
+ if (!isValidationSuccess(invalidResult)) {
45
+ console.log(invalidResult.issues); // [{ message: 'Expected i32' }]
46
+ }
47
+
48
+ // Generate JSON Schema
49
+ const schema = StringSchema['~standard'].jsonSchema.input({ target: 'draft-2020-12' });
50
+ console.log(schema); // { type: 'string' }
51
+ }
52
+ ```
53
+
54
+ ## Available Schemas
55
+
56
+ ### Primitive Types
57
+
58
+ | Schema | TypeScript Type | Description |
59
+ |--------|-----------------|-------------|
60
+ | `StringSchema` | `string` | Any string value |
61
+ | `NumberSchema` | `number` | IEEE 754 double-precision float |
62
+ | `BooleanSchema` | `boolean` | `true` or `false` |
63
+ | `Int32Schema` | `number` | 32-bit signed integer |
64
+ | `Int64Schema` | `number` | 64-bit signed integer* |
65
+ | `Uint32Schema` | `number` | 32-bit unsigned integer |
66
+ | `Uint64Schema` | `number` | 64-bit unsigned integer* |
67
+ | `Float32Schema` | `number` | 32-bit float |
68
+ | `Float64Schema` | `number` | 64-bit float (same as `NumberSchema`) |
69
+
70
+ *Note: JavaScript numbers can only safely represent integers up to 2^53 - 1.
71
+
72
+ ### Aliases
73
+
74
+ - `IntegerSchema` - Alias for `Int32Schema`
75
+ - `DoubleSchema` - Alias for `Float64Schema`
76
+
77
+ ## Creating Custom Schemas
78
+
79
+ ### Basic Schema
80
+
81
+ ```typescript
82
+ import { createSchema } from 'valrs';
83
+
84
+ const PositiveNumber = createSchema<number>((value) => {
85
+ if (typeof value !== 'number') {
86
+ return { issues: [{ message: 'Expected a number' }] };
87
+ }
88
+ if (value <= 0) {
89
+ return { issues: [{ message: 'Must be positive' }] };
90
+ }
91
+ return { value };
92
+ });
93
+ ```
94
+
95
+ ### Schema with JSON Schema Support
96
+
97
+ ```typescript
98
+ import { createSchemaWithJsonSchema } from 'valrs';
99
+
100
+ const EmailSchema = createSchemaWithJsonSchema<string>(
101
+ (value) => {
102
+ if (typeof value !== 'string') {
103
+ return { issues: [{ message: 'Expected string' }] };
104
+ }
105
+ if (!value.includes('@')) {
106
+ return { issues: [{ message: 'Invalid email format' }] };
107
+ }
108
+ return { value };
109
+ },
110
+ (target) => ({
111
+ type: 'string',
112
+ format: 'email',
113
+ })
114
+ );
115
+ ```
116
+
117
+ ## Type Inference
118
+
119
+ ```typescript
120
+ import type { InferInput, InferOutput, StandardSchemaV1 } from 'valrs';
121
+
122
+ // Infer types from a schema
123
+ type StringInput = InferInput<typeof StringSchema>; // string
124
+ type StringOutput = InferOutput<typeof StringSchema>; // string
125
+
126
+ // Use as a type constraint
127
+ function validate<T extends StandardSchemaV1>(
128
+ schema: T,
129
+ value: unknown
130
+ ): InferOutput<T> | null {
131
+ const result = schema['~standard'].validate(value);
132
+ if ('value' in result) {
133
+ return result.value;
134
+ }
135
+ return null;
136
+ }
137
+ ```
138
+
139
+ ## JSON Schema Generation
140
+
141
+ All schemas with `StandardJSONSchemaV1` support can generate JSON Schema:
142
+
143
+ ```typescript
144
+ // Generate for different targets
145
+ const draft2020 = StringSchema['~standard'].jsonSchema.input({ target: 'draft-2020-12' });
146
+ const draft07 = StringSchema['~standard'].jsonSchema.input({ target: 'draft-07' });
147
+ const openapi = StringSchema['~standard'].jsonSchema.input({ target: 'openapi-3.0' });
148
+ ```
149
+
150
+ ## Standard Schema Compliance
151
+
152
+ This library implements the [Standard Schema](https://standardschema.dev/) specification v1:
153
+
154
+ ```typescript
155
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
156
+ readonly '~standard': {
157
+ readonly version: 1;
158
+ readonly vendor: string;
159
+ readonly validate: (value: unknown) => ValidationResult<Output>;
160
+ };
161
+ }
162
+ ```
163
+
164
+ Any schema from this library can be used with tools that support Standard Schema.
165
+
166
+ ## API Reference
167
+
168
+ ### Initialization
169
+
170
+ - `init()` - Initialize the WASM module (required before validation)
171
+ - `isInitialized()` - Check if WASM is ready
172
+
173
+ ### Type Guards
174
+
175
+ - `isValidationSuccess(result)` - Check if validation succeeded
176
+ - `isValidationFailure(result)` - Check if validation failed
177
+
178
+ ### Schema Factories
179
+
180
+ - `createSchema(validateFn)` - Create a basic schema
181
+ - `createSchemaWithJsonSchema(validateFn, jsonSchemaFn)` - Create schema with JSON Schema support
182
+ - `createSchemaWithSeparateJsonSchemas(validateFn, inputSchemaFn, outputSchemaFn)` - Create schema with different input/output JSON Schemas
183
+
184
+ ### Result Helpers
185
+
186
+ - `success(value)` - Create a success result
187
+ - `failure(issues)` - Create a failure result with multiple issues
188
+ - `fail(message, path?)` - Create a failure result with a single issue
189
+
190
+ ### Constants
191
+
192
+ - `VENDOR` - The vendor name (`'valrs'`)
193
+ - `VERSION` - The Standard Schema version (`1`)
194
+
195
+ ## License
196
+
197
+ MIT
@@ -0,0 +1,195 @@
1
+ /**
2
+ * JSON Schema to JavaScript Compiler
3
+ *
4
+ * Compiles JSON Schema definitions into optimized JavaScript validation functions.
5
+ * This approach generates direct property checks similar to TypeBox's TypeCompiler,
6
+ * providing high-performance validation without WASM overhead.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ /**
11
+ * JSON Schema type definition for compiler input.
12
+ * Supports a subset of JSON Schema draft-07/2020-12 features.
13
+ */
14
+ export interface JsonSchema {
15
+ readonly type?: string;
16
+ readonly properties?: Record<string, JsonSchema>;
17
+ readonly required?: readonly string[];
18
+ readonly items?: JsonSchema;
19
+ readonly minLength?: number;
20
+ readonly maxLength?: number;
21
+ readonly minimum?: number;
22
+ readonly maximum?: number;
23
+ readonly exclusiveMinimum?: number;
24
+ readonly exclusiveMaximum?: number;
25
+ readonly minItems?: number;
26
+ readonly maxItems?: number;
27
+ readonly pattern?: string;
28
+ readonly format?: string;
29
+ readonly enum?: readonly unknown[];
30
+ readonly const?: unknown;
31
+ readonly multipleOf?: number;
32
+ readonly uniqueItems?: boolean;
33
+ readonly additionalProperties?: boolean | JsonSchema;
34
+ readonly allOf?: readonly JsonSchema[];
35
+ readonly anyOf?: readonly JsonSchema[];
36
+ readonly oneOf?: readonly JsonSchema[];
37
+ readonly not?: JsonSchema;
38
+ readonly $ref?: string;
39
+ readonly [key: string]: unknown;
40
+ }
41
+ /**
42
+ * Compiled validator function type.
43
+ * Returns true if data is valid, false otherwise.
44
+ */
45
+ export type CompiledValidator = (data: unknown) => boolean;
46
+ /**
47
+ * Compiles a JSON Schema into an optimized JavaScript validation function.
48
+ *
49
+ * This generates direct property checks like TypeBox's TypeCompiler,
50
+ * creating highly efficient validators without the overhead of schema
51
+ * interpretation at runtime.
52
+ *
53
+ * @param schema - The JSON Schema to compile
54
+ * @returns A compiled validation function
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * import { compileSchema } from 'valrs';
59
+ *
60
+ * const userSchema = {
61
+ * type: 'object',
62
+ * properties: {
63
+ * name: { type: 'string', minLength: 1 },
64
+ * age: { type: 'integer', minimum: 0 },
65
+ * },
66
+ * required: ['name', 'age'],
67
+ * };
68
+ *
69
+ * const validate = compileSchema(userSchema);
70
+ *
71
+ * validate({ name: 'John', age: 30 }); // true
72
+ * validate({ name: '', age: 30 }); // false (minLength violation)
73
+ * validate({ name: 'John', age: -1 }); // false (minimum violation)
74
+ * ```
75
+ */
76
+ export declare function compileSchema(schema: JsonSchema): CompiledValidator;
77
+ /**
78
+ * Generates the JavaScript source code for a validator function.
79
+ *
80
+ * Useful for debugging or generating static validator files.
81
+ *
82
+ * @param schema - The JSON Schema to compile
83
+ * @returns The JavaScript function body as a string
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * import { compileSchemaToCode } from 'valrs';
88
+ *
89
+ * const code = compileSchemaToCode({
90
+ * type: 'string',
91
+ * minLength: 1,
92
+ * });
93
+ * // Returns: "return (typeof data === 'string' && data.length >= 1)"
94
+ * ```
95
+ */
96
+ export declare function compileSchemaToCode(schema: JsonSchema): string;
97
+ /**
98
+ * Schema registry with pre-compiled validators.
99
+ *
100
+ * Provides a convenient way to register schemas by name and validate
101
+ * data against them. All schemas are compiled on registration for
102
+ * optimal validation performance.
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * import { CompiledRegistry } from 'valrs';
107
+ *
108
+ * const registry = new CompiledRegistry();
109
+ *
110
+ * registry.register('User', {
111
+ * type: 'object',
112
+ * properties: {
113
+ * name: { type: 'string' },
114
+ * email: { type: 'string' },
115
+ * },
116
+ * required: ['name', 'email'],
117
+ * });
118
+ *
119
+ * registry.validate('User', { name: 'John', email: 'john@example.com' }); // true
120
+ * registry.validate('User', { name: 'John' }); // false (missing email)
121
+ * ```
122
+ */
123
+ export declare class CompiledRegistry {
124
+ private readonly validators;
125
+ private readonly schemas;
126
+ private readonly generatedCode;
127
+ /**
128
+ * Registers a schema with the registry.
129
+ *
130
+ * The schema is immediately compiled for optimal validation performance.
131
+ *
132
+ * @param name - The name to register the schema under
133
+ * @param schema - The JSON Schema to register
134
+ */
135
+ register(name: string, schema: JsonSchema): void;
136
+ /**
137
+ * Validates data against a registered schema.
138
+ *
139
+ * @param name - The name of the registered schema
140
+ * @param data - The data to validate
141
+ * @returns true if valid, false otherwise
142
+ * @throws Error if schema is not registered
143
+ */
144
+ validate(name: string, data: unknown): boolean;
145
+ /**
146
+ * Gets a registered schema by name.
147
+ *
148
+ * @param name - The name of the schema
149
+ * @returns The schema, or undefined if not registered
150
+ */
151
+ getSchema(name: string): JsonSchema | undefined;
152
+ /**
153
+ * Gets the compiled validator function for a schema.
154
+ *
155
+ * @param name - The name of the schema
156
+ * @returns The compiled validator, or undefined if not registered
157
+ */
158
+ getValidator(name: string): CompiledValidator | undefined;
159
+ /**
160
+ * Gets the generated JavaScript code for a schema.
161
+ *
162
+ * Useful for debugging or static code generation.
163
+ *
164
+ * @param name - The name of the schema
165
+ * @returns The generated code, or undefined if not registered
166
+ */
167
+ getGeneratedCode(name: string): string | undefined;
168
+ /**
169
+ * Checks if a schema is registered.
170
+ *
171
+ * @param name - The name to check
172
+ * @returns true if registered, false otherwise
173
+ */
174
+ has(name: string): boolean;
175
+ /**
176
+ * Removes a schema from the registry.
177
+ *
178
+ * @param name - The name of the schema to remove
179
+ * @returns true if removed, false if not found
180
+ */
181
+ delete(name: string): boolean;
182
+ /**
183
+ * Removes all schemas from the registry.
184
+ */
185
+ clear(): void;
186
+ /**
187
+ * Gets the names of all registered schemas.
188
+ */
189
+ get names(): string[];
190
+ /**
191
+ * Gets the number of registered schemas.
192
+ */
193
+ get size(): number;
194
+ }
195
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"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"}