ascertain 3.2.21 → 3.2.22

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 CHANGED
@@ -1,12 +1,13 @@
1
1
  # Ascertain
2
2
 
3
- Zero-dependency, high-performance schema validator for Node.js and browsers.
3
+ Compiled schema-and-constraint validation for JavaScript-native runtime values.
4
+
5
+ Write schemas as native JavaScript values, compile them once, and validate at AJV-class or better speed with zero dependencies and detailed pathful errors.
4
6
 
5
7
  [![Coverage Status][codecov-image]][codecov-url]
6
8
  [![Build Status][github-image]][github-url]
7
9
  [![NPM version][npm-image]][npm-url]
8
10
  [![Downloads][downloads-image]][npm-url]
9
- [![Snyk][snyk-image]][snyk-url]
10
11
 
11
12
  ## Table of Contents
12
13
 
@@ -25,14 +26,15 @@ Zero-dependency, high-performance schema validator for Node.js and browsers.
25
26
 
26
27
  ## Features
27
28
 
28
- - **Zero dependencies** - Minimal footprint, no external dependencies
29
- - **High performance** - Compiles schemas to optimized JS functions (~6x faster than dynamic validation)
29
+ - **JavaScript-native schemas** - Use constructors, literals, regexes, arrays, and object shapes directly
30
+ - **Compiled validators** - `compile()` emits specialized JS validators instead of interpreting the schema on every call
31
+ - **Fast first-error and all-errors modes** - Stay fast on valid data and on bad input
32
+ - **Zero dependencies** - Small footprint for Node.js and browsers
30
33
  - **Type-safe** - Full TypeScript support with type inference
31
- - **Flexible schemas** - AND, OR, optional, tuple, discriminated operators
32
- - **Type casting** - Built-in parsers for numbers (hex, octal, binary), dates, JSON, base64
34
+ - **Flexible schemas** - AND, OR, optional, tuple, discriminated, and custom check operators
33
35
  - **Object validation** - Validate keys/values with `$keys`, `$values`, `$strict`
36
+ - **Type casting** - Built-in parsers for numbers, dates, JSON, base64, bytes, and durations
34
37
  - **Partial validation** - `createValidator` validates subsets with type narrowing
35
- - **Detailed errors** - Clear error messages with paths for debugging
36
38
  - **Standard Schema v1** - Interoperable with tRPC, TanStack Form, and other ecosystem tools
37
39
 
38
40
  ## Install
@@ -44,19 +46,34 @@ npm install ascertain
44
46
  ## Quick Start
45
47
 
46
48
  ```typescript
47
- import { ascertain, or, optional } from 'ascertain';
49
+ import { compile, discriminated, optional, or } from 'ascertain';
48
50
 
49
- ascertain({
50
- name: String,
51
- age: Number,
52
- role: or('admin', 'user'),
53
- email: optional(String),
54
- }, userData);
51
+ const validateUser = compile({
52
+ id: Number,
53
+ role: or('admin', 'user', 'guest'),
54
+ score: optional(Number),
55
+ notifications: [
56
+ discriminated(
57
+ [
58
+ { type: 'email', address: String },
59
+ { type: 'sms', phone: String },
60
+ { type: 'push', token: String },
61
+ ],
62
+ 'type',
63
+ ),
64
+ ],
65
+ });
66
+
67
+ if (!validateUser(userData)) {
68
+ console.error(validateUser.issues);
69
+ }
55
70
  ```
56
71
 
72
+ Use `ascertain(schema, data)` when you want the convenience wrapper that compiles and throws immediately on failure.
73
+
57
74
  ## Performance
58
75
 
59
- Ascertain compiles schemas into optimized JavaScript functions. Compiled validators run **~6x faster** than dynamic validation.
76
+ `compile()` is the center of the library. It turns a schema written as native JS values into a specialized validator function that you can reuse in hot paths.
60
77
 
61
78
  ```typescript
62
79
  import { compile } from 'ascertain';
@@ -69,22 +86,27 @@ validateUser(user1);
69
86
  validateUser(user2);
70
87
  ```
71
88
 
72
- | When to use | Function | Speed |
73
- |-------------|----------|-------|
74
- | Repeated validation (API handlers, loops) | `compile()` | Fastest |
75
- | One-off validation | `ascertain()` | Convenient |
89
+ | When to use | Function | Why |
90
+ |-------------|----------|-----|
91
+ | Repeated validation (API handlers, loops, message boundaries) | `compile()` | Compile once, reuse the generated validator |
92
+ | One-off validation | `ascertain()` | Convenience wrapper around `compile()` that throws on failure |
76
93
 
77
94
  ### Benchmark
78
95
 
79
- | Library | Mode | Valid (ops/s) | Invalid (ops/s) |
80
- |---------|------|---------------|-----------------|
81
- | **Ascertain** | first-error | 322M | 84M |
82
- | **Ascertain** | all-errors | 325M | 36M |
83
- | AJV | first-error | 92M | 65M |
84
- | AJV | all-errors | 92M | 30M |
85
- | Zod | all-errors | 62M | 72K |
96
+ Maintainer-run benchmark suites live in `src/__bench__/benchmark.ts` and `src/__bench__/benchmark-complex.ts`. On the current checkout, Ascertain is consistently faster than AJV in this suite and dramatically faster than Zod on invalid all-errors workloads.
97
+
98
+ Comparable all-errors results from the current run:
99
+
100
+ | Workload | Ascertain | AJV | Zod |
101
+ |----------|-----------|-----|-----|
102
+ | Simple valid | **350.9M** ops/s | 88.7M ops/s | 57.9M ops/s |
103
+ | Simple invalid | **38.2M** ops/s | 28.2M ops/s | 75.7K ops/s |
104
+ | Complex valid | **47.8M** ops/s | 38.1M ops/s | 6.1M ops/s |
105
+ | Complex invalid | **16.9M** ops/s | 11.7M ops/s | 44.0K ops/s |
106
+
107
+ First-error mode is the default and pushes invalid-path throughput higher still. In the same run, Ascertain reached 91.1M ops/s on simple invalid data and 83.6M ops/s on complex invalid data.
86
108
 
87
- Benchmark source: [`src/__bench__/benchmark.ts`](https://github.com/3axap4eHko/ascertain/blob/master/src/__bench__/benchmark.ts)
109
+ Benchmark sources: [`src/__bench__/benchmark.ts`](https://github.com/3axap4eHko/ascertain/blob/master/src/__bench__/benchmark.ts), [`src/__bench__/benchmark-complex.ts`](https://github.com/3axap4eHko/ascertain/blob/master/src/__bench__/benchmark-complex.ts), [`src/__bench__/self.ts`](https://github.com/3axap4eHko/ascertain/blob/master/src/__bench__/self.ts)
88
110
 
89
111
  Run it locally:
90
112
 
@@ -395,5 +417,3 @@ if (!validate(data)) {
395
417
  [github-image]: https://github.com/3axap4eHko/ascertain/actions/workflows/cicd.yml/badge.svg
396
418
  [codecov-url]: https://codecov.io/gh/3axap4eHko/ascertain
397
419
  [codecov-image]: https://img.shields.io/codecov/c/github/3axap4eHko/ascertain/master.svg?maxAge=43200
398
- [snyk-url]: https://snyk.io/test/npm/ascertain/latest
399
- [snyk-image]: https://img.shields.io/snyk/vulnerabilities/github/3axap4eHko/ascertain.svg?maxAge=43200