Skip to content

Commit

Permalink
Revision 0.34.7 (#1093)
Browse files Browse the repository at this point in the history
* Revert Ref(Schema) Signature with Deprecation Notice

* ChangeLog

* Version
  • Loading branch information
sinclairzx81 authored Nov 21, 2024
1 parent b13b3c3 commit b05c59c
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 17 deletions.
2 changes: 2 additions & 0 deletions changelog/0.34.0.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
### 0.34.0
- [Revision 0.34.7](https://github.com/sinclairzx81/typebox/pull/1093)
- Revert Ref(Schema) Signature with Deprecation Notice
- [Revision 0.34.6](https://github.com/sinclairzx81/typebox/pull/1090)
- Add Computed To Type and Kind Guards (IsSchema)
- [Revision 0.34.5](https://github.com/sinclairzx81/typebox/pull/1088)
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.34.6",
"version": "0.34.7",
"description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
Expand Down
10 changes: 1 addition & 9 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,15 +534,7 @@ The following table lists the supported Json types. These types are fully compat
│ │ │ } │
│ │ │ │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
const T = Type.Object({ │ type T = { │ const R = { │
│ x: Type.Number(), │ x: number, │ $ref: 'T'
y: Type.Number() │ y: number │ } │
│ }, { $id: 'T' }) | } │ │
│ │ │ │
const R = Type.Ref(T) │ type R = T │ │
│ │ │ │
│ │ │ │
│ │ │ │
const R = Type.Ref('T') │ type R = unknownconst R = { $ref: 'T' } │
│ │ │ │
└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
```
Expand Down
28 changes: 27 additions & 1 deletion src/type/ref/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

import type { TSchema, SchemaOptions } from '../schema/index'
import { TypeBoxError } from '../error/index'
import { CreateType } from '../create/type'
import { Kind } from '../symbols/index'
import { TUnsafe } from '../unsafe/index'
import { Static } from '../static/index'

// ------------------------------------------------------------------
// TRef
Expand All @@ -38,7 +41,30 @@ export interface TRef<Ref extends string = string> extends TSchema {
static: unknown
$ref: Ref
}

export type TRefUnsafe<Type extends TSchema> = TUnsafe<Static<Type>>

/** `[Json]` Creates a Ref type.*/
export function Ref<Ref extends string>($ref: Ref, options?: SchemaOptions): TRef<Ref>
/**
* @deprecated `[Json]` Creates a Ref type. The referenced type MUST contain a $id. The Ref(TSchema) signature was
* deprecated on 0.34.0 in support of a new type referencing model (Module). Existing implementations using Ref(TSchema)
* can migrate using the following. The Ref(TSchema) validation behavior of Ref will be preserved how the construction
* of legacy Ref(TSchema) will require wrapping in TUnsafe (where TUnsafe is used for inference only)
*
* ```typescript
* const R = Type.Ref(T)
* ```
* to
*
* ```typescript
* const R = Type.Unsafe<Static<T>>(T.$id)
* ```
*/
export function Ref<Type extends TSchema>(type: Type, options?: SchemaOptions): TRefUnsafe<Type>
/** `[Json]` Creates a Ref type. The referenced type must contain a $id */
export function Ref<Ref extends string>($ref: Ref, options?: SchemaOptions): TRef<Ref> {
export function Ref(...args: any[]): unknown {
const [$ref, options] = typeof args[0] === 'string' ? [args[0], args[1]] : [args[0].$id, args[1]]
if (typeof $ref !== 'string') throw new TypeBoxError('Ref: $ref must be a string')
return CreateType({ [Kind]: 'Ref', $ref }, options) as never
}
27 changes: 23 additions & 4 deletions src/type/type/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import { Readonly, type TReadonlyWithFlag, type TReadonlyFromMappedResult } from
import { ReadonlyOptional, type TReadonlyOptional } from '../readonly-optional/index'
import { Record, type TRecordOrObject } from '../record/index'
import { Recursive, type TRecursive, type TThis } from '../recursive/index'
import { Ref, type TRef } from '../ref/index'
import { Ref, type TRef, type TRefUnsafe } from '../ref/index'
import { Required, type TRequired, type TRequiredFromMappedResult } from '../required/index'
import { Rest, type TRest } from '../rest/index'
import { type TSchema, type SchemaOptions } from '../schema/index'
Expand Down Expand Up @@ -259,9 +259,28 @@ export class JsonTypeBuilder {
public Recursive<T extends TSchema>(callback: (thisType: TThis) => T, options?: SchemaOptions): TRecursive<T> {
return Recursive(callback, options)
}
/** `[Json]` Creates a Ref type. */
public Ref<Ref extends string>($ref: Ref, options?: SchemaOptions): TRef<Ref> {
return Ref($ref, options)

/** `[Json]` Creates a Ref type.*/
public Ref<Ref extends string>($ref: Ref, options?: SchemaOptions): TRef<Ref>
/**
* @deprecated `[Json]` Creates a Ref type. The referenced type MUST contain a $id. The Ref(TSchema) signature was
* deprecated on 0.34.0 in support of a new type referencing model (Module). Existing implementations using Ref(TSchema)
* can migrate using the following. The Ref(TSchema) validation behavior of Ref will be preserved how the construction
* of legacy Ref(TSchema) will require wrapping in TUnsafe (where TUnsafe is used for inference only)
*
* ```typescript
* const R = Type.Ref(T)
* ```
* to
*
* ```typescript
* const R = Type.Unsafe<Static<T>>(T.$id)
* ```
*/
public Ref<Type extends TSchema>(type: Type, options?: SchemaOptions): TRefUnsafe<Type>
/** `[Json]` Creates a Ref type. The referenced type must contain a $id */
public Ref(...args: any[]): unknown {
return Ref(args[0] as string, args[1])
}
/** `[Json]` Constructs a type where all properties are required */
public Required<MappedResult extends TMappedResult>(type: MappedResult, options?: SchemaOptions): TRequiredFromMappedResult<MappedResult>
Expand Down
12 changes: 12 additions & 0 deletions test/runtime/compiler-ajv/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import { Type } from '@sinclair/typebox'
import { Ok, Fail } from './validate'

describe('compiler-ajv/Ref', () => {
// ----------------------------------------------------------------
// Deprecated
// ----------------------------------------------------------------
it('Should validate for Ref(Schema)', () => {
const T = Type.Number({ $id: 'T' })
const R = Type.Ref(T)
Ok(R, 1234, [T])
Fail(R, 'hello', [T])
})
// ----------------------------------------------------------------
// Standard
// ----------------------------------------------------------------
it('Should should validate when referencing a type', () => {
const T = Type.Object(
{
Expand Down
12 changes: 12 additions & 0 deletions test/runtime/compiler/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ import { Ok, Fail } from './validate'
import { Assert } from '../assert/index'

describe('compiler/Ref', () => {
// ----------------------------------------------------------------
// Deprecated
// ----------------------------------------------------------------
it('Should validate for Ref(Schema)', () => {
const T = Type.Number({ $id: 'T' })
const R = Type.Ref(T)
Ok(R, 1234, [T])
Fail(R, 'hello', [T])
})
// ----------------------------------------------------------------
// Standard
// ----------------------------------------------------------------
it('Should should validate when referencing a type', () => {
const T = Type.Object(
{
Expand Down
21 changes: 21 additions & 0 deletions test/runtime/type/guard/kind/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@ import { Type } from '@sinclair/typebox'
import { Assert } from '../../../assert/index'

describe('guard/kind/TRef', () => {
// ----------------------------------------------------------------
// Deprecated
// ----------------------------------------------------------------
it('Should guard for Ref(Schema) 1', () => {
const T = Type.Number({ $id: 'T' })
const R = Type.Ref(T)
Assert.IsTrue(KindGuard.IsRef(R))
Assert.IsTrue(typeof R['$ref'] === 'string')
})
it('Should guard for Ref(Schema) 2', () => {
const T = Type.Number()
Assert.Throws(() => Type.Ref(T))
})
it('Should guard for Ref(Schema) 3', () => {
// @ts-ignore
const T = Type.Number({ $id: null })
Assert.Throws(() => Type.Ref(T))
})
// ----------------------------------------------------------------
// Standard
// ----------------------------------------------------------------
it('Should guard for TRef', () => {
const T = Type.Number({ $id: 'T' })
const R = KindGuard.IsRef(Type.Ref(T))
Expand Down
21 changes: 21 additions & 0 deletions test/runtime/type/guard/type/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@ import { Type, CloneType } from '@sinclair/typebox'
import { Assert } from '../../../assert/index'

describe('guard/type/TRef', () => {
// ----------------------------------------------------------------
// Deprecated
// ----------------------------------------------------------------
it('Should guard for Ref(Schema) 1', () => {
const T = Type.Number({ $id: 'T' })
const R = Type.Ref(T)
Assert.IsTrue(TypeGuard.IsRef(R))
Assert.IsTrue(typeof R['$ref'] === 'string')
})
it('Should guard for Ref(Schema) 2', () => {
const T = Type.Number()
Assert.Throws(() => Type.Ref(T))
})
it('Should guard for Ref(Schema) 3', () => {
// @ts-ignore
const T = Type.Number({ $id: null })
Assert.Throws(() => Type.Ref(T))
})
// ----------------------------------------------------------------
// Standard
// ----------------------------------------------------------------
it('Should guard for TRef', () => {
const T = Type.Number({ $id: 'T' })
const R = TypeGuard.IsRef(Type.Ref('T'))
Expand Down
12 changes: 12 additions & 0 deletions test/runtime/value/check/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ import { Type } from '@sinclair/typebox'
import { Assert } from '../../assert/index'

describe('value/check/Ref', () => {
// ----------------------------------------------------------------
// Deprecated
// ----------------------------------------------------------------
it('Should validate for Ref(Schema)', () => {
const T = Type.Number({ $id: 'T' })
const R = Type.Ref(T)
Assert.IsTrue(Value.Check(T, [T], 1234))
Assert.IsFalse(Value.Check(T, [T], 'hello'))
})
// ----------------------------------------------------------------
// Standard
// ----------------------------------------------------------------
it('Should should validate when referencing a type', () => {
const T = Type.Object(
{
Expand Down

0 comments on commit b05c59c

Please sign in to comment.