@sinclair/typebox 0.29.3 → 0.29.5

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/errors/errors.js CHANGED
@@ -350,7 +350,7 @@ var ValueErrors;
350
350
  yield { type: ValueErrorType.ObjectMinProperties, schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` };
351
351
  }
352
352
  if (IsDefined(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) {
353
- yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` };
353
+ yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.maxProperties} properties` };
354
354
  }
355
355
  const requiredKeys = globalThis.Array.isArray(schema.required) ? schema.required : [];
356
356
  const knownKeys = globalThis.Object.getOwnPropertyNames(schema.properties);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.29.3",
3
+ "version": "0.29.5",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
@@ -24,10 +24,13 @@
24
24
  "url": "https://github.com/sinclairzx81/typebox"
25
25
  },
26
26
  "scripts": {
27
+ "test:typescript": "hammer task test_typescript",
28
+ "test:static": "hammer task test_static",
29
+ "test:runtime": "hammer task test_runtime",
30
+ "test": "hammer task test",
27
31
  "clean": "hammer task clean",
28
32
  "format": "hammer task format",
29
33
  "start": "hammer task start",
30
- "test": "hammer task test",
31
34
  "benchmark": "hammer task benchmark",
32
35
  "build": "hammer task build",
33
36
  "publish": "hammer task publish"
package/readme.md CHANGED
@@ -11,8 +11,8 @@
11
11
 
12
12
  [![npm version](https://badge.fury.io/js/%40sinclair%2Ftypebox.svg)](https://badge.fury.io/js/%40sinclair%2Ftypebox)
13
13
  [![Downloads](https://img.shields.io/npm/dm/%40sinclair%2Ftypebox.svg)](https://www.npmjs.com/package/%40sinclair%2Ftypebox)
14
- [![GitHub CI](https://github.com/sinclairzx81/typebox/workflows/GitHub%20CI/badge.svg)](https://github.com/sinclairzx81/typebox/actions)
15
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
+ [![Build](https://github.com/sinclairzx81/typebox/actions/workflows/build.yml/badge.svg)](https://github.com/sinclairzx81/typebox/actions/workflows/build.yml)
15
+ [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
16
16
 
17
17
  </div>
18
18
 
@@ -335,15 +335,15 @@ The following table lists the Standard TypeBox types. These types are fully comp
335
335
  │ │ │ } │
336
336
  │ │ │ │
337
337
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
338
- │ const T = Type.Composite([ │ type I = { │ const T = { │
338
+ │ const T = Type.Composite([ │ type T = { │ const T = { │
339
339
  │ Type.Object({ │ x: number │ type: 'object', │
340
340
  │ x: Type.Number() │ } & { │ required: ['x', 'y'], │
341
341
  │ }), │ y: number │ properties: { │
342
342
  │ Type.Object({ │ } │ x: { │
343
343
  │ y: Type.Number() │ │ type: 'number' │
344
- │ }) │ type T = { │ }, │
345
- │ ]) │ [K in keyof I]: I[K] │ y: { │
346
- │ │ } │ type: 'number' │
344
+ │ }) │ │ }, │
345
+ │ ]) │ │ y: { │
346
+ │ │ │ type: 'number' │
347
347
  │ │ │ } │
348
348
  │ │ │ } │
349
349
  │ │ │ } │
@@ -739,12 +739,12 @@ const R = Type.Ref(T) // const R = {
739
739
 
740
740
  ### Recursive Types
741
741
 
742
- Recursive types are supported with `Type.Recursive`
742
+ Recursive types are supported with `Type.Recursive`.
743
743
 
744
744
  ```typescript
745
- const Node = Type.Recursive(Node => Type.Object({ // const Node = {
745
+ const Node = Type.Recursive(This => Type.Object({ // const Node = {
746
746
  id: Type.String(), // $id: 'Node',
747
- nodes: Type.Array(Node) // type: 'object',
747
+ nodes: Type.Array(This) // type: 'object',
748
748
  }), { $id: 'Node' }) // properties: {
749
749
  // id: {
750
750
  // type: 'string'
@@ -776,38 +776,50 @@ function test(node: Node) {
776
776
 
777
777
  ### Conditional Types
778
778
 
779
- Conditional types are supported with `Type.Extends`, `Type.Exclude` and `Type.Extract`
779
+ TypeBox supports conditional types with `Type.Extends`. This type will perform a structural assignment check for the first two parameters and return a `true` or `false` type from the second two parameters. The types `Type.Exclude` and `Type.Extract` are also supported.
780
780
 
781
781
  ```typescript
782
782
  // TypeScript
783
783
 
784
784
  type T0 = string extends number ? true : false // type T0 = false
785
785
 
786
- type T1 = Extract<string | number, number> // type T1 = number
786
+ type T1 = Extract<(1 | 2 | 3), 1> // type T1 = 1
787
787
 
788
- type T2 = Exclude<string | number, number> // type T2 = string
788
+ type T2 = Exclude<(1 | 2 | 3), 1> // type T2 = 2 | 3
789
789
 
790
790
  // TypeBox
791
791
 
792
- const T0 = Type.Extends(Type.String(), Type.Number(), Type.Literal(true), Type.Literal(false))
793
-
794
- const T1 = Type.Extract(Type.Union([Type.String(), Type.Number()]), Type.Number())
795
-
796
- const T2 = Type.Exclude(Type.Union([Type.String(), Type.Number()]), Type.Number())
797
-
798
-
799
- type T0 = Static<typeof T0> // type T0 = false
792
+ const T0 = Type.Extends( // const T0: TLiteral<false>
793
+ Type.String(),
794
+ Type.Number(),
795
+ Type.Literal(true),
796
+ Type.Literal(false)
797
+ )
800
798
 
801
- type T1 = Static<typeof T1> // type T1 = number
799
+ const T1 = Type.Extract( // const T1: TLiteral<1>
800
+ Type.Union([
801
+ Type.Literal(1),
802
+ Type.Literal(2),
803
+ Type.Literal(3)
804
+ ]),
805
+ Type.Literal(1)
806
+ )
802
807
 
803
- type T2 = Static<typeof T2> // type T2 = string
808
+ const T2 = Type.Exclude( // const T2: TUnion<[
809
+ Type.Union([ // TLiteral<2>,
810
+ Type.Literal(1), // TLiteral<3>
811
+ Type.Literal(2), // ]>
812
+ Type.Literal(3)
813
+ ]),
814
+ Type.Literal(1)
815
+ )
804
816
  ```
805
817
 
806
818
  <a name='types-template-literal'></a>
807
819
 
808
820
  ### Template Literal Types
809
821
 
810
- TypeBox supports Template Literal types using `Type.TemplateLiteral`. These types can be created using a simple template DSL syntax, however more complex template literals can be created by passing an array of literal and union types. The examples below show the template DSL syntax.
822
+ TypeBox supports template literal types with `Type.TemplateLiteral`. This type implements an embedded DSL syntax to match the TypeScript template literal syntax. This type can also be composed by passing an array of union and literal types as parameters. The following example shows the DSL syntax.
811
823
 
812
824
  ```typescript
813
825
  // TypeScript
@@ -853,7 +865,7 @@ const R = Type.Record(T, Type.String()) // const R = {
853
865
 
854
866
  ### Indexed Access Types
855
867
 
856
- TypeBox supports Indexed Access types using `Type.Index`. This feature provides a consistent way to access property types without having to extract them from the underlying schema representation. Indexed accessors are supported for object and tuples, as well as nested union and intersect types.
868
+ TypeBox supports indexed access types using `Type.Index`. This type provides a consistent way to access interior property and array element types without having to extract them from the underlying schema representation. Indexed access types are supported for object, array, tuple, union and intersect types.
857
869
 
858
870
  ```typescript
859
871
  const T = Type.Object({ // const T = {
@@ -888,7 +900,7 @@ const C = Type.Index(T, Type.KeyOf(T)) // const C = {
888
900
 
889
901
  ### Not Types
890
902
 
891
- TypeBox has partial support for the JSON schema `not` keyword with `Type.Not`. This type is synonymous with the concept of a [negated types](https://github.com/microsoft/TypeScript/issues/4196) which are not supported in the TypeScript language. TypeBox does provide partial inference support via the intersection of `T & not U` (where all negated types infer as `unknown`). This can be used in the following context.
903
+ TypeBox provides support for the `not` keyword with `Type.Not`. This type is synonymous with [negated types](https://github.com/microsoft/TypeScript/issues/4196) which are not supported in the TypeScript language. Partial inference of this type can be attained via the intersection of `T & not U` (where all Not types infer as `unknown`). This approach can be used to narrow for broader types in the following context.
892
904
 
893
905
  ```typescript
894
906
  // TypeScript
package/typebox.d.ts CHANGED
@@ -103,11 +103,12 @@ export interface TBoolean extends TSchema {
103
103
  }
104
104
  export type TConstructorParameters<T extends TConstructor<TSchema[], TSchema>> = TTuple<T['parameters']>;
105
105
  export type TInstanceType<T extends TConstructor<TSchema[], TSchema>> = T['returns'];
106
- export type TCompositeReduce<T extends TIntersect<TObject[]>, K extends string[]> = K extends [infer L, ...infer R] ? {
106
+ export type TCompositeKeys<T extends TObject[]> = T extends [infer L, ...infer R] ? keyof Assert<L, TObject>['properties'] | TCompositeKeys<Assert<R, TObject[]>> : never;
107
+ export type TCompositeIndex<T extends TIntersect<TObject[]>, K extends string[]> = K extends [infer L, ...infer R] ? {
107
108
  [_ in Assert<L, string>]: TIndexType<T, Assert<L, string>>;
108
- } & TCompositeReduce<T, Assert<R, string[]>> : {};
109
- export type TCompositeSelect<T extends TIntersect<TObject[]>> = UnionToTuple<keyof Static<T>> extends infer K ? Evaluate<TCompositeReduce<T, Assert<K, string[]>>> : {};
110
- export type TComposite<T extends TObject[]> = TIntersect<T> extends infer R ? TObject<TCompositeSelect<Assert<R, TIntersect<TObject[]>>>> : TObject<{}>;
109
+ } & TCompositeIndex<T, Assert<R, string[]>> : {};
110
+ export type TCompositeReduce<T extends TObject[]> = UnionToTuple<TCompositeKeys<T>> extends infer K ? Evaluate<TCompositeIndex<TIntersect<T>, Assert<K, string[]>>> : {};
111
+ export type TComposite<T extends TObject[]> = TIntersect<T> extends TIntersect ? TObject<TCompositeReduce<T>> : TObject<{}>;
111
112
  export type TConstructorParameterArray<T extends readonly TSchema[], P extends unknown[]> = [...{
112
113
  [K in keyof T]: Static<AssertType<T[K]>, P>;
113
114
  }];
@@ -335,13 +336,14 @@ export type TRequiredProperties<T extends TProperties> = Evaluate<AssertProperti
335
336
  [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? TReadonly<U> : T[K] extends TReadonly<infer U> ? TReadonly<U> : T[K] extends TOptional<infer U> ? U : T[K];
336
337
  }>>;
337
338
  export type TRequired<T extends TSchema> = T extends TRecursive<infer S> ? TRecursive<TRequired<S>> : T extends TIntersect<infer S> ? TIntersect<TRequiredArray<S>> : T extends TUnion<infer S> ? TUnion<TRequiredArray<S>> : T extends TObject<infer S> ? TObject<TRequiredProperties<S>> : T;
338
- export type StringFormatOption = 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex';
339
+ export type StringFormatOption = 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex' | ({} & string);
340
+ export type StringContentEncodingOption = '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64' | ({} & string);
339
341
  export interface StringOptions extends SchemaOptions {
340
342
  minLength?: number;
341
343
  maxLength?: number;
342
344
  pattern?: string;
343
- format?: string;
344
- contentEncoding?: '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64';
345
+ format?: StringFormatOption;
346
+ contentEncoding?: StringContentEncodingOption;
345
347
  contentMediaType?: string;
346
348
  }
347
349
  export interface TString extends TSchema, StringOptions {