-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
da49443
commit 81ab941
Showing
317 changed files
with
7,326 additions
and
6,165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
import { TypeCompiler } from '@sinclair/typebox/compiler' | ||
import { Type } from '@sinclair/typebox' | ||
|
||
const T = TypeCompiler.Compile(Type.String()) | ||
console.log(TypeCompiler) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
import { ValueErrorType } from '@sinclair/typebox/errors' | ||
import * as ValueErrors from '@sinclair/typebox/errors' | ||
|
||
console.log(ValueErrorType) | ||
console.log(ValueErrors) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
import { TypeSystem } from '@sinclair/typebox/system' | ||
|
||
TypeSystem.AllowNaN = true | ||
console.log(TypeSystem) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
import { Value } from '@sinclair/typebox/value' | ||
import { Type } from '@sinclair/typebox' | ||
|
||
const T = Value.Create(Type.String()) | ||
console.log(Value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
## [0.30.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.30.0) | ||
|
||
## Overview | ||
|
||
Revision 0.30.0 updates the schema representations Extended types and includes two new iterator types. This revision also changes how TypeBox handles readonly and optional modifiers. Additional updates include adding additional constraints supported on newer versions of the specification, as well initial attempts to reduce package size. | ||
|
||
This revision includes breaking representation changes to Extended Types and Modifiers and requires a minor semver. | ||
|
||
## Contents | ||
|
||
- Changes | ||
- [Extended Type Representations](#Extended-Type-Representations) | ||
- [Optional and Readonly](#Optional-and-Readonly) | ||
- [Iterator and AsyncIterator](#Iterator-and-AsyncIterator) | ||
- [Order Independent References](#Order-Independent-References) | ||
- [Value Submodules](#Value-Submodules) | ||
- [Additional Array Constaints](#Additional-Array-Constaints) | ||
- [Reducing Package Size](#Reducing-Package-Size) | ||
- Breaking | ||
- [RegEx Renamed To RegExp](#RegEx-Renamed-To-RegExp) | ||
- [Modifier Symbol Deprecated](#Modifier-Deprecated) | ||
|
||
|
||
<a name="Extended-Type-Representations"></a> | ||
|
||
## Extended Type Representations | ||
|
||
Revision 0.30.0 updates representations for all extended types. This change is made due to TypeBox's observed role as a general purpose JavaScript validation library as well as to deprecate support for extended type validation in Ajv (which was partially functional at best) | ||
|
||
Attempts were made on Revision 0.25.0 to restructure extended types to provide Ajv hooks for custom type configuration. These hooks used the `type` property where `{ type: 'object', instanceOf: 'TypeName' }` was used to configure schematics for JavaScript objects, and `{ type: 'null', typeOf: 'PrimitiveName' }` was used for JavaScript primitives. Despite these hooks, Ajv would still struggle with validation of primitive types (such as `undefined`), and for the types `Function`, `Constructor` and `Promise`; these were meaningless to Ajv and it did not make sense to try provide hooks for a validator that could not use them anyway. | ||
|
||
This change mostly represents a move towards a formal specification to express pure JavaScript constructs. The change will implicate the use of `Uint8Array` and `Date` objects when configuring for Ajv. A supplimentary fallback will be provided in the `/examples` directory using `Type.Unsafe` | ||
|
||
```typescript | ||
// Revision 0.29.0 | ||
// | ||
const T = Type.Date() // const T: TDate = { type: 'object', instanceOf: 'Date' } | ||
|
||
const U = Type.Undefined() // const U: TUndefined = { type: 'null', typeOf: 'Undefined' } | ||
|
||
// Revision 0.30.0 | ||
// | ||
const T = Type.Date() // const T: TDate = { type: 'Date' } | ||
|
||
const U = Type.Undefined() // const U: TUndefined = { type: 'undefined' } | ||
``` | ||
|
||
<a name="Optional-and-Readonly"></a> | ||
|
||
## Optional and Readonly | ||
|
||
Revision 0.30.0 deprecates the `[Modifier]` symbol and introduces two new symbols, `[Readonly]` and `[Optional]`. This change is carried out to simplify internal type inference as well as to simplify runtime mapping logic. This change should not implicate users leveraging the `Type.*` for type construction, however implementors building runtime mapping utilities should update to use the new symbols. | ||
|
||
```typescript | ||
// Revision 0.29.0 | ||
// | ||
const A = Type.ReadonlyOptional(Type.Number()) // const A: TReadonlyOptional<TNumber> = { | ||
// type: 'number', | ||
// [TypeBox.Modifier]: 'ReadonlyOptional' | ||
// } | ||
|
||
const B = Type.Readonly(Type.Number()) // const B: TReadonly<TNumber> = { | ||
// type: 'number', | ||
// [TypeBox.Modifier]: 'Readonly' | ||
// } | ||
|
||
const C = Type.Optional(Type.Number()) // const C: TOptional<TNumber> = { | ||
// type: 'number', | ||
// [TypeBox.Modifier]: 'Optional' | ||
// } | ||
|
||
// Revision 0.30.0 | ||
// | ||
const A = Type.ReadonlyOptional(Type.Number()) // const A: TReadonly<TOptional<TNumber>> = { | ||
// type: 'number', | ||
// [TypeBox.Readonly]: 'Readonly', | ||
// [TypeBox.Optional]: 'Optional' | ||
// } | ||
|
||
const B = Type.Readonly(Type.Number()) // const B: TReadonly<TNumber> = { | ||
// type: 'number', | ||
// [TypeBox.Readonly]: 'Readonly' | ||
// } | ||
|
||
const C = Type.Optional(Type.Number()) // const C: TOptional<TNumber> = { | ||
// type: 'number', | ||
// [TypeBox.Optional]: 'Optional' | ||
// } | ||
``` | ||
|
||
<a name="Iterator-and-AsyncIterator"></a> | ||
|
||
## Iterator and AsyncIterator | ||
|
||
Revision 0.30.0 adds additional extended types `Type.Iterator` and `Type.AsyncIterator`. These types compliment the existing non-validatable extended types and can be used in wider infrastructure to describe interfaces that return iterator sequences. | ||
|
||
```typescript | ||
// Revision 0.30.0 | ||
// | ||
const EnumerableRange = <T extends TSchema>(T: T) => Type.Function([ | ||
Type.Number({ description: 'Start index' }), | ||
Type.Number({ description: 'End index' }) | ||
], Type.Iterator(T)) | ||
|
||
|
||
type EnumerableNumberRange = Static<typeof EnumerableNumberRange> | ||
const EnumerableNumberRange = EnumerableRange(Type.Number()) | ||
|
||
const Range: EnumerableNumberRange = function * (start: number, end: number) { | ||
for(let i = start; i < end; i++) yield i | ||
} | ||
|
||
const R = [...Range(10, 20)] // const R = [10, 11, 12, ..., 19] | ||
``` | ||
|
||
<a name="Order-Independent-References"></a> | ||
|
||
## Order Independent References | ||
|
||
Revision 0.30.0 adds a overload for `Type.Ref` to enable non order dependent type referencing. Prior to this revision, reference targets needed to be defined before referencing. Revision 0.30.0 lifts this restriction and allows reference yet to be defined targets through the use of `typeof` operator. This overload makes use of TypeScript's ability to reason about all types irrespective of topological ordering. | ||
|
||
This overload is principally implemented for TypeScript to TypeBox code generation where TypeScript types are not guaranteed to be sorted using runtime dependent ordering. | ||
|
||
```typescript | ||
// Revision 0.29.0 | ||
// | ||
const R = Type.Ref(T) // Error: T isn't defined yet | ||
|
||
const T = Type.Object({ | ||
x: Type.Number(), | ||
y: Type.Number(), | ||
z: Type.Number() | ||
}, { $id: 'T' }) | ||
|
||
// Revision 0.30.0 | ||
// | ||
const R = Type.Ref<typeof T>('T') // Ok: infer from typeof T | ||
|
||
const T = Type.Object({ | ||
x: Type.Number(), | ||
y: Type.Number(), | ||
z: Type.Number() | ||
}, { $id: 'T' }) | ||
``` | ||
|
||
<a name="Value-Submodules"></a> | ||
|
||
## Value Submodules | ||
|
||
Revision 0.30.0 refactors the `Value.*` module to allow each submodule to be imported individually. This change is part of larger refactoring to reduce the size of the Value module, but also to address issues with bundlers unable to tree-shake against the internal namespaces. | ||
|
||
The `Value.*` namespace is retained on Revision 0.30.0 | ||
|
||
```typescript | ||
// Revision 0.29.0 | ||
// | ||
import { Value } from '@sinclair/typebox/value' // Value.* namespace | ||
const A = Value.Create(Type.String()) | ||
|
||
// Revision 0.30.0 | ||
// | ||
import { Create } from '@sinclair/typebox/value/create' // Create function only | ||
const B = Create(Type.String()) | ||
``` | ||
|
||
<a name="Additional Array Constaints"></a> | ||
|
||
## Additional Array Constaints | ||
|
||
Revision 0.30.0 provides support for additional constraints on `Type.Array`. The `contains` keyword is now supported as well as draft 2019-09 `minContains` and `maxContains` keywords. These keywords are documented as types and validator support is also provided. Documentation on these constraints can be found https://json-schema.org/understanding-json-schema/reference/array.html#contains | ||
|
||
The introduction of these constraints continues ongoing work to support newer versions of the JSON Schema specification where `minContains` and `maxContains` join `unevaluatedProperties` as representations of the 2019-09 specification. | ||
|
||
```typescript | ||
// Revision 0.30.0 | ||
// | ||
const T = Type.Array(Type.Number(), { | ||
contains: Type.Literal(1), | ||
minContains: 3, | ||
maxContains: 5 | ||
}) | ||
|
||
Value.Check(T, [1, 1, 1]) // true - between 3 and 5 instances of 1 | ||
Value.Check(T, [1, 1, 1, 1, 1]) // true - between 3 and 5 instances of 1 | ||
Value.Check(T, [0, 1, 1, 1, 1, 1]) // true - between 3 and 5 instances of 1 | ||
Value.Check(T, [1, 1]) // false - less than 3 instances of 1 | ||
Value.Check(T, [1, 1, 1, 1, 1, 1]) // false - more than 5 instances of 1 | ||
Value.Check(T, [0]) // false - no instances of 1 | ||
``` | ||
|
||
<a name="RegEx-Renamed-To-RegExp"></a> | ||
|
||
## RegEx Renamed To RegExp | ||
|
||
Revision 0.30.0 flags `Type.RegEx` as deprecated but provides `Type.RegExp` as an alternative (matching the JavaScript `RegExp` type name). Additionally this type has also been moved from the `Standard` to `Extended` type set. The `RegExp` type will no longer considered part of the Standard type set due to JavaScript Regular Expressions supporting a wider range of symbols and control characeters than is supported by the ECMA262 subset used by the JSON Schema specification. Information on the ECMA262 subset supported by JSON Schema can be found at the following Url https://json-schema.org/understanding-json-schema/reference/regular_expressions.html | ||
|
||
As `Type.RegEx()` is widely used. TypeBox will retain this type under the `@deprecated` annotation for the 0.30.0 - 0.31.0 revisions. | ||
|
||
```typescript | ||
// Revision 0.29.0 | ||
|
||
const T = Type.RegEx(/abc/) | ||
|
||
// Revision 0.30.0 | ||
|
||
const A = Type.RegEx(/abc/) // deprecation warning! | ||
|
||
const B = Type.RegExp(/abc/) // Extended Type | ||
|
||
const T = Type.String({ pattern: /abc/.source }) // Standard Type | ||
``` | ||
For Unicode (UTF-16) support on 0.30.0, the recommendation is to continue using custom formats. | ||
|
||
```typescript | ||
import { Type, FormatRegistry } from '@sinclair/typebox' | ||
|
||
FormatRegistry.Set('emoji', value => /<a?:.+?:\d{18}>|\p{Extended_Pictographic}/gu.test(value)) | ||
|
||
const T = Type.String({ format: 'emoji' }) | ||
|
||
Value.Check(T, '♥️♦️♠️♣️') // Ok | ||
``` | ||
For information on configuring custom formats on Ajv, refer to https://ajv.js.org/guide/formats.html#user-defined-formats | ||
|
||
|
||
<a name="Reducing-Package-Size"></a> | ||
|
||
## Reducing Package Size | ||
|
||
```typescript | ||
// Revision 0.29.0 | ||
// | ||
┌──────────────────────┬────────────┬────────────┬─────────────┐ | ||
│ (index) │ Compiled │ Minified │ Compression │ | ||
├──────────────────────┼────────────┼────────────┼─────────────┤ | ||
│ typebox/compiler │ '130.3 kb' │ ' 58.2 kb' │ '2.24 x' │ | ||
│ typebox/errors │ '113.3 kb' │ ' 49.8 kb' │ '2.27 x' │ | ||
│ typebox/system │ ' 78.8 kb' │ ' 32.2 kb' │ '2.45 x' │ | ||
│ typebox/value │ '180.0 kb' │ ' 77.7 kb' │ '2.32 x' │ | ||
│ typebox │ ' 77.7 kb' │ ' 31.7 kb' │ '2.45 x' │ | ||
└──────────────────────┴────────────┴────────────┴─────────────┘ | ||
|
||
// Revision 0.30.0 | ||
// | ||
┌──────────────────────┬────────────┬────────────┬─────────────┐ | ||
│ (index) │ Compiled │ Minified │ Compression │ | ||
├──────────────────────┼────────────┼────────────┼─────────────┤ | ||
│ typebox/compiler │ '128.9 kb' │ ' 58.5 kb' │ '2.20 x' │ | ||
│ typebox/errors │ '111.1 kb' │ ' 49.8 kb' │ '2.23 x' │ | ||
│ typebox/system │ ' 75.9 kb' │ ' 31.4 kb' │ '2.42 x' │ | ||
│ typebox/value │ '180.4 kb' │ ' 79.0 kb' │ '2.28 x' │ | ||
│ typebox │ ' 74.8 kb' │ ' 31.0 kb' │ '2.42 x' │ | ||
└──────────────────────┴────────────┴────────────┴─────────────┘ | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/*-------------------------------------------------------------------------- | ||
@sinclair/typebox/transform | ||
The MIT License (MIT) | ||
Copyright (c) 2017-2023 Haydn Paterson (sinclair) <haydn.developer@gmail.com> | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
---------------------------------------------------------------------------*/ | ||
|
||
export * from './transform' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Transform | ||
|
||
Use Transform to apply codec functions to a type. Transform is designed to be used with the Decode and Encode functions to handle automatic encode and decode of JSON values. The following shows transforming Date objects to and from number types. | ||
|
||
```typescript | ||
import { Transform, Encode, Decode } from './transform' | ||
|
||
// Applies codec functions to a type | ||
const Timestamp = Transform(Type.Number(), { | ||
decode: (value) => new Date(value), | ||
encode: (value) => value.getTime(), | ||
}) | ||
// Transform type can be nested within objects | ||
const N = Type.Object({ | ||
timestamp: Timestamp | ||
}) | ||
|
||
// Decodes as { timestamp: Date } | ||
const D = Decode(N, { timestamp: Date.now() }) | ||
|
||
// Encodes as { timestamp: number } | ||
const E = Encode(N, D) | ||
``` |
Oops, something went wrong.