typebox 1.0.81 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,9 @@
1
1
  // deno-fmt-ignore-file
2
+ import { Settings } from '../system/settings/index.mjs';
2
3
  import { Arguments } from '../system/arguments/index.mjs';
3
4
  import { Environment } from '../system/environment/index.mjs';
4
5
  import { Base } from '../type/index.mjs';
5
- import { Errors, Clean, Convert, Create, Default, Decode, Encode, HasCodec, Parser } from '../value/index.mjs';
6
+ import { Errors, Clean, Convert, Create, Default, Decode, Encode, HasCodec, Parser, ParseError } from '../value/index.mjs';
6
7
  import { Build } from '../schema/index.mjs';
7
8
  // ------------------------------------------------------------------
8
9
  // Validator<...>
@@ -93,13 +94,14 @@ export class Validator extends Base {
93
94
  Clone() {
94
95
  return new Validator(this.context, this.type, this.isEvaluated, this.hasCodec, this.code, this.check);
95
96
  }
96
- // ----------------------------------------------------------------
97
- // Parse | Decode | Encode
98
- // ----------------------------------------------------------------
99
97
  /** Parses a value */
100
98
  Parse(value) {
101
- const result = this.Check(value) ? value : Parser(this.context, this.type, value);
102
- return result;
99
+ const checked = this.Check(value);
100
+ if (checked)
101
+ return value;
102
+ if (Settings.Get().correctiveParse)
103
+ return Parser(this.context, this.type, value);
104
+ throw new ParseError(value, this.Errors(value));
103
105
  }
104
106
  /** Decodes a value */
105
107
  Decode(value) {
@@ -1,5 +1,6 @@
1
1
  import * as Schema from './types/index.mjs';
2
+ import * as Static from './static/index.mjs';
2
3
  /** Checks a value against the provided schema */
3
- export declare function Check(schema: Schema.XSchema, value: unknown): boolean;
4
+ export declare function Check<const Schema extends Schema.XSchema>(schema: Schema, value: unknown): value is Static.XStatic<Schema>;
4
5
  /** Checks a value against the provided schema */
5
- export declare function Check(context: Record<PropertyKey, Schema.XSchema>, schema: Schema.XSchema, value: unknown): boolean;
6
+ export declare function Check<const Schema extends Schema.XSchema>(context: Record<PropertyKey, Schema.XSchema>, schema: Schema, value: unknown): value is Static.XStatic<Schema>;
@@ -0,0 +1,18 @@
1
+ import { type TLocalizedValidationError } from '../error/index.mjs';
2
+ import * as Schema from './types/index.mjs';
3
+ import * as Static from './static/index.mjs';
4
+ export declare class Validator<Schema extends Schema.XSchema, Value extends unknown = Static.XStatic<Schema>> {
5
+ private readonly build;
6
+ private readonly result;
7
+ constructor(context: Record<string, Schema.XSchema>, schema: Schema);
8
+ /** Checks this value is valid */
9
+ Check(value: unknown): value is Value;
10
+ /** Parses this value and throw if invalid */
11
+ Parse(value: unknown): Value;
12
+ /** Returns errors for the given value */
13
+ Errors(value: unknown): [result: boolean, errors: TLocalizedValidationError[]];
14
+ }
15
+ /** Compiles this schema into a high performance Validator */
16
+ export declare function Compile<const Schema extends Schema.XSchema>(schema: Schema): Validator<Schema>;
17
+ /** Compiles this schema into a high performance Validator */
18
+ export declare function Compile<const Schema extends Schema.XSchema>(context: Record<PropertyKey, Schema.XSchema>, schema: Schema): Validator<Schema>;
@@ -0,0 +1,38 @@
1
+ // deno-fmt-ignore-file
2
+ // deno-lint-ignore-file
3
+ import { Arguments } from '../system/arguments/index.mjs';
4
+ import * as Build from './build.mjs';
5
+ import { Errors } from './errors.mjs';
6
+ import { ParseError } from './parse.mjs';
7
+ // ------------------------------------------------------------------
8
+ // Validator
9
+ // ------------------------------------------------------------------
10
+ export class Validator {
11
+ constructor(context, schema) {
12
+ this.build = Build.Build(context, schema);
13
+ this.result = this.build.Evaluate();
14
+ }
15
+ /** Checks this value is valid */
16
+ Check(value) {
17
+ return this.result.Check(value);
18
+ }
19
+ /** Parses this value and throw if invalid */
20
+ Parse(value) {
21
+ if (this.result.Check(value))
22
+ return value;
23
+ const [_result, errors] = Errors(this.build.Context(), this.build.Schema(), value);
24
+ throw new ParseError(this.build.Context(), this.build.Schema(), errors);
25
+ }
26
+ /** Returns errors for the given value */
27
+ Errors(value) {
28
+ return Errors(this.build.Context(), this.build.Schema(), value);
29
+ }
30
+ }
31
+ /** Compiles this schema into a high performance Validator */
32
+ export function Compile(...args) {
33
+ const [context, schema] = Arguments.Match(args, {
34
+ 2: (context, schema) => [context, schema],
35
+ 1: (schema) => [{}, schema]
36
+ });
37
+ return new Validator(context, schema);
38
+ }
@@ -0,0 +1,13 @@
1
+ import { type TLocalizedValidationError } from '../error/index.mjs';
2
+ import * as Schema from './types/index.mjs';
3
+ import * as Static from './static/index.mjs';
4
+ export declare class ParseError {
5
+ schema: Schema.XSchema;
6
+ value: unknown;
7
+ errors: TLocalizedValidationError[];
8
+ constructor(schema: Schema.XSchema, value: unknown, errors: TLocalizedValidationError[]);
9
+ }
10
+ /** Parses a value against the provided schema */
11
+ export declare function Parse<const Schema extends Schema.XSchema>(schema: Schema, value: unknown): Static.XStatic<Schema>;
12
+ /** Parses a value against the provided schema */
13
+ export declare function Parse<const Schema extends Schema.XSchema>(context: Record<PropertyKey, Schema.XSchema>, schema: Schema, value: unknown): Static.XStatic<Schema>;
@@ -0,0 +1,27 @@
1
+ // deno-fmt-ignore-file
2
+ // deno-lint-ignore-file
3
+ import { Arguments } from '../system/arguments/index.mjs';
4
+ import { Check } from './check.mjs';
5
+ import { Errors } from './errors.mjs';
6
+ // ------------------------------------------------------------------
7
+ // ParseError
8
+ // ------------------------------------------------------------------
9
+ export class ParseError {
10
+ constructor(schema, value, errors) {
11
+ this.schema = schema;
12
+ this.value = value;
13
+ this.errors = errors;
14
+ }
15
+ }
16
+ /** Parses a value against the provided schema */
17
+ export function Parse(...args) {
18
+ const [context, schema, value] = Arguments.Match(args, {
19
+ 3: (context, schema, value) => [context, schema, value],
20
+ 2: (schema, value) => [{}, schema, value]
21
+ });
22
+ if (!Check(context, schema, value)) {
23
+ const [_result, errors] = Errors(context, schema, value);
24
+ throw new ParseError(schema, value, errors);
25
+ }
26
+ return value;
27
+ }
@@ -4,5 +4,7 @@ export * from './resolve/index.mjs';
4
4
  export * from './static/index.mjs';
5
5
  export * from './types/index.mjs';
6
6
  export * from './build.mjs';
7
+ export * from './compile.mjs';
7
8
  export * from './check.mjs';
9
+ export * from './parse.mjs';
8
10
  export * from './errors.mjs';
@@ -4,5 +4,7 @@ export * from './resolve/index.mjs';
4
4
  export * from './static/index.mjs';
5
5
  export * from './types/index.mjs';
6
6
  export * from './build.mjs';
7
+ export * from './compile.mjs';
7
8
  export * from './check.mjs';
9
+ export * from './parse.mjs';
8
10
  export * from './errors.mjs';
@@ -38,6 +38,15 @@ export interface TSettings {
38
38
  * @default false
39
39
  */
40
40
  enumerableKind: boolean;
41
+ /**
42
+ * Controls whether TypeBox uses corrective Parse. When enabled, TypeBox will attempt to recover invalid
43
+ * values during Parse by running a sequence of `Value.*` operations to `Convert`, `Default`, and `Clean`
44
+ * the value, followed by a subsequent `Assert`. Enabling this option may incur significant performance
45
+ * overhead for invalid values. It is recommended to keep this disabled in performance-sensitive
46
+ * applications.
47
+ * @default false
48
+ */
49
+ correctiveParse: boolean;
41
50
  }
42
51
  /** Resets system settings to defaults */
43
52
  export declare function Reset(): void;
@@ -5,7 +5,8 @@ const settings = {
5
5
  maxErrors: 8,
6
6
  useEval: true,
7
7
  exactOptionalPropertyTypes: false,
8
- enumerableKind: false
8
+ enumerableKind: false,
9
+ correctiveParse: false
9
10
  };
10
11
  /** Resets system settings to defaults */
11
12
  export function Reset() {
@@ -14,6 +15,7 @@ export function Reset() {
14
15
  settings.useEval = true;
15
16
  settings.exactOptionalPropertyTypes = false;
16
17
  settings.enumerableKind = false;
18
+ settings.correctiveParse = false;
17
19
  }
18
20
  /** Sets system settings */
19
21
  export function Set(options) {
@@ -5,17 +5,7 @@ export declare class ParseError extends AssertError {
5
5
  constructor(value: unknown, errors: TLocalizedValidationError[]);
6
6
  }
7
7
  export declare const Parser: import("../pipeline/pipeline.mjs").PipelineInterface;
8
- /**
9
- * Parses a value with the given type. The function will Check the value and return
10
- * early if it matches the provided type. If the value does not match, it is processed
11
- * through a sequence of Clone, Default, Convert, and Clean operations and checked again.
12
- * A `ParseError` is thrown if the value fails to match after the processing sequence.
13
- */
8
+ /** Parses a value with the given type. */
14
9
  export declare function Parse<const Type extends TSchema, Result extends unknown = StaticParse<Type>>(type: Type, value: unknown): Result;
15
- /**
16
- * Parses a value with the given type. The function will Check the value and return
17
- * early if it matches the provided type. If the value does not match, it is processed
18
- * through a sequence of Clone, Default, Convert, and Clean operations and checked again.
19
- * A `ParseError` is thrown if the value fails to match after the processing sequence.
20
- */
10
+ /** Parses a value with the given type. */
21
11
  export declare function Parse<Context extends TProperties, const Type extends TSchema, Result extends unknown = StaticParse<Type, Context>>(context: Context, type: Type, value: unknown): Result;
@@ -1,4 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
+ import { Settings } from '../../system/system.mjs';
2
3
  import { Arguments } from '../../system/arguments/index.mjs';
3
4
  import { AssertError } from '../assert/index.mjs';
4
5
  import { Check } from '../check/index.mjs';
@@ -31,17 +32,16 @@ export const Parser = Pipeline([
31
32
  (context, type, value) => Clean(context, type, value),
32
33
  (context, type, value) => Assert(context, type, value)
33
34
  ]);
34
- /**
35
- * Parses a value with the given type. The function will Check the value and return
36
- * early if it matches the provided type. If the value does not match, it is processed
37
- * through a sequence of Clone, Default, Convert, and Clean operations and checked again.
38
- * A `ParseError` is thrown if the value fails to match after the processing sequence.
39
- */
35
+ /** Parses a value with the given type. */
40
36
  export function Parse(...args) {
41
37
  const [context, type, value] = Arguments.Match(args, {
42
38
  3: (context, type, value) => [context, type, value],
43
39
  2: (type, value) => [{}, type, value],
44
40
  });
45
- const result = Check(context, type, value) ? value : Parser(context, type, value);
46
- return result;
41
+ const checked = Check(context, type, value);
42
+ if (checked)
43
+ return value;
44
+ if (Settings.Get().correctiveParse)
45
+ return Parser(context, type, value);
46
+ throw new ParseError(value, Errors(context, type, value));
47
47
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typebox",
3
3
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
4
- "version": "1.0.81",
4
+ "version": "1.1.1",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "jsonschema"
package/readme.md CHANGED
@@ -25,13 +25,9 @@ $ npm install typebox
25
25
 
26
26
  ## Usage
27
27
 
28
- A TypeScript engine for JSON Schema [Example](https://tsplay.dev/mZMOeN)
29
-
30
28
  ```typescript
31
29
  import Type from 'typebox'
32
30
 
33
- // JSON Schema
34
-
35
31
  const T = Type.Object({ // const T = {
36
32
  x: Type.Number(), // type: 'object',
37
33
  y: Type.Number(), // required: ['x', 'y', 'z'],
@@ -47,20 +43,6 @@ type T = Type.Static<typeof T> // type T = {
47
43
  // y: number,
48
44
  // z: number
49
45
  // }
50
-
51
- // TypeScript
52
-
53
- const { S } = Type.Script({ T }, `
54
- type S = {
55
- readonly [K in keyof T as Uppercase<K>]: string
56
- }
57
- `)
58
-
59
- type S = Type.Static<typeof S> // type S = {
60
- // readonly X: string,
61
- // readonly Y: string,
62
- // readonly Z: string
63
- // }
64
46
  ```
65
47
 
66
48
  ## Overview
@@ -79,7 +61,6 @@ License: MIT
79
61
  - [Type](#Type)
80
62
  - [Value](#Value)
81
63
  - [Script](#Script)
82
- - [Compile](#Compile)
83
64
  - [Schema](#Schema)
84
65
  - [Legacy](#Legacy)
85
66
  - [Contribute](#Contribute)
@@ -164,41 +145,37 @@ const A = Value.Parse(T, { // const A: {
164
145
 
165
146
  ## Script
166
147
 
167
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/script/overview) | [Example 1](https://tsplay.dev/Wk6L1m) | [Example 2](https://tsplay.dev/NnrJoN)
148
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/script/overview) | [Example 1](https://tsplay.dev/N9rQ8m) | [Example 2](https://tsplay.dev/NnrJoN)
168
149
 
169
- TypeBox is a runtime TypeScript DSL engine that can create, transform, and compute JSON Schema using native TypeScript syntax. The engine is implemented symmetrically at runtime and within the TypeScript type system, and is intended for use with the TypeScript 7 native compiler and above.
150
+ TypeBox includes a runtime TypeScript DSL engine that can transform TypeScript syntax into JSON Schema. The engine is implemented at runtime and within the TypeScript type system.
170
151
 
171
152
  ```typescript
172
- // Scripted Type
173
-
153
+ // ----------------------------------------------------------
154
+ // Script
155
+ // ----------------------------------------------------------
174
156
  const T = Type.Script(`{
175
157
  x: number,
176
158
  y: string,
177
159
  z: boolean
178
- }`) // const T: TObject<{
179
- // x: TNumber,
180
- // y: TString,
181
- // z: TBoolean
182
- // }>
183
-
184
- // JSON Schema Introspection
160
+ }`)
185
161
 
162
+ // ----------------------------------------------------------
163
+ // Reflect
164
+ // ----------------------------------------------------------
186
165
  T.type // 'object'
187
166
  T.required // ['x', 'y', 'z']
188
167
  T.properties // { x: ..., y: ..., z: ... }
189
168
 
190
- // Scripted Type (Computed)
191
-
169
+ // ----------------------------------------------------------
170
+ // Computed
171
+ // ----------------------------------------------------------
192
172
  const S = Type.Script({ T }, `{
193
173
  [K in keyof T]: T[K] | null
194
- }`) // const S: TObject<{
195
- // x: TUnion<[TNumber, TNull]>,
196
- // y: TUnion<[TString, TNull]>,
197
- // z: TUnion<[TBoolean, TNull]>
198
- // }>
199
-
200
- // Standard Inference
174
+ }`)
201
175
 
176
+ // ----------------------------------------------------------
177
+ // Inference
178
+ // ----------------------------------------------------------
202
179
  type S = Type.Static<typeof S> // type S = {
203
180
  // x: number | null,
204
181
  // y: string | null,
@@ -206,50 +183,27 @@ type S = Type.Static<typeof S> // type S = {
206
183
  // }
207
184
  ```
208
185
 
209
- <a name="Compile"></a>
210
-
211
- ## Compile
212
-
213
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/compile/overview) | [Example](https://tsplay.dev/WyraZw)
214
-
215
- The Compile submodule is a high-performance, JSON Schema compliant JIT compiler that transforms schematics into efficient runtime validators. It is optimized for fast, dynamic schema compilation and delivers extremely high data-validation throughput.
216
-
217
- ```typescript
218
- import Compile from 'typebox/compile'
219
- ```
186
+ <a name="Schema"></a>
220
187
 
221
- ### Example
188
+ ## Schema
222
189
 
223
- The following uses the compiler to Compile and Parse a value.
190
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/schema/overview)
224
191
 
225
192
  ```typescript
226
- const C = Compile(Type.Object({ // const C: Validator<{}, TObject<{
227
- x: Type.Number(), // x: TNumber,
228
- y: Type.Number(), // y: TNumber,
229
- z: Type.Number() // z: TNumber
230
- })) // }>>
231
-
232
- const A = C.Parse({ // const A: {
233
- x: 0, // x: number,
234
- y: 1, // y: number,
235
- z: 0 // z: number
236
- }) // } = ...
193
+ import Schema from 'typebox/schema'
237
194
  ```
238
195
 
239
- <a name="Schema"></a>
240
-
241
- ## Schema
242
-
243
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/schema/overview) | [Example 1](https://tsplay.dev/Wvrv3W) | [Example 2](https://tsplay.dev/m3g0ym)
244
-
245
- TypeBox is built upon a high-performance validation infrastructure that supports the direct compilation and inference of JSON Schema schematics. TypeBox implements Draft 3 to 2020-12 and is compliance tested via the official JSON Schema [Test Suite](https://github.com/JSON-schema-org/JSON-Schema-Test-Suite). It offers high-performance JIT compilation with automatic fallback to dynamic checking in JIT restricted environments.
196
+ The Value submodule is developed over a more low level JSON Schema spec compliant validation system that supports Drafts 3 through to 2020-12. This validation system is entirely decoupled from both Type and Value submodules and is designed to be a ultra lightweight, high performance alternative to Ajv.
246
197
 
247
198
  ### Example
248
199
 
249
- The following compiles JSON Schema. Type inference is supported.
200
+ The following uses the Schema submodule to compile and parse from JSON Schema.
250
201
 
251
202
  ```typescript
252
- const C = Compile({
203
+ // ----------------------------------------------------------
204
+ // Compile
205
+ // ----------------------------------------------------------
206
+ const C = Schema.Compile({
253
207
  type: 'object',
254
208
  required: ['x', 'y', 'z'],
255
209
  properties: {
@@ -259,11 +213,14 @@ const C = Compile({
259
213
  }
260
214
  })
261
215
 
262
- const A = C.Parse({ // const A: {
263
- x: 0, // x: number,
264
- y: 0, // y: number,
265
- z: 1 // z: number
266
- }) // } = ...
216
+ // ----------------------------------------------------------
217
+ // Parse
218
+ // ----------------------------------------------------------
219
+ const R = C.Parse({ x: 0, y: 0, z: 0 }) // const R: {
220
+ // x: number,
221
+ // y: number,
222
+ // z: number
223
+ // } = ...
267
224
  ```
268
225
 
269
226
  ## Legacy
@@ -280,8 +237,9 @@ Most types created with 0.34.x are compatible with V1, and it is possible to run
280
237
  import { Type } from '@sinclair/typebox' // TB: 0.34.x
281
238
  import { Static } from 'typebox' // TB: 1.0.0
282
239
 
240
+ // ----------------------------------------------------------
283
241
  // Legacy Types
284
-
242
+ // ----------------------------------------------------------
285
243
  const A = Type.Object({
286
244
  x: Type.Number(),
287
245
  y: Type.Number(),
@@ -296,8 +254,9 @@ const B = Type.Object({
296
254
 
297
255
  const C = Type.Composite([A, B])
298
256
 
257
+ // ----------------------------------------------------------
299
258
  // Modern Inference
300
-
259
+ // ----------------------------------------------------------
301
260
  type C = Static<typeof C> // type C = {
302
261
  // x: number;
303
262
  // y: number;
@@ -307,11 +266,12 @@ type C = Static<typeof C> // type C = {
307
266
  // c: number;
308
267
  // }
309
268
 
269
+ // ----------------------------------------------------------
310
270
  // Modern Compile
271
+ // ----------------------------------------------------------
272
+ import Schema from 'typebox/schema'
311
273
 
312
- import Compile from 'typebox/compile'
313
-
314
- const Result = Compile(C).Check({ ... })
274
+ const R = Schema.Compile(C).Check({ ... })
315
275
  ```
316
276
 
317
277
  Revision 0.34.x is actively maintained at the following URL.