Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Dates with Current Time #671

Merged
merged 5 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.31.26",
"version": "0.31.27",
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
Expand Down
26 changes: 22 additions & 4 deletions src/typebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,10 @@ export namespace ValueGuard {
export function IsBoolean(value: unknown): value is boolean {
return typeof value === 'boolean'
}
/** Returns true if this value is a Date object */
export function IsDate(value: unknown): value is Date {
return value instanceof globalThis.Date
}
/** Returns true if this value is null */
export function IsNull(value: unknown): value is null {
return value === null
Expand All @@ -1103,6 +1107,10 @@ export namespace ValueGuard {
export function IsString(value: unknown): value is string {
return typeof value === 'string'
}
/** Returns true if this value is a Uint8Array */
export function IsUint8Array(value: unknown): value is Uint8Array {
return value instanceof globalThis.Uint8Array
}
/** Returns true if this value is undefined */
export function IsUndefined(value: unknown): value is undefined {
return value === undefined
Expand Down Expand Up @@ -2287,19 +2295,29 @@ export namespace TypeExtends {
// --------------------------------------------------------------------------
/** Specialized Clone for Types */
export namespace TypeClone {
function ArrayType(value: unknown[]) {
return (value as any).map((value: unknown) => Visit(value as any))
}
function DateType(value: Date) {
return new Date(value.getTime())
}
function Uint8ArrayType(value: Uint8Array) {
return new Uint8Array(value)
}
function ObjectType(value: Record<keyof any, unknown>) {
const clonedProperties = Object.getOwnPropertyNames(value).reduce((acc, key) => ({ ...acc, [key]: Visit(value[key]) }), {})
const clonedSymbols = Object.getOwnPropertySymbols(value).reduce((acc, key) => ({ ...acc, [key]: Visit(value[key as any]) }), {})
return { ...clonedProperties, ...clonedSymbols }
}
function ArrayType(value: unknown[]) {
return (value as any).map((value: unknown) => Visit(value as any))
}
function Visit(value: unknown): any {
// prettier-ignore
return ValueGuard.IsArray(value) ? ArrayType(value) :
return (
ValueGuard.IsArray(value) ? ArrayType(value) :
ValueGuard.IsDate(value) ? DateType(value) :
ValueGuard.IsUint8Array(value) ? Uint8ArrayType(value) :
ValueGuard.IsObject(value) ? ObjectType(value) :
value
)
}
/** Clones a Rest */
export function Rest<T extends TSchema[]>(schemas: [...T]): T {
Expand Down
2 changes: 1 addition & 1 deletion src/value/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function TDate(schema: Types.TDate, references: Types.TSchema[]): any {
} else if (schema.minimumTimestamp !== undefined) {
return new Date(schema.minimumTimestamp)
} else {
return new Date(0)
return new Date()
}
}
function TFunction(schema: Types.TFunction, references: Types.TSchema[]): any {
Expand Down
5 changes: 5 additions & 0 deletions test/runtime/assert/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export namespace Assert {
export function NotEqual(actual: unknown, expect: unknown) {
return assert.notEqual(actual, expect)
}
/** Asserts a numeric value is within range of the expected */
export function InRange(value: number, expect: number, range: number) {
if (Math.abs(value - expect) <= range) return
throw Error('Expected value to be in range')
}
let nextIdOrdinal = 0
export function NextId() {
return `$id-${nextIdOrdinal++}`
Expand Down
10 changes: 5 additions & 5 deletions test/runtime/value/cast/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@ describe('value/cast/Date', () => {
it('Should upcast from string', () => {
const value = 'world'
const result = Value.Cast(T, value)
Assert.IsEqual(result, E)
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
})
it('Should upcast from object', () => {
const value = {}
const result = Value.Cast(T, value)
Assert.IsEqual(result, E)
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
})
it('Should upcast from array', () => {
const value = [1]
const result = Value.Cast(T, value)
Assert.IsEqual(result, E)
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
})
it('Should upcast from undefined', () => {
const value = undefined
const result = Value.Cast(T, value)
Assert.IsEqual(result, E)
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
})
it('Should upcast from null', () => {
const value = null
const result = Value.Cast(T, value)
Assert.IsEqual(result, E)
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
})
it('Should preseve', () => {
const value = new Date(100)
Expand Down
30 changes: 30 additions & 0 deletions test/runtime/value/create/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Value } from '@sinclair/typebox/value'
import { Type } from '@sinclair/typebox'
import { Assert } from '../../assert/index'

describe('value/create/Date', () => {
it('Should create value', () => {
const T = Type.Date()
const A = Value.Create(T)
const B = new Date()
Assert.InRange(A.getTime(), B.getTime(), 1000)
})
it('Should create default', () => {
const T = Type.Date({ default: new Date(1001) })
const A = Value.Create(T)
const B = new Date(1001)
Assert.IsEqual(A, B)
})
it('Should create value nested', () => {
const T = Type.Object({ value: Type.Date() })
const A = Value.Create(T)
const B = { value: new Date() }
Assert.InRange(A.value.getTime(), B.value.getTime(), 1000)
})
it('Should create default nested', () => {
const T = Type.Object({ value: Type.Date({ default: new Date(1001) }) })
const A = Value.Create(T)
const B = { value: new Date(1001) }
Assert.IsEqual(A, B)
})
})
1 change: 1 addition & 0 deletions test/runtime/value/create/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import './bigint'
import './boolean'
import './composite'
import './constructor'
import './date'
import './enum'
import './function'
import './integer'
Expand Down
8 changes: 8 additions & 0 deletions test/runtime/value/create/uint8array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ describe('value/create/Uint8Array', () => {
Assert.IsEqual(value.length, 4)
Assert.IsEqual([value[0], value[1], value[2], value[3]], [0, 0, 0, 0])
})
it('Should create value nested', () => {
const T = Type.Object({ value: Type.Uint8Array() })
Assert.IsEqual(Value.Create(T), { value: new Uint8Array() })
})
it('Should create default nested', () => {
const T = Type.Object({ value: Type.Date({ default: new Uint8Array([1, 2, 3, 4]) }) })
Assert.IsEqual(Value.Create(T), { value: new Uint8Array([1, 2, 3, 4]) })
})
})
4 changes: 2 additions & 2 deletions test/runtime/value/transform/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ describe('value/transform/Date', () => {
// --------------------------------------------------------
const T1 = Type.Transform(Type.Date())
.Decode((value) => 1)
.Encode((value) => new Date())
.Encode((value) => new Date(0))
it('Should decode mapped', () => {
const R = Encoder.Decode(T1, new Date())
const R = Encoder.Decode(T1, new Date(0))
Assert.IsEqual(R, 1)
})
it('Should encode mapped', () => {
Expand Down
Loading