@nmtjs/type
Advanced tools
Comparing version 0.2.1 to 0.3.0
import { TypeCompiler } from '@sinclair/typebox/compiler'; | ||
import { Value } from '@sinclair/typebox/value'; | ||
import { typeFinalSchema } from "./types/base.js"; | ||
import { getTypeSchema } from "./types/base.js"; | ||
const compileType = (type)=>{ | ||
const schema = type[typeFinalSchema]; | ||
const schema = getTypeSchema(type); | ||
const compiled = TypeCompiler.Compile(schema); | ||
@@ -7,0 +7,0 @@ const prepare = (value)=>{ |
import { ArrayType } from "./types/array.js"; | ||
import { BooleanType } from "./types/boolean.js"; | ||
import { CustomType } from "./types/custom.js"; | ||
import { DateTimeType, DateType } from "./types/datetime.js"; | ||
import { DateType } from "./types/datetime.js"; | ||
import { EnumType, NativeEnumType } from "./types/enum.js"; | ||
@@ -19,3 +19,3 @@ import { LiteralType } from "./types/literal.js"; | ||
export { BaseType, getTypeSchema } from "./types/base.js"; | ||
export { ArrayType, BooleanType, CustomType, DateTimeType, DateType, EnumType, LiteralType, IntegerType, NumberType, ObjectType, StringType, IntersactionType, UnionType, AnyType, NeverType, }; | ||
export { ArrayType, BooleanType, CustomType, DateType, EnumType, LiteralType, IntegerType, NumberType, ObjectType, StringType, IntersactionType, UnionType, AnyType, NeverType, }; | ||
export var t; | ||
@@ -32,3 +32,2 @@ (function(t) { | ||
t.date = ()=>new DateType(); | ||
t.datetime = ()=>new DateTimeType(); | ||
t.array = (element)=>new ArrayType(element); | ||
@@ -35,0 +34,0 @@ t.object = (properties)=>new ObjectType(properties); |
@@ -0,3 +1,4 @@ | ||
import { t as baseT } from "./index.js"; | ||
import { DurationType, PlainDateTimeType, PlainDateType, PlainMonthDayType, PlainTimeType, PlainYearMonthType, ZonedDateTimeType } from "./types/temporal.js"; | ||
export function extend(value) { | ||
function extend(value) { | ||
return Object.assign({}, value, { | ||
@@ -15,2 +16,3 @@ temporal: { | ||
} | ||
export const t = extend(baseT); | ||
export { DurationType, PlainDateTimeType, PlainDateType, PlainMonthDayType, PlainTimeType, PlainYearMonthType, ZonedDateTimeType, }; |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType } from "./base.js"; | ||
export class AnyType extends BaseType { | ||
constructor(schema = Type.Any(), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Any(options); | ||
} | ||
nullable() { | ||
return new AnyType(...this._nullable()); | ||
return new AnyType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
return new AnyType(...this._optional()); | ||
return new AnyType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
return new AnyType(...this._nullish()); | ||
return new AnyType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new AnyType(...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new AnyType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new AnyType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType, typeFinalSchema } from "./base.js"; | ||
import { BaseType, getTypeSchema } from "./base.js"; | ||
export class ArrayType extends BaseType { | ||
element; | ||
options; | ||
constructor(element, options = {}, nullable = false, optional = false){ | ||
super(Type.Array(element[typeFinalSchema]), nullable, optional); | ||
constructor(element, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault, element); | ||
this.element = element; | ||
this.options = options; | ||
} | ||
_constructSchema(options, element) { | ||
return Type.Array(getTypeSchema(element), options); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new ArrayType(this.element, this.options, ...args); | ||
return new ArrayType(this.element, ...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new ArrayType(this.element, this.options, ...args); | ||
return new ArrayType(this.element, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new ArrayType(this.element, this.options, ...args); | ||
return new ArrayType(this.element, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new ArrayType(this.element, ...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new ArrayType(this.element, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new ArrayType(this.element, ...this._with({ | ||
options: { | ||
example: examples[0], | ||
examples | ||
} | ||
})); | ||
} | ||
min(value) { | ||
return new ArrayType(this.element, { | ||
...this.options, | ||
minItems: value | ||
}, ...this._isNullableOptional); | ||
return new ArrayType(this.element, ...this._with({ | ||
options: { | ||
minItems: value | ||
} | ||
})); | ||
} | ||
max(value) { | ||
return new ArrayType(this.element, { | ||
...this.options, | ||
maxItems: value | ||
}, ...this._isNullableOptional); | ||
return new ArrayType(this.element, ...this._with({ | ||
options: { | ||
maxItems: value | ||
} | ||
})); | ||
} | ||
length(value) { | ||
return new ArrayType(this.element, { | ||
...this.options, | ||
minItems: value, | ||
maxItems: value | ||
}, ...this._isNullableOptional); | ||
return new ArrayType(this.element, ...this._with({ | ||
options: { | ||
minItems: value, | ||
maxItems: value | ||
} | ||
})); | ||
} | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { typeSchema, typeStatic } from "../constants.js"; | ||
import { Nullable } from "../schemas/nullable.js"; | ||
export const typeSchema = Symbol(); | ||
export const typeOptions = Symbol(); | ||
export const typeOptional = Symbol(); | ||
export const typeNullable = Symbol(); | ||
export const staticType = Symbol(); | ||
export const typeFinalSchema = Symbol(); | ||
export class BaseType { | ||
[typeSchema]; | ||
[typeNullable]; | ||
[typeOptional]; | ||
[staticType]; | ||
constructor(schema, nullable = false, optional = false){ | ||
this[typeSchema] = schema; | ||
this[typeNullable] = nullable; | ||
this[typeOptional] = optional; | ||
} | ||
get [typeFinalSchema]() { | ||
let schema = this._schema; | ||
if (this._isNullable) { | ||
options; | ||
isNullable; | ||
isOptional; | ||
hasDefault; | ||
[typeStatic]; | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false, ...contstructArgs){ | ||
this.options = options; | ||
this.isNullable = isNullable; | ||
this.isOptional = isOptional; | ||
this.hasDefault = hasDefault; | ||
let schema = this._constructSchema(options, ...contstructArgs); | ||
if (this.isNullable) { | ||
schema = Nullable(schema); | ||
} | ||
if (this._isOptional) { | ||
if (this.isOptional) { | ||
schema = Type.Optional(schema); | ||
} | ||
return schema; | ||
this[typeSchema] = schema; | ||
} | ||
get _schema() { | ||
return this[typeSchema]; | ||
[typeSchema]; | ||
get _args() { | ||
return [ | ||
this.isNullable, | ||
this.isOptional, | ||
this.hasDefault | ||
]; | ||
} | ||
get _isNullable() { | ||
return this[typeNullable]; | ||
} | ||
get _isOptional() { | ||
return this[typeOptional]; | ||
} | ||
get _isNullableOptional() { | ||
_with({ options = this.options, isNullable = this.isNullable, isOptional = this.isOptional, hasDefault = this.hasDefault } = {}) { | ||
return [ | ||
this._isNullable, | ||
this._isOptional | ||
{ | ||
...this.options, | ||
...options | ||
}, | ||
isNullable, | ||
isOptional, | ||
hasDefault | ||
]; | ||
} | ||
_contructSelf(...args) { | ||
return args; | ||
} | ||
_nullable() { | ||
return this._contructSelf(this._schema, true, this[typeOptional]); | ||
} | ||
_optional() { | ||
return this._contructSelf(this._schema, this[typeNullable], true); | ||
} | ||
_nullish() { | ||
return this._contructSelf(this._schema, true, true); | ||
} | ||
default(value) { | ||
return this._contructSelf({ | ||
...this._schema, | ||
default: value | ||
}, this[typeNullable], this[typeOptional]); | ||
} | ||
description(description) { | ||
return this._contructSelf({ | ||
...this._schema, | ||
description | ||
}, this[typeNullable], this[typeOptional]); | ||
} | ||
examples(...examples) { | ||
return this._contructSelf({ | ||
...this._schema, | ||
examples | ||
}, this[typeNullable], this[typeOptional]); | ||
} | ||
} | ||
export function getTypeSchema(type) { | ||
return type[typeFinalSchema]; | ||
return type[typeSchema]; | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType } from "./base.js"; | ||
export class BooleanType extends BaseType { | ||
constructor(schema = Type.Boolean(), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Boolean(options); | ||
} | ||
nullable() { | ||
return new BooleanType(...this._nullable()); | ||
return new BooleanType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
return new BooleanType(...this._optional()); | ||
return new BooleanType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
return new BooleanType(...this._nullish()); | ||
return new BooleanType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new BooleanType(...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new BooleanType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new BooleanType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} |
@@ -6,19 +6,48 @@ import { Type } from '@sinclair/typebox'; | ||
encode; | ||
constructor(decode, encode, nullable = false, optional = false){ | ||
super(Type.Optional(Type.Transform(Type.Any()).Decode(decode).Encode(encode)), nullable, optional); | ||
constructor(decode, encode, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault, decode, encode); | ||
this.decode = decode; | ||
this.encode = encode; | ||
} | ||
_constructSchema(options, decode, encode) { | ||
return Type.Transform(Type.Any(options)).Decode(decode).Encode(encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new CustomType(this.decode, this.encode, ...args); | ||
return new CustomType(this.decode, this.encode, ...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new CustomType(this.decode, this.encode, ...args); | ||
return new CustomType(this.decode, this.encode, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new CustomType(this.decode, this.encode, ...args); | ||
return new CustomType(this.decode, this.encode, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new CustomType(this.decode, this.encode, ...this._with({ | ||
options: { | ||
default: this.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new CustomType(this.decode, this.encode, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new CustomType(this.decode, this.encode, ...this._with({ | ||
options: { | ||
examples: examples.map(this.encode) | ||
} | ||
})); | ||
} | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType } from "./base.js"; | ||
const decode = (value)=>new Date(value); | ||
const encode = (value)=>value.toISOString(); | ||
export class DateType extends BaseType { | ||
constructor(schema = Type.Transform(Type.String({ | ||
format: 'date' | ||
})).Decode((value)=>new Date(value)).Encode((value)=>value.toJSON()), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options, | ||
format: 'date-time' | ||
})).Decode(decode).Encode(encode); | ||
} | ||
nullable() { | ||
return new DateType(...this._nullable()); | ||
return new DateType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
return new DateType(...this._optional()); | ||
return new DateType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
return new DateType(...this._nullish()); | ||
return new DateType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
} | ||
export class DateTimeType extends BaseType { | ||
constructor(schema = Type.Transform(Type.String({ | ||
format: 'date-time' | ||
})).Decode((value)=>new Date(value)).Encode((value)=>value.toJSON()), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
default(value) { | ||
return new DateType(...this._with({ | ||
options: { | ||
default: encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
nullable() { | ||
return new DateTimeType(...this._nullable()); | ||
description(value) { | ||
return new DateType(...this._with({ | ||
options: { | ||
description: value | ||
} | ||
})); | ||
} | ||
optional() { | ||
return new DateTimeType(...this._optional()); | ||
examples(...values) { | ||
return new DateType(...this._with({ | ||
options: { | ||
examples: values.map(encode) | ||
} | ||
})); | ||
} | ||
nullish() { | ||
return new DateTimeType(...this._nullish()); | ||
} | ||
} |
@@ -6,37 +6,95 @@ import { NativeEnum } from "../schemas/native-enum.js"; | ||
values; | ||
constructor(values, nullable = false, optional = false){ | ||
super(NativeEnum(values), nullable, optional); | ||
constructor(values, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
this.values = values; | ||
} | ||
_constructSchema(options) { | ||
return NativeEnum(this.values, options); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new NativeEnumType(this.values, ...args); | ||
return new NativeEnumType(this.values, ...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new NativeEnumType(this.values, ...args); | ||
return new NativeEnumType(this.values, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new NativeEnumType(this.values, ...args); | ||
return new NativeEnumType(this.values, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new NativeEnumType(this.values, ...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new NativeEnumType(this.values, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new NativeEnumType(this.values, ...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} | ||
export class EnumType extends BaseType { | ||
values; | ||
constructor(values, nullable = false, optional = false){ | ||
super(UnionEnum(values), nullable, optional); | ||
constructor(values, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault, values); | ||
this.values = values; | ||
} | ||
_constructSchema(options, values) { | ||
return UnionEnum(values, options); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new EnumType(this.values, ...args); | ||
return new EnumType(this.values, ...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new EnumType(this.values, ...args); | ||
return new EnumType(this.values, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new EnumType(this.values, ...args); | ||
return new EnumType(this.values, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new EnumType(this.values, ...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new EnumType(this.values, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new EnumType(this.values, ...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} |
@@ -5,18 +5,45 @@ import { Type } from '@sinclair/typebox'; | ||
value; | ||
constructor(value, nullable = false, optional = false){ | ||
super(Type.Literal(value), nullable, optional); | ||
constructor(value, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault, value); | ||
this.value = value; | ||
} | ||
_constructSchema(options, value) { | ||
return Type.Literal(value, options); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new LiteralType(this.value, ...args); | ||
return new LiteralType(this.value, this.options, true, this.isOptional); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new LiteralType(this.value, ...args); | ||
return new LiteralType(this.value, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new LiteralType(this.value, ...args); | ||
return new LiteralType(this.value, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value = this.value) { | ||
return new LiteralType(this.value, ...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new LiteralType(this.value, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new LiteralType(this.value, ...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType } from "./base.js"; | ||
export class NeverType extends BaseType { | ||
constructor(schema = Type.Never(), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
constructor(options = {}){ | ||
super(options, false, false, false); | ||
} | ||
_constructSchema(options) { | ||
return Type.Never(options); | ||
} | ||
nullable() { | ||
@@ -16,2 +19,14 @@ throw new Error('NeverType cannot be nullable'); | ||
} | ||
default() { | ||
throw new Error('NeverType cannot have a default value'); | ||
} | ||
description(description) { | ||
return new NeverType({ | ||
...this.options, | ||
description | ||
}); | ||
} | ||
examples() { | ||
throw new Error('NeverType cannot have examples'); | ||
} | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType } from "./base.js"; | ||
export class NumberType extends BaseType { | ||
constructor(schema = Type.Number(), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
options; | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
this.options = options; | ||
} | ||
_constructSchema(options) { | ||
return Type.Number(options); | ||
} | ||
nullable() { | ||
return new NumberType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
return new NumberType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
return new NumberType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new NumberType(...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new NumberType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new NumberType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
positive() { | ||
return new NumberType(Type.Number({ | ||
...this._schema, | ||
minimum: 0, | ||
exclusiveMinimum: 0 | ||
}), ...this._isNullableOptional); | ||
return this.min(0, true); | ||
} | ||
negative() { | ||
return new NumberType(Type.Number({ | ||
...this._schema, | ||
maximum: 0, | ||
exclusiveMaximum: 0 | ||
}), ...this._isNullableOptional); | ||
return this.max(0, true); | ||
} | ||
max(value, exclusive) { | ||
return new NumberType(Type.Number({ | ||
...this._schema, | ||
maximum: value, | ||
...exclusive ? {} : { | ||
exclusiveMaximum: value | ||
return new NumberType(...this._with({ | ||
options: { | ||
maximum: value, | ||
...exclusive ? {} : { | ||
exclusiveMaximum: value | ||
} | ||
} | ||
}), ...this._isNullableOptional); | ||
})); | ||
} | ||
min(value, exclusive) { | ||
return new NumberType(Type.Number({ | ||
...this._schema, | ||
minimum: value, | ||
...exclusive ? {} : { | ||
exclusiveMinimum: value | ||
return new NumberType(...this._with({ | ||
options: { | ||
minimum: value, | ||
...exclusive ? {} : { | ||
exclusiveMinimum: value | ||
} | ||
} | ||
}), ...this._isNullableOptional); | ||
})); | ||
} | ||
} | ||
export class IntegerType extends BaseType { | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Integer(options); | ||
} | ||
nullable() { | ||
return new NumberType(...this._nullable()); | ||
return new IntegerType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
return new NumberType(...this._optional()); | ||
return new IntegerType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
return new NumberType(...this._nullish()); | ||
return new IntegerType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
} | ||
export class IntegerType extends BaseType { | ||
constructor(schema = Type.Integer(), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
default(value) { | ||
return new IntegerType(...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new IntegerType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new IntegerType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
positive() { | ||
return new IntegerType(Type.Integer({ | ||
...this._schema, | ||
minimum: 0, | ||
exclusiveMinimum: 0 | ||
}), ...this._isNullableOptional); | ||
return this.min(0, true); | ||
} | ||
negative() { | ||
return new IntegerType(Type.Integer({ | ||
...this._schema, | ||
maximum: 0, | ||
exclusiveMaximum: 0 | ||
}), ...this._isNullableOptional); | ||
return this.max(0, true); | ||
} | ||
max(value, exclusive) { | ||
return new IntegerType(Type.Integer({ | ||
...this._schema, | ||
maximum: value, | ||
...exclusive ? {} : { | ||
exclusiveMaximum: value | ||
return new IntegerType(...this._with({ | ||
options: { | ||
maximum: value, | ||
...exclusive ? {} : { | ||
exclusiveMaximum: value | ||
} | ||
} | ||
}), ...this._isNullableOptional); | ||
})); | ||
} | ||
min(value, exclusive) { | ||
return new IntegerType(Type.Integer({ | ||
...this._schema, | ||
minimum: value, | ||
...exclusive ? {} : { | ||
exclusiveMinimum: value | ||
return new IntegerType(...this._with({ | ||
options: { | ||
minimum: value, | ||
...exclusive ? {} : { | ||
exclusiveMinimum: value | ||
} | ||
} | ||
}), ...this._isNullableOptional); | ||
})); | ||
} | ||
nullable() { | ||
return new IntegerType(...this._nullable()); | ||
} | ||
optional() { | ||
return new IntegerType(...this._optional()); | ||
} | ||
nullish() { | ||
return new IntegerType(...this._nullish()); | ||
} | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType, typeFinalSchema } from "./base.js"; | ||
import { BaseType, getTypeSchema } from "./base.js"; | ||
import { EnumType } from "./enum.js"; | ||
export class ObjectType extends BaseType { | ||
properties; | ||
constructor(properties = {}, nullable = false, optional = false){ | ||
const schemaProperties = Object.fromEntries(Object.entries(properties).map(([key, value])=>[ | ||
key, | ||
value[typeFinalSchema] | ||
])); | ||
super(Type.Object(schemaProperties), nullable, optional); | ||
constructor(properties = {}, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault, properties); | ||
this.properties = properties; | ||
} | ||
_constructSchema(options, properties) { | ||
const schemaProperties = {}; | ||
for (const [key, value] of Object.entries(properties)){ | ||
schemaProperties[key] = getTypeSchema(value); | ||
} | ||
return Type.Object(schemaProperties, options); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new ObjectType(this.properties, ...args); | ||
return new ObjectType(this.properties, ...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new ObjectType(this.properties, ...args); | ||
return new ObjectType(this.properties, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new ObjectType(this.properties, ...args); | ||
return new ObjectType(this.properties, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new ObjectType(this.properties, ...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new ObjectType(this.properties, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new ObjectType(this.properties, ...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
pick(pick) { | ||
const properties = Object.fromEntries(Object.entries(this.properties).filter(([key])=>pick[key])); | ||
return new ObjectType(properties, ...this._isNullableOptional); | ||
const [_, ...args] = this._with(); | ||
return new ObjectType(properties, {}, ...args); | ||
} | ||
omit(omit) { | ||
const properties = Object.fromEntries(Object.entries(this.properties).filter(([key])=>!omit[key])); | ||
return new ObjectType(properties, ...this._isNullableOptional); | ||
const [_, ...args] = this._with(); | ||
return new ObjectType(properties, {}, ...args); | ||
} | ||
extend(properties) { | ||
const [_, ...args] = this._with(); | ||
return new ObjectType({ | ||
...this.properties, | ||
...properties | ||
}, ...this._isNullableOptional); | ||
}, {}, ...args); | ||
} | ||
merge(object) { | ||
const [_, ...args] = this._with(); | ||
return new ObjectType({ | ||
...this.properties, | ||
...object.properties | ||
}, ...this._isNullableOptional); | ||
}, {}, ...args); | ||
} | ||
partial() { | ||
const properties = {}; | ||
for (const [key, value] of Object.entries(this.properties)){ | ||
properties[key] = value.optional(); | ||
} | ||
const [_, ...args] = this._with(); | ||
return new ObjectType(properties, {}, ...args); | ||
} | ||
keyof() { | ||
@@ -47,0 +88,0 @@ return new EnumType(Object.keys(this.properties)); |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType } from "./base.js"; | ||
export class StringType extends BaseType { | ||
constructor(schema = Type.String(), nullable = false, optional = false){ | ||
super(schema, nullable, optional); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.String(options); | ||
} | ||
nullable() { | ||
return new StringType(...this._nullable()); | ||
return new StringType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
return new StringType(...this._optional()); | ||
return new StringType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
return new StringType(...this._nullish()); | ||
return new StringType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new StringType(...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new StringType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new StringType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
format(format) { | ||
return new StringType({ | ||
...this._schema, | ||
format | ||
}, ...this._isNullableOptional); | ||
return new StringType(...this._with({ | ||
options: { | ||
format | ||
} | ||
})); | ||
} | ||
max(value) { | ||
return new StringType({ | ||
...this._schema, | ||
maxLength: value | ||
}, ...this._isNullableOptional); | ||
return new StringType(...this._with({ | ||
options: { | ||
maxLength: value | ||
} | ||
})); | ||
} | ||
min(value) { | ||
return new StringType({ | ||
...this._schema, | ||
minLength: value | ||
}, ...this._isNullableOptional); | ||
return new StringType(...this._with({ | ||
options: { | ||
minLength: value | ||
} | ||
})); | ||
} | ||
pattern(pattern) { | ||
return new StringType({ | ||
...this._schema, | ||
pattern | ||
}, ...this._isNullableOptional); | ||
return new StringType(...this._with({ | ||
options: { | ||
pattern | ||
} | ||
})); | ||
} | ||
@@ -40,0 +76,0 @@ email() { |
import { Type } from '@sinclair/typebox'; | ||
import { Temporal } from 'temporal-polyfill'; | ||
import { BaseType } from "./base.js"; | ||
const createTemporalTransformer = (type, decode = (value)=>Temporal[type].from(value))=>{ | ||
const encode = (value)=>value.toString({ | ||
calendarName: 'never', | ||
smallestUnit: 'microsecond', | ||
timeZoneName: 'never' | ||
}); | ||
return { | ||
decode, | ||
encode | ||
}; | ||
}; | ||
export class PlainDateType extends BaseType { | ||
constructor(nullable = false, optional = false){ | ||
super(Type.Transform(Type.String({ | ||
static transformer = createTemporalTransformer('PlainDate'); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options, | ||
format: 'iso-date' | ||
})).Decode((value)=>Temporal.PlainDate.from(value)).Encode((value)=>value.toString({ | ||
calendarName: 'never' | ||
})), nullable, optional); | ||
})).Decode(PlainDateType.transformer.decode).Encode(PlainDateType.transformer.encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new PlainDateType(...args); | ||
return new PlainDateType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new PlainDateType(...args); | ||
return new PlainDateType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new PlainDateType(...args); | ||
return new PlainDateType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new PlainDateType(...this._with({ | ||
options: { | ||
default: PlainDateType.transformer.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new PlainDateType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new PlainDateType(...this._with({ | ||
options: { | ||
examples: examples.map(PlainDateType.transformer.encode) | ||
} | ||
})); | ||
} | ||
} | ||
export class PlainDateTimeType extends BaseType { | ||
constructor(nullable = false, optional = false){ | ||
super(Type.Transform(Type.String({ | ||
static transformer = createTemporalTransformer('PlainDateTime'); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options, | ||
format: 'iso-date-time' | ||
})).Decode((value)=>Temporal.PlainDateTime.from(value)).Encode((value)=>value.toString({ | ||
calendarName: 'never' | ||
})), nullable, optional); | ||
})).Decode(PlainDateTimeType.transformer.decode).Encode(PlainDateTimeType.transformer.encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new PlainDateTimeType(...args); | ||
return new PlainDateTimeType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new PlainDateTimeType(...args); | ||
return new PlainDateTimeType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new PlainDateTimeType(...args); | ||
return new PlainDateTimeType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new PlainDateTimeType(...this._with({ | ||
options: { | ||
default: PlainDateTimeType.transformer.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new PlainDateTimeType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new PlainDateTimeType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} | ||
export class ZonedDateTimeType extends BaseType { | ||
constructor(nullable = false, optional = false){ | ||
super(Type.Transform(Type.String({ | ||
static transformer = createTemporalTransformer('ZonedDateTime', (value)=>Temporal.Instant.from(value).toZonedDateTimeISO('UTC')); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options, | ||
format: 'date-time' | ||
})).Decode((value)=>Temporal.Instant.from(value).toZonedDateTimeISO('UTC')).Encode((value)=>value.toString({ | ||
calendarName: 'never' | ||
})), nullable, optional); | ||
})).Decode(ZonedDateTimeType.transformer.decode).Encode(ZonedDateTimeType.transformer.encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new ZonedDateTimeType(...args); | ||
return new ZonedDateTimeType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new ZonedDateTimeType(...args); | ||
return new ZonedDateTimeType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new ZonedDateTimeType(...args); | ||
return new ZonedDateTimeType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new ZonedDateTimeType(...this._with({ | ||
options: { | ||
default: ZonedDateTimeType.transformer.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new ZonedDateTimeType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new ZonedDateTimeType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} | ||
export class PlainTimeType extends BaseType { | ||
constructor(nullable = false, optional = false){ | ||
super(Type.Transform(Type.String({ | ||
static transformer = createTemporalTransformer('PlainTime'); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options, | ||
format: 'time' | ||
})).Decode((value)=>Temporal.PlainTime.from(value)).Encode((value)=>value.toString({ | ||
smallestUnit: 'microsecond' | ||
})), nullable, optional); | ||
})).Decode(PlainTimeType.transformer.decode).Encode(PlainTimeType.transformer.encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new PlainTimeType(...args); | ||
return new PlainTimeType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new PlainTimeType(...args); | ||
return new PlainTimeType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new PlainTimeType(...args); | ||
return new PlainTimeType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new PlainTimeType(...this._with({ | ||
options: { | ||
default: PlainTimeType.transformer.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new PlainTimeType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new PlainTimeType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} | ||
export class DurationType extends BaseType { | ||
constructor(nullable = false, optional = false){ | ||
super(Type.Transform(Type.String({})).Decode((value)=>Temporal.Duration.from(value)).Encode((value)=>value.toString({ | ||
smallestUnit: 'microsecond' | ||
})), nullable, optional); | ||
static transformer = createTemporalTransformer('Duration'); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options, | ||
format: 'duration' | ||
})).Decode(DurationType.transformer.decode).Encode(DurationType.transformer.encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new DurationType(...args); | ||
return new DurationType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new DurationType(...args); | ||
return new DurationType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new DurationType(...args); | ||
return new DurationType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new DurationType(...this._with({ | ||
options: { | ||
default: DurationType.transformer.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new DurationType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new DurationType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} | ||
export class PlainYearMonthType extends BaseType { | ||
constructor(nullable = false, optional = false){ | ||
super(Type.Transform(Type.String({})).Decode((value)=>Temporal.PlainYearMonth.from(value)).Encode((value)=>value.toString({ | ||
calendarName: 'never' | ||
})), nullable, optional); | ||
static transformer = createTemporalTransformer('PlainYearMonth'); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options | ||
})).Decode(PlainYearMonthType.transformer.decode).Encode(PlainYearMonthType.transformer.encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new PlainYearMonthType(...args); | ||
return new PlainYearMonthType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new PlainYearMonthType(...args); | ||
return new PlainYearMonthType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new PlainYearMonthType(...args); | ||
return new PlainYearMonthType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new PlainYearMonthType(...this._with({ | ||
options: { | ||
default: PlainYearMonthType.transformer.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new PlainYearMonthType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new PlainYearMonthType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} | ||
export class PlainMonthDayType extends BaseType { | ||
constructor(nullable = false, optional = false){ | ||
super(Type.Transform(Type.String({})).Decode((value)=>Temporal.PlainMonthDay.from(value)).Encode((value)=>value.toString({ | ||
calendarName: 'never' | ||
})), nullable, optional); | ||
static transformer = createTemporalTransformer('PlainMonthDay'); | ||
constructor(options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
} | ||
_constructSchema(options) { | ||
return Type.Transform(Type.String({ | ||
...options | ||
})).Decode(PlainMonthDayType.transformer.decode).Encode(PlainMonthDayType.transformer.encode); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new PlainMonthDayType(...args); | ||
return new PlainMonthDayType(...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new PlainMonthDayType(...args); | ||
return new PlainMonthDayType(...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new PlainMonthDayType(...args); | ||
return new PlainMonthDayType(...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new PlainMonthDayType(...this._with({ | ||
options: { | ||
default: PlainMonthDayType.transformer.encode(value) | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new PlainMonthDayType(...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new PlainMonthDayType(...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} |
import { Type } from '@sinclair/typebox'; | ||
import { BaseType, typeFinalSchema } from "./base.js"; | ||
import { BaseType, getTypeSchema } from "./base.js"; | ||
export class UnionType extends BaseType { | ||
types; | ||
constructor(types, nullable = false, optional = false){ | ||
super(Type.Union(types.map((t)=>t[typeFinalSchema])), nullable, optional); | ||
constructor(types, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
this.types = types; | ||
} | ||
_constructSchema(options) { | ||
return Type.Union(this.types.map(getTypeSchema), options); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new UnionType(this.types, ...args); | ||
return new UnionType(this.types, ...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new UnionType(this.types, ...args); | ||
return new UnionType(this.types, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new UnionType(this.types, ...args); | ||
return new UnionType(this.types, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new UnionType(this.types, ...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new UnionType(this.types, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...examples) { | ||
return new UnionType(this.types, ...this._with({ | ||
options: { | ||
examples | ||
} | ||
})); | ||
} | ||
} | ||
export class IntersactionType extends BaseType { | ||
types; | ||
constructor(types, nullable = false, optional = false){ | ||
super(Type.Intersect(types.map((t)=>t[typeFinalSchema])), nullable, optional); | ||
constructor(types, options = {}, isNullable = false, isOptional = false, hasDefault = false){ | ||
super(options, isNullable, isOptional, hasDefault); | ||
this.types = types; | ||
} | ||
_constructSchema(options) { | ||
return Type.Intersect(this.types.map(getTypeSchema), options); | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable(); | ||
return new IntersactionType(this.types, ...args); | ||
return new IntersactionType(this.types, ...this._with({ | ||
isNullable: true | ||
})); | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional(); | ||
return new IntersactionType(this.types, ...args); | ||
return new IntersactionType(this.types, ...this._with({ | ||
isOptional: true | ||
})); | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish(); | ||
return new IntersactionType(this.types, ...args); | ||
return new IntersactionType(this.types, ...this._with({ | ||
isNullable: true, | ||
isOptional: true | ||
})); | ||
} | ||
default(value) { | ||
return new IntersactionType(this.types, ...this._with({ | ||
options: { | ||
default: value | ||
}, | ||
hasDefault: true | ||
})); | ||
} | ||
description(description) { | ||
return new IntersactionType(this.types, ...this._with({ | ||
options: { | ||
description | ||
} | ||
})); | ||
} | ||
examples(...values) { | ||
return new IntersactionType(this.types, ...this._with({ | ||
options: { | ||
examples: values | ||
} | ||
})); | ||
} | ||
} |
@@ -24,3 +24,3 @@ { | ||
"temporal-polyfill": "^0.2.5", | ||
"@nmtjs/common": "0.2.1" | ||
"@nmtjs/common": "0.3.0" | ||
}, | ||
@@ -30,3 +30,3 @@ "devDependencies": { | ||
"temporal-polyfill": "^0.2.5", | ||
"@nmtjs/common": "0.2.1" | ||
"@nmtjs/common": "0.3.0" | ||
}, | ||
@@ -40,3 +40,3 @@ "files": [ | ||
], | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"scripts": { | ||
@@ -43,0 +43,0 @@ "build": "neemata-build -p neutral --root=./src './**/*.ts'", |
@@ -6,3 +6,3 @@ import { | ||
import { Value } from '@sinclair/typebox/value' | ||
import { type BaseType, typeFinalSchema } from './types/base.ts' | ||
import { type BaseType, getTypeSchema } from './types/base.ts' | ||
@@ -23,3 +23,3 @@ export type Compiled = { | ||
const compileType = (type: BaseType) => { | ||
const schema = type[typeFinalSchema] | ||
const schema = getTypeSchema(type) | ||
const compiled = TypeCompiler.Compile(schema) | ||
@@ -26,0 +26,0 @@ const prepare = (value: any) => { |
import type { TLiteralValue } from '@sinclair/typebox' | ||
import { ArrayType } from './types/array.ts' | ||
import type { BaseType, staticType } from './types/base.ts' | ||
import type { BaseType } from './types/base.ts' | ||
import { BooleanType } from './types/boolean.ts' | ||
import { CustomType } from './types/custom.ts' | ||
import { DateTimeType, DateType } from './types/datetime.ts' | ||
import { DateType } from './types/datetime.ts' | ||
import { EnumType, NativeEnumType } from './types/enum.ts' | ||
@@ -14,2 +14,3 @@ import { LiteralType } from './types/literal.ts' | ||
import type { typeStatic } from './constants.ts' | ||
// register ajv formats | ||
@@ -33,3 +34,2 @@ import { register } from './formats.ts' | ||
CustomType, | ||
DateTimeType, | ||
DateType, | ||
@@ -50,4 +50,4 @@ EnumType, | ||
export namespace infer { | ||
export type decoded<T extends BaseType> = T[staticType]['decoded'] | ||
export type encoded<T extends BaseType> = T[staticType]['encoded'] | ||
export type decoded<T extends BaseType> = T[typeStatic]['decoded'] | ||
export type encoded<T extends BaseType> = T[typeStatic]['encoded'] | ||
} | ||
@@ -66,3 +66,2 @@ export const never = () => new NeverType() | ||
export const date = () => new DateType() | ||
export const datetime = () => new DateTimeType() | ||
export const array = <T extends BaseType>(element: T) => | ||
@@ -69,0 +68,0 @@ new ArrayType(element) |
@@ -1,2 +0,2 @@ | ||
import type { t } from './index.ts' | ||
import { t as baseT } from './index.ts' | ||
import { | ||
@@ -12,3 +12,3 @@ DurationType, | ||
export function extend<T extends typeof t>(value: T) { | ||
function extend<T extends typeof baseT>(value: T) { | ||
return Object.assign({}, value, { | ||
@@ -27,2 +27,4 @@ temporal: { | ||
export const t = extend(baseT) | ||
export { | ||
@@ -29,0 +31,0 @@ DurationType, |
@@ -1,2 +0,2 @@ | ||
import { type TAny, Type } from '@sinclair/typebox' | ||
import { type SchemaOptions, type TAny, Type } from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
@@ -7,22 +7,45 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TAny, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TAny, N, O, D, SchemaOptions> { | ||
constructor( | ||
schema = Type.Any(), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(schema, nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema(options: SchemaOptions): TAny { | ||
return Type.Any(options) | ||
} | ||
nullable() { | ||
return new AnyType(...this._nullable()) | ||
return new AnyType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
return new AnyType(...this._optional()) | ||
return new AnyType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
return new AnyType(...this._nullish()) | ||
return new AnyType(...this._with({ isNullable: true, isOptional: true })) | ||
} | ||
default(value: any) { | ||
return new AnyType( | ||
...this._with({ | ||
options: { default: value }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new AnyType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: [any, ...any[]]) { | ||
return new AnyType(...this._with({ options: { examples } })) | ||
} | ||
} |
import { type ArrayOptions, type TArray, Type } from '@sinclair/typebox' | ||
import { BaseType, typeFinalSchema } from './base.ts' | ||
import type { typeStatic } from '../constants.ts' | ||
import { BaseType, getTypeSchema } from './base.ts' | ||
@@ -8,35 +9,70 @@ export class ArrayType< | ||
O extends boolean = false, | ||
> extends BaseType<TArray<T[typeFinalSchema]>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TArray<T[typeStatic]['schema']>, N, O, D, ArrayOptions> { | ||
constructor( | ||
readonly element: T, | ||
readonly options: ArrayOptions = {}, | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: ArrayOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(Type.Array(element[typeFinalSchema]), nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault, element) | ||
} | ||
protected _constructSchema( | ||
options: ArrayOptions, | ||
element: T, | ||
): TArray<T[typeStatic]['schema']> { | ||
return Type.Array(getTypeSchema(element), options) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new ArrayType(this.element, this.options, ...args) | ||
return new ArrayType(this.element, ...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new ArrayType(this.element, this.options, ...args) | ||
return new ArrayType(this.element, ...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new ArrayType(this.element, this.options, ...args) | ||
return new ArrayType( | ||
this.element, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: this[typeStatic]['encoded']) { | ||
return new ArrayType( | ||
this.element, | ||
...this._with({ | ||
options: { default: value }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new ArrayType( | ||
this.element, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples( | ||
...examples: [this[typeStatic]['encoded'], ...this[typeStatic]['encoded'][]] | ||
) { | ||
return new ArrayType( | ||
this.element, | ||
...this._with({ | ||
options: { example: examples[0], examples }, | ||
}), | ||
) | ||
} | ||
min(value: number) { | ||
return new ArrayType( | ||
this.element, | ||
{ | ||
...this.options, | ||
minItems: value, | ||
}, | ||
...this._isNullableOptional, | ||
...this._with({ | ||
options: { minItems: value }, | ||
}), | ||
) | ||
@@ -48,7 +84,5 @@ } | ||
this.element, | ||
{ | ||
...this.options, | ||
maxItems: value, | ||
}, | ||
...this._isNullableOptional, | ||
...this._with({ | ||
options: { maxItems: value }, | ||
}), | ||
) | ||
@@ -60,10 +94,7 @@ } | ||
this.element, | ||
{ | ||
...this.options, | ||
minItems: value, | ||
maxItems: value, | ||
}, | ||
...this._isNullableOptional, | ||
...this._with({ | ||
options: { minItems: value, maxItems: value }, | ||
}), | ||
) | ||
} | ||
} |
import { | ||
type SchemaOptions, | ||
type StaticDecode, | ||
@@ -9,28 +10,11 @@ type StaticEncode, | ||
} from '@sinclair/typebox' | ||
import { typeSchema, typeStatic } from '../constants.ts' | ||
import { Nullable, type TNullable } from '../schemas/nullable.ts' | ||
export const typeSchema: unique symbol = Symbol() | ||
export type typeSchema = typeof typeSchema | ||
export const typeOptions: unique symbol = Symbol() | ||
export type typeOptions = typeof typeOptions | ||
export const typeOptional: unique symbol = Symbol() | ||
export type typeOptional = typeof typeOptional | ||
export const typeNullable: unique symbol = Symbol() | ||
export type typeNullable = typeof typeNullable | ||
export const staticType: unique symbol = Symbol() | ||
export type staticType = typeof staticType | ||
export const typeFinalSchema: unique symbol = Symbol() | ||
export type typeFinalSchema = typeof typeFinalSchema | ||
type ResolveNullable<T extends TSchema, Is extends boolean> = Is extends true | ||
? T | TNullable<T> | ||
? TNullable<T> | ||
: T | ||
type ResolveOptional<T extends TSchema, Is extends boolean> = Is extends true | ||
? T | TOptional<T> | ||
? TOptional<T> | ||
: T | ||
@@ -45,116 +29,79 @@ | ||
export abstract class BaseType< | ||
Schema extends TSchema = any, | ||
Schema extends TSchema = TSchema, | ||
IsNullable extends boolean = boolean, | ||
IsOptional extends boolean = boolean, | ||
Final extends Resolve<Schema, IsNullable, IsOptional> = Resolve< | ||
Schema, | ||
IsNullable, | ||
IsOptional | ||
>, | ||
HasDefault extends boolean = boolean, | ||
Options extends SchemaOptions = SchemaOptions, | ||
> { | ||
[typeSchema]: Schema; | ||
[typeNullable]: IsNullable; | ||
[typeOptional]: IsOptional; | ||
protected abstract _constructSchema( | ||
options: Options, | ||
...constructArgs: any[] | ||
): Schema | ||
[staticType]!: { | ||
final: Final | ||
[typeStatic]!: { | ||
schema: Resolve<Schema, IsNullable, IsOptional> | ||
isOptional: IsOptional | ||
isNullable: IsNullable | ||
encoded: StaticEncode<Final> | ||
decoded: StaticDecode<Final> | ||
hasDefault: HasDefault | ||
encoded: StaticEncode<Resolve<Schema, IsNullable, IsOptional>> | ||
decoded: StaticDecode< | ||
Resolve<Schema, IsNullable, HasDefault extends false ? false : IsOptional> | ||
> | ||
} | ||
constructor( | ||
schema: Schema, | ||
nullable: IsNullable = false as IsNullable, | ||
optional: IsOptional = false as IsOptional, | ||
protected options: Options = {} as Options, | ||
protected isNullable: IsNullable = false as IsNullable, | ||
protected isOptional: IsOptional = false as IsOptional, | ||
protected hasDefault: HasDefault = false as HasDefault, | ||
...contstructArgs: any[] | ||
) { | ||
this[typeSchema] = schema | ||
this[typeNullable] = nullable | ||
this[typeOptional] = optional | ||
} | ||
get [typeFinalSchema](): Final { | ||
let schema: TSchema = this._schema | ||
if (this._isNullable) { | ||
let schema: TSchema = this._constructSchema(options, ...contstructArgs) | ||
if (this.isNullable) { | ||
schema = Nullable(schema) | ||
} | ||
if (this._isOptional) { | ||
if (this.isOptional) { | ||
schema = Type.Optional(schema) | ||
} | ||
return schema as Final | ||
this[typeSchema] = schema as Schema | ||
} | ||
protected [typeSchema]: Schema | ||
protected get _schema() { | ||
return this[typeSchema] | ||
protected get _args(): [IsNullable, IsOptional, HasDefault] { | ||
return [this.isNullable, this.isOptional, this.hasDefault] | ||
} | ||
protected get _isNullable(): IsNullable { | ||
return this[typeNullable] | ||
protected _with< | ||
_IsNullable extends boolean = IsNullable, | ||
_IsOptional extends boolean = IsOptional, | ||
_HasDefault extends boolean = HasDefault, | ||
>({ | ||
options = this.options as Options, | ||
isNullable = this.isNullable as unknown as _IsNullable, | ||
isOptional = this.isOptional as unknown as _IsOptional, | ||
hasDefault = this.hasDefault as unknown as _HasDefault, | ||
}: { | ||
options?: Options | ||
isNullable?: _IsNullable | ||
isOptional?: _IsOptional | ||
hasDefault?: _HasDefault | ||
} = {}): [Options, _IsNullable, _IsOptional, _HasDefault] { | ||
return [{ ...this.options, ...options }, isNullable, isOptional, hasDefault] | ||
} | ||
protected get _isOptional(): IsOptional { | ||
return this[typeOptional] | ||
} | ||
protected get _isNullableOptional(): [IsNullable, IsOptional] { | ||
return [this._isNullable, this._isOptional] | ||
} | ||
protected _contructSelf<T extends any[]>(...args: T) { | ||
return args | ||
} | ||
protected _nullable() { | ||
return this._contructSelf(this._schema, true as const, this[typeOptional]) | ||
} | ||
protected _optional() { | ||
return this._contructSelf(this._schema, this[typeNullable], true as const) | ||
} | ||
protected _nullish() { | ||
return this._contructSelf(this._schema, true as const, true as const) | ||
} | ||
abstract nullable(): BaseType<Schema, true, IsOptional> | ||
abstract optional(): BaseType<Schema, IsNullable, true> | ||
abstract nullish(): BaseType<Schema, true, true> | ||
default(value: StaticDecode<Schema>): this { | ||
return this._contructSelf( | ||
{ | ||
...this._schema, | ||
default: value, | ||
}, | ||
this[typeNullable], | ||
this[typeOptional], | ||
) as unknown as this | ||
} | ||
description(description: string): this { | ||
return this._contructSelf( | ||
{ | ||
...this._schema, | ||
description, | ||
}, | ||
this[typeNullable], | ||
this[typeOptional], | ||
) as unknown as this | ||
} | ||
examples(...examples: StaticDecode<Schema>[]): this { | ||
return this._contructSelf( | ||
{ | ||
...this._schema, | ||
examples, | ||
}, | ||
this[typeNullable], | ||
this[typeOptional], | ||
) as unknown as this | ||
} | ||
abstract optional(): BaseType<Schema, IsNullable, true, HasDefault> | ||
abstract nullish(): BaseType<Schema, true, true, HasDefault> | ||
abstract default(value: any): BaseType<Schema, IsNullable, IsOptional, true> | ||
abstract description( | ||
value: string, | ||
): BaseType<Schema, IsNullable, IsOptional, HasDefault> | ||
abstract examples( | ||
...values: any[] | ||
): BaseType<Schema, IsNullable, IsOptional, HasDefault> | ||
} | ||
export function getTypeSchema<T extends BaseType>(type: T): T[typeFinalSchema] { | ||
return type[typeFinalSchema] | ||
export function getTypeSchema<T extends BaseType>( | ||
type: T, | ||
): T[typeStatic]['schema'] { | ||
return type[typeSchema] | ||
} |
@@ -1,2 +0,2 @@ | ||
import { type TBoolean, Type } from '@sinclair/typebox' | ||
import { type SchemaOptions, type TBoolean, Type } from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
@@ -7,22 +7,44 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TBoolean, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TBoolean, N, O, D> { | ||
constructor( | ||
schema: TBoolean = Type.Boolean(), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(schema, nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema(options: SchemaOptions): TBoolean { | ||
return Type.Boolean(options) | ||
} | ||
nullable() { | ||
return new BooleanType(...this._nullable()) | ||
return new BooleanType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
return new BooleanType(...this._optional()) | ||
return new BooleanType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
return new BooleanType(...this._nullish()) | ||
return new BooleanType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: boolean) { | ||
return new BooleanType( | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new BooleanType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: [boolean, ...boolean[]]) { | ||
return new BooleanType(...this._with({ options: { examples } })) | ||
} | ||
} |
@@ -1,4 +0,12 @@ | ||
import { type TTransform, type TUnsafe, Type } from '@sinclair/typebox' | ||
import { | ||
type SchemaOptions, | ||
type TTransform, | ||
type TUnsafe, | ||
Type, | ||
} from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
type CustomDecode<T> = (value: any) => T | ||
type CustomEncode<T> = (value: T) => any | ||
export class CustomType< | ||
@@ -9,26 +17,30 @@ T, | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TUnsafe<S>, T>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TTransform<TUnsafe<S>, T>, N, O, D> { | ||
constructor( | ||
protected readonly decode: (value: any) => T, | ||
protected readonly encode: (value: T) => any, | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
protected readonly decode: CustomDecode<T>, | ||
protected readonly encode: CustomEncode<T>, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super( | ||
Type.Optional( | ||
Type.Transform(Type.Any() as unknown as TUnsafe<S>) | ||
.Decode(decode) | ||
.Encode(encode), | ||
), | ||
nullable, | ||
optional, | ||
) | ||
super(options, isNullable, isOptional, hasDefault, decode, encode) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
decode: CustomDecode<T>, | ||
encode: CustomEncode<T>, | ||
): TTransform<TUnsafe<S>, T> { | ||
return Type.Transform(Type.Any(options) as unknown as TUnsafe<S>) | ||
.Decode(decode) | ||
.Encode(encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new CustomType<T, S, (typeof args)[0], (typeof args)[1]>( | ||
return new CustomType<T, S, true, O, D>( | ||
this.decode, | ||
this.encode, | ||
...args, | ||
...this._with({ isNullable: true }), | ||
) | ||
@@ -38,7 +50,6 @@ } | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new CustomType<T, S, (typeof args)[0], (typeof args)[1]>( | ||
return new CustomType<T, S, N, true, D>( | ||
this.decode, | ||
this.encode, | ||
...args, | ||
...this._with({ isOptional: true }), | ||
) | ||
@@ -48,9 +59,35 @@ } | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new CustomType<T, S, (typeof args)[0], (typeof args)[1]>( | ||
return new CustomType<T, S, true, true, D>( | ||
this.decode, | ||
this.encode, | ||
...args, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: T) { | ||
return new CustomType<T, S, N, O, true>( | ||
this.decode, | ||
this.encode, | ||
...this._with({ | ||
options: { default: this.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new CustomType<T, S, N, O, D>( | ||
this.decode, | ||
this.encode, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples(...examples: [T, ...T[]]) { | ||
return new CustomType<T, S, N, O, D>( | ||
this.decode, | ||
this.encode, | ||
...this._with({ options: { examples: examples.map(this.encode) } }), | ||
) | ||
} | ||
} |
@@ -1,60 +0,65 @@ | ||
import { type TString, type TTransform, Type } from '@sinclair/typebox' | ||
import { | ||
type SchemaOptions, | ||
type StringOptions, | ||
type TString, | ||
type TTransform, | ||
Type, | ||
} from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
const decode = (value: any): Date => new Date(value) | ||
const encode = (value: Date): any => value.toISOString() | ||
export class DateType< | ||
N extends boolean = false, | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Date>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TTransform<TString, Date>, N, O, D, StringOptions> { | ||
constructor( | ||
schema: TTransform<TString, Date> = Type.Transform( | ||
Type.String({ format: 'date' }), | ||
) | ||
.Decode((value) => new Date(value)) | ||
.Encode((value) => value.toJSON()), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(schema, nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: StringOptions, | ||
): TTransform<TString, Date> { | ||
return Type.Transform(Type.String({ ...options, format: 'date-time' })) | ||
.Decode(decode) | ||
.Encode(encode) | ||
} | ||
nullable() { | ||
return new DateType(...this._nullable()) | ||
return new DateType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
return new DateType(...this._optional()) | ||
return new DateType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
return new DateType(...this._nullish()) | ||
return new DateType(...this._with({ isNullable: true, isOptional: true })) | ||
} | ||
} | ||
export class DateTimeType< | ||
N extends boolean = false, | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Date>, N, O> { | ||
constructor( | ||
schema: TTransform<TString, Date> = Type.Transform( | ||
Type.String({ format: 'date-time' }), | ||
default(value: Date) { | ||
return new DateType( | ||
...this._with({ | ||
options: { default: encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
.Decode((value) => new Date(value)) | ||
.Encode((value) => value.toJSON()), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
) { | ||
super(schema, nullable, optional) | ||
} | ||
nullable() { | ||
return new DateTimeType(...this._nullable()) | ||
description(value: string) { | ||
return new DateType(...this._with({ options: { description: value } })) | ||
} | ||
optional() { | ||
return new DateTimeType(...this._optional()) | ||
examples(...values: [Date, ...Date[]]) { | ||
return new DateType( | ||
...this._with({ options: { examples: values.map(encode) } }), | ||
) | ||
} | ||
nullish() { | ||
return new DateTimeType(...this._nullish()) | ||
} | ||
} |
@@ -0,1 +1,2 @@ | ||
import type { SchemaOptions } from '@sinclair/typebox' | ||
import type { TNativeEnum } from '../schemas/native-enum.ts' | ||
@@ -10,25 +11,53 @@ import { NativeEnum } from '../schemas/native-enum.ts' | ||
O extends boolean = false, | ||
> extends BaseType<TNativeEnum<T>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TNativeEnum<T>, N, O, D> { | ||
constructor( | ||
readonly values: T, | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(NativeEnum(values), nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema(options: SchemaOptions): TNativeEnum<T> { | ||
return NativeEnum(this.values, options) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new NativeEnumType(this.values, ...args) | ||
return new NativeEnumType(this.values, ...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new NativeEnumType(this.values, ...args) | ||
return new NativeEnumType(this.values, ...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new NativeEnumType(this.values, ...args) | ||
return new NativeEnumType( | ||
this.values, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: keyof T) { | ||
return new NativeEnumType( | ||
this.values, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new NativeEnumType( | ||
this.values, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples(...examples: (keyof T)[]) { | ||
return new NativeEnumType( | ||
this.values, | ||
...this._with({ options: { examples } }), | ||
) | ||
} | ||
} | ||
@@ -40,25 +69,53 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TUnionEnum<T>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TUnionEnum<T>, N, O, D> { | ||
constructor( | ||
readonly values: [...T], | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
protected readonly values: [...T], | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(UnionEnum(values), nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault, values) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
values: [...T], | ||
): TUnionEnum<T> { | ||
return UnionEnum(values, options) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new EnumType(this.values, ...args) | ||
return new EnumType(this.values, ...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new EnumType(this.values, ...args) | ||
return new EnumType(this.values, ...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new EnumType(this.values, ...args) | ||
return new EnumType( | ||
this.values, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: T[number]) { | ||
return new EnumType( | ||
this.values, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new EnumType( | ||
this.values, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples(...examples: [T[number], ...T[number][]]) { | ||
return new EnumType(this.values, ...this._with({ options: { examples } })) | ||
} | ||
} |
@@ -1,2 +0,7 @@ | ||
import { type TLiteral, type TLiteralValue, Type } from '@sinclair/typebox' | ||
import { | ||
type SchemaOptions, | ||
type TLiteral, | ||
type TLiteralValue, | ||
Type, | ||
} from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
@@ -8,25 +13,50 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TLiteral<T>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TLiteral<T>, N, O, D> { | ||
constructor( | ||
readonly value: T, | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
protected readonly value: T, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(Type.Literal(value), nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault, value) | ||
} | ||
protected _constructSchema(options: SchemaOptions, value: T): TLiteral<T> { | ||
return Type.Literal(value, options) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new LiteralType(this.value, ...args) | ||
return new LiteralType(this.value, this.options, true, this.isOptional) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new LiteralType(this.value, ...args) | ||
return new LiteralType(this.value, ...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new LiteralType(this.value, ...args) | ||
return new LiteralType( | ||
this.value, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: T = this.value) { | ||
return new LiteralType( | ||
this.value, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new LiteralType( | ||
this.value, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples(...examples: [T, ...T[]]) { | ||
return new LiteralType(this.value, ...this._with({ options: { examples } })) | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { type TNever, Type } from '@sinclair/typebox' | ||
import { type SchemaOptions, type TNever, Type } from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
@@ -7,22 +7,35 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TNever, N, O> { | ||
constructor( | ||
schema = Type.Never(), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
) { | ||
super(schema, nullable, optional) | ||
D extends boolean = false, | ||
> extends BaseType<TNever, N, O, D> { | ||
constructor(options: SchemaOptions = {}) { | ||
super(options, false as N, false as O, false as D) | ||
} | ||
nullable(): NeverType<true, O> { | ||
protected _constructSchema(options: SchemaOptions): TNever { | ||
return Type.Never(options) | ||
} | ||
nullable(): NeverType<true, O, D> { | ||
throw new Error('NeverType cannot be nullable') | ||
} | ||
optional(): NeverType<N, true> { | ||
optional(): NeverType<N, true, D> { | ||
throw new Error('NeverType cannot be optional') | ||
} | ||
nullish(): NeverType<true, true> { | ||
nullish(): NeverType<true, true, D> { | ||
throw new Error('NeverType cannot be nullish') | ||
} | ||
default(): NeverType<N, O, true> { | ||
throw new Error('NeverType cannot have a default value') | ||
} | ||
description(description: string): NeverType<N, O, D> { | ||
return new NeverType({ ...this.options, description }) | ||
} | ||
examples(): NeverType<N, O, D> { | ||
throw new Error('NeverType cannot have examples') | ||
} | ||
} |
@@ -1,2 +0,8 @@ | ||
import { type TInteger, type TNumber, Type } from '@sinclair/typebox' | ||
import { | ||
type IntegerOptions, | ||
type NumberOptions, | ||
type TInteger, | ||
type TNumber, | ||
Type, | ||
} from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
@@ -7,23 +13,49 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TNumber, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TNumber, N, O, D, NumberOptions> { | ||
constructor( | ||
schema: TNumber = Type.Number(), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
protected readonly options: NumberOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(schema, nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
positive() { | ||
protected _constructSchema(options: NumberOptions): TNumber { | ||
return Type.Number(options) | ||
} | ||
nullable() { | ||
return new NumberType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
return new NumberType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
return new NumberType(...this._with({ isNullable: true, isOptional: true })) | ||
} | ||
default(value: number) { | ||
return new NumberType( | ||
Type.Number({ ...this._schema, minimum: 0, exclusiveMinimum: 0 }), | ||
...this._isNullableOptional, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new NumberType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: [number, ...number[]]) { | ||
return new NumberType(...this._with({ options: { examples } })) | ||
} | ||
positive() { | ||
return this.min(0, true) | ||
} | ||
negative() { | ||
return new NumberType( | ||
Type.Number({ ...this._schema, maximum: 0, exclusiveMaximum: 0 }), | ||
...this._isNullableOptional, | ||
) | ||
return this.max(0, true) | ||
} | ||
@@ -33,8 +65,8 @@ | ||
return new NumberType( | ||
Type.Number({ | ||
...this._schema, | ||
maximum: value, | ||
...(exclusive ? {} : { exclusiveMaximum: value }), | ||
...this._with({ | ||
options: { | ||
maximum: value, | ||
...(exclusive ? {} : { exclusiveMaximum: value }), | ||
}, | ||
}), | ||
...this._isNullableOptional, | ||
) | ||
@@ -45,48 +77,64 @@ } | ||
return new NumberType( | ||
Type.Number({ | ||
...this._schema, | ||
minimum: value, | ||
...(exclusive ? {} : { exclusiveMinimum: value }), | ||
...this._with({ | ||
options: { | ||
minimum: value, | ||
...(exclusive ? {} : { exclusiveMinimum: value }), | ||
}, | ||
}), | ||
...this._isNullableOptional, | ||
) | ||
} | ||
} | ||
export class IntegerType< | ||
N extends boolean = false, | ||
O extends boolean = false, | ||
D extends boolean = false, | ||
> extends BaseType<TInteger, N, O, D, IntegerOptions> { | ||
constructor( | ||
options: IntegerOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema(options: IntegerOptions): TInteger { | ||
return Type.Integer(options) | ||
} | ||
nullable() { | ||
return new NumberType(...this._nullable()) | ||
return new IntegerType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
return new NumberType(...this._optional()) | ||
return new IntegerType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
return new NumberType(...this._nullish()) | ||
return new IntegerType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
} | ||
export class IntegerType< | ||
N extends boolean = false, | ||
O extends boolean = false, | ||
> extends BaseType<TInteger, N, O> { | ||
constructor( | ||
schema: TInteger = Type.Integer(), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
) { | ||
super(schema, nullable, optional) | ||
default(value: number) { | ||
return new IntegerType( | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new IntegerType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: [number, ...number[]]) { | ||
return new IntegerType(...this._with({ options: { examples } })) | ||
} | ||
positive() { | ||
return new IntegerType( | ||
Type.Integer({ ...this._schema, minimum: 0, exclusiveMinimum: 0 }), | ||
...this._isNullableOptional, | ||
) | ||
return this.min(0, true) | ||
} | ||
negative() { | ||
return new IntegerType( | ||
Type.Integer({ ...this._schema, maximum: 0, exclusiveMaximum: 0 }), | ||
...this._isNullableOptional, | ||
) | ||
return this.max(0, true) | ||
} | ||
@@ -96,8 +144,8 @@ | ||
return new IntegerType( | ||
Type.Integer({ | ||
...this._schema, | ||
maximum: value, | ||
...(exclusive ? {} : { exclusiveMaximum: value }), | ||
...this._with({ | ||
options: { | ||
maximum: value, | ||
...(exclusive ? {} : { exclusiveMaximum: value }), | ||
}, | ||
}), | ||
...this._isNullableOptional, | ||
) | ||
@@ -108,22 +156,10 @@ } | ||
return new IntegerType( | ||
Type.Integer({ | ||
...this._schema, | ||
minimum: value, | ||
...(exclusive ? {} : { exclusiveMinimum: value }), | ||
...this._with({ | ||
options: { | ||
minimum: value, | ||
...(exclusive ? {} : { exclusiveMinimum: value }), | ||
}, | ||
}), | ||
...this._isNullableOptional, | ||
) | ||
} | ||
nullable() { | ||
return new IntegerType(...this._nullable()) | ||
} | ||
optional() { | ||
return new IntegerType(...this._optional()) | ||
} | ||
nullish() { | ||
return new IntegerType(...this._nullish()) | ||
} | ||
} |
@@ -1,4 +0,10 @@ | ||
import { type TObject, Type } from '@sinclair/typebox' | ||
import { | ||
type ObjectOptions, | ||
type StaticEncode, | ||
type TObject, | ||
Type, | ||
} from '@sinclair/typebox' | ||
import type { typeStatic } from '../constants.ts' | ||
import type { UnionToTupleString } from '../utils.ts' | ||
import { BaseType, typeFinalSchema } from './base.ts' | ||
import { BaseType, getTypeSchema } from './base.ts' | ||
import { EnumType } from './enum.ts' | ||
@@ -10,38 +16,72 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TObject<{ [K in keyof T]: T[K][typeFinalSchema] }>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TObject<{ [K in keyof T]: T[K][typeStatic]['schema'] }>, | ||
N, | ||
O, | ||
D | ||
> { | ||
constructor( | ||
readonly properties: T = {} as T, | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
protected readonly properties: T = {} as T, | ||
options: ObjectOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
const schemaProperties = Object.fromEntries( | ||
Object.entries(properties).map(([key, value]) => [ | ||
key, | ||
value[typeFinalSchema], | ||
]), | ||
) | ||
super( | ||
Type.Object( | ||
schemaProperties as { [K in keyof T]: T[K][typeFinalSchema] }, | ||
), | ||
nullable, | ||
optional, | ||
) | ||
super(options, isNullable, isOptional, hasDefault, properties) | ||
} | ||
protected _constructSchema( | ||
options: ObjectOptions, | ||
properties: T, | ||
): TObject<{ [K in keyof T]: T[K][typeStatic]['schema'] }> { | ||
const schemaProperties = {} as { | ||
[K in keyof T]: T[K][typeStatic]['schema'] | ||
} | ||
for (const [key, value] of Object.entries(properties)) { | ||
// @ts-expect-error | ||
schemaProperties[key] = getTypeSchema(value) | ||
} | ||
return Type.Object(schemaProperties, options) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new ObjectType(this.properties, ...args) | ||
return new ObjectType(this.properties, ...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new ObjectType(this.properties, ...args) | ||
return new ObjectType(this.properties, ...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new ObjectType(this.properties, ...args) | ||
return new ObjectType( | ||
this.properties, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: this[typeStatic]['encoded']) { | ||
return new ObjectType( | ||
this.properties, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new ObjectType( | ||
this.properties, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples( | ||
...examples: [this[typeStatic]['encoded'], ...this[typeStatic]['encoded'][]] | ||
) { | ||
return new ObjectType( | ||
this.properties, | ||
...this._with({ options: { examples } }), | ||
) | ||
} | ||
pick<P extends { [K in keyof T]?: true }>(pick: P) { | ||
@@ -51,5 +91,7 @@ const properties = Object.fromEntries( | ||
) | ||
const [_, ...args] = this._with() | ||
return new ObjectType( | ||
properties as Pick<T, Extract<keyof P, keyof T>>, | ||
...this._isNullableOptional, | ||
{}, | ||
...args, | ||
) | ||
@@ -62,5 +104,7 @@ } | ||
) | ||
const [_, ...args] = this._with() | ||
return new ObjectType( | ||
properties as Omit<T, Extract<keyof P, keyof T>>, | ||
...this._isNullableOptional, | ||
{}, | ||
...args, | ||
) | ||
@@ -70,15 +114,26 @@ } | ||
extend<P extends Record<string, BaseType>>(properties: P) { | ||
return new ObjectType( | ||
{ ...this.properties, ...properties }, | ||
...this._isNullableOptional, | ||
) | ||
const [_, ...args] = this._with() | ||
return new ObjectType({ ...this.properties, ...properties }, {}, ...args) | ||
} | ||
merge<T extends ObjectType>(object: T) { | ||
const [_, ...args] = this._with() | ||
return new ObjectType( | ||
{ ...this.properties, ...object.properties }, | ||
...this._isNullableOptional, | ||
{}, | ||
...args, | ||
) | ||
} | ||
partial() { | ||
const properties: { [K in keyof T]: ReturnType<T[K]['optional']> } = | ||
{} as any | ||
for (const [key, value] of Object.entries(this.properties)) { | ||
// @ts-expect-error | ||
properties[key] = value.optional() | ||
} | ||
const [_, ...args] = this._with() | ||
return new ObjectType(properties, {}, ...args) | ||
} | ||
keyof(): EnumType<UnionToTupleString<keyof T>> { | ||
@@ -85,0 +140,0 @@ return new EnumType(Object.keys(this.properties) as any) |
@@ -1,2 +0,2 @@ | ||
import { type TString, Type } from '@sinclair/typebox' | ||
import { type StringOptions, type TString, Type } from '@sinclair/typebox' | ||
import { BaseType } from './base.ts' | ||
@@ -7,40 +7,52 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TString, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType<TString, N, O, D, StringOptions> { | ||
constructor( | ||
schema = Type.String(), | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(schema, nullable, optional) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema(options: StringOptions): TString { | ||
return Type.String(options) | ||
} | ||
nullable() { | ||
return new StringType(...this._nullable()) | ||
return new StringType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
return new StringType(...this._optional()) | ||
return new StringType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
return new StringType(...this._nullish()) | ||
return new StringType(...this._with({ isNullable: true, isOptional: true })) | ||
} | ||
format(format: TString['format']) { | ||
default(value: string) { | ||
return new StringType( | ||
{ | ||
...this._schema, | ||
format, | ||
}, | ||
...this._isNullableOptional, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new StringType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: string[]) { | ||
return new StringType(...this._with({ options: { examples } })) | ||
} | ||
format(format: TString['format']) { | ||
return new StringType(...this._with({ options: { format } })) | ||
} | ||
max(value: number) { | ||
return new StringType( | ||
{ | ||
...this._schema, | ||
maxLength: value, | ||
}, | ||
...this._isNullableOptional, | ||
...this._with({ | ||
options: { maxLength: value }, | ||
}), | ||
) | ||
@@ -51,7 +63,5 @@ } | ||
return new StringType( | ||
{ | ||
...this._schema, | ||
minLength: value, | ||
}, | ||
...this._isNullableOptional, | ||
...this._with({ | ||
options: { minLength: value }, | ||
}), | ||
) | ||
@@ -62,7 +72,5 @@ } | ||
return new StringType( | ||
{ | ||
...this._schema, | ||
pattern, | ||
}, | ||
...this._isNullableOptional, | ||
...this._with({ | ||
options: { pattern }, | ||
}), | ||
) | ||
@@ -69,0 +77,0 @@ } |
@@ -1,33 +0,102 @@ | ||
import { type TString, type TTransform, Type } from '@sinclair/typebox' | ||
import { | ||
type SchemaOptions, | ||
type StringOptions, | ||
type TString, | ||
type TTransform, | ||
Type, | ||
} from '@sinclair/typebox' | ||
import { Temporal } from 'temporal-polyfill' | ||
import { BaseType } from './base.ts' | ||
type Types = Exclude< | ||
keyof typeof Temporal, | ||
'Now' | 'Instant' | 'Calendar' | 'TimeZone' | ||
> | ||
type TemporalTransformer<T extends Types> = { | ||
decode: (value: string) => ReturnType<(typeof Temporal)[T]['from']> | ||
encode: (value: ReturnType<(typeof Temporal)[T]['from']>) => string | ||
} | ||
const createTemporalTransformer = <T extends Types>( | ||
type: T, | ||
decode = (value: string) => Temporal[type].from(value), | ||
) => { | ||
const encode = (value: ReturnType<(typeof Temporal)[T]['from']>) => | ||
value.toString({ | ||
calendarName: 'never', | ||
smallestUnit: 'microsecond', | ||
timeZoneName: 'never', | ||
}) | ||
return { | ||
decode, | ||
encode, | ||
} as TemporalTransformer<T> | ||
} | ||
export class PlainDateType< | ||
N extends boolean = false, | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Temporal.PlainDate>, N, O> { | ||
constructor(nullable: N = false as N, optional: O = false as O) { | ||
super( | ||
Type.Transform(Type.String({ format: 'iso-date' })) | ||
.Decode((value) => Temporal.PlainDate.from(value)) | ||
.Encode((value) => value.toString({ calendarName: 'never' })), | ||
nullable, | ||
optional, | ||
) | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TTransform<TString, Temporal.PlainDate>, | ||
N, | ||
O, | ||
D, | ||
StringOptions | ||
> { | ||
static readonly transformer = createTemporalTransformer('PlainDate') | ||
constructor( | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
): TTransform<TString, Temporal.PlainDate> { | ||
return Type.Transform(Type.String({ ...options, format: 'iso-date' })) | ||
.Decode(PlainDateType.transformer.decode) | ||
.Encode(PlainDateType.transformer.encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new PlainDateType(...args) | ||
return new PlainDateType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new PlainDateType(...args) | ||
return new PlainDateType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new PlainDateType(...args) | ||
return new PlainDateType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: Temporal.PlainDate) { | ||
return new PlainDateType( | ||
...this._with({ | ||
options: { default: PlainDateType.transformer.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new PlainDateType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: [Temporal.PlainDate, ...Temporal.PlainDate[]]) { | ||
return new PlainDateType( | ||
...this._with({ | ||
options: { examples: examples.map(PlainDateType.transformer.encode) }, | ||
}), | ||
) | ||
} | ||
} | ||
@@ -38,27 +107,59 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Temporal.PlainDateTime>, N, O> { | ||
constructor(nullable: N = false as N, optional: O = false as O) { | ||
super( | ||
Type.Transform(Type.String({ format: 'iso-date-time' })) | ||
.Decode((value) => Temporal.PlainDateTime.from(value)) | ||
.Encode((value) => value.toString({ calendarName: 'never' })), | ||
nullable, | ||
optional, | ||
) | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TTransform<TString, Temporal.PlainDateTime>, | ||
N, | ||
O, | ||
D, | ||
StringOptions | ||
> { | ||
static readonly transformer = createTemporalTransformer('PlainDateTime') | ||
constructor( | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
): TTransform<TString, Temporal.PlainDateTime> { | ||
return Type.Transform(Type.String({ ...options, format: 'iso-date-time' })) | ||
.Decode(PlainDateTimeType.transformer.decode) | ||
.Encode(PlainDateTimeType.transformer.encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new PlainDateTimeType(...args) | ||
return new PlainDateTimeType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new PlainDateTimeType(...args) | ||
return new PlainDateTimeType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new PlainDateTimeType(...args) | ||
return new PlainDateTimeType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: Temporal.PlainDateTime) { | ||
return new PlainDateTimeType( | ||
...this._with({ | ||
options: { default: PlainDateTimeType.transformer.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new PlainDateTimeType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: string[]) { | ||
return new PlainDateTimeType(...this._with({ options: { examples } })) | ||
} | ||
} | ||
@@ -69,29 +170,62 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Temporal.ZonedDateTime>, N, O> { | ||
constructor(nullable: N = false as N, optional: O = false as O) { | ||
super( | ||
Type.Transform(Type.String({ format: 'date-time' })) | ||
.Decode((value) => | ||
Temporal.Instant.from(value).toZonedDateTimeISO('UTC'), | ||
) | ||
.Encode((value) => value.toString({ calendarName: 'never' })), | ||
nullable, | ||
optional, | ||
) | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TTransform<TString, Temporal.ZonedDateTime>, | ||
N, | ||
O, | ||
D, | ||
StringOptions | ||
> { | ||
static readonly transformer = createTemporalTransformer( | ||
'ZonedDateTime', | ||
(value) => Temporal.Instant.from(value).toZonedDateTimeISO('UTC'), | ||
) | ||
constructor( | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
): TTransform<TString, Temporal.ZonedDateTime> { | ||
return Type.Transform(Type.String({ ...options, format: 'date-time' })) | ||
.Decode(ZonedDateTimeType.transformer.decode) | ||
.Encode(ZonedDateTimeType.transformer.encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new ZonedDateTimeType(...args) | ||
return new ZonedDateTimeType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new ZonedDateTimeType(...args) | ||
return new ZonedDateTimeType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new ZonedDateTimeType(...args) | ||
return new ZonedDateTimeType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: Temporal.ZonedDateTime) { | ||
return new ZonedDateTimeType( | ||
...this._with({ | ||
options: { default: ZonedDateTimeType.transformer.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new ZonedDateTimeType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: string[]) { | ||
return new ZonedDateTimeType(...this._with({ options: { examples } })) | ||
} | ||
} | ||
@@ -102,27 +236,59 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Temporal.PlainTime>, N, O> { | ||
constructor(nullable: N = false as N, optional: O = false as O) { | ||
super( | ||
Type.Transform(Type.String({ format: 'time' })) | ||
.Decode((value) => Temporal.PlainTime.from(value)) | ||
.Encode((value) => value.toString({ smallestUnit: 'microsecond' })), | ||
nullable, | ||
optional, | ||
) | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TTransform<TString, Temporal.PlainTime>, | ||
N, | ||
O, | ||
D, | ||
StringOptions | ||
> { | ||
static readonly transformer = createTemporalTransformer('PlainTime') | ||
constructor( | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
): TTransform<TString, Temporal.PlainTime> { | ||
return Type.Transform(Type.String({ ...options, format: 'time' })) | ||
.Decode(PlainTimeType.transformer.decode) | ||
.Encode(PlainTimeType.transformer.encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new PlainTimeType(...args) | ||
return new PlainTimeType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new PlainTimeType(...args) | ||
return new PlainTimeType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new PlainTimeType(...args) | ||
return new PlainTimeType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: Temporal.PlainTime) { | ||
return new PlainTimeType( | ||
...this._with({ | ||
options: { default: PlainTimeType.transformer.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new PlainTimeType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: string[]) { | ||
return new PlainTimeType(...this._with({ options: { examples } })) | ||
} | ||
} | ||
@@ -133,31 +299,59 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Temporal.Duration>, N, O> { | ||
constructor(nullable: N = false as N, optional: O = false as O) { | ||
super( | ||
Type.Transform( | ||
Type.String({ | ||
/* TODO: duration format, or regex? */ | ||
}), | ||
) | ||
.Decode((value) => Temporal.Duration.from(value)) | ||
.Encode((value) => value.toString({ smallestUnit: 'microsecond' })), | ||
nullable, | ||
optional, | ||
) | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TTransform<TString, Temporal.Duration>, | ||
N, | ||
O, | ||
D, | ||
StringOptions | ||
> { | ||
static readonly transformer = createTemporalTransformer('Duration') | ||
constructor( | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
): TTransform<TString, Temporal.Duration> { | ||
return Type.Transform(Type.String({ ...options, format: 'duration' })) | ||
.Decode(DurationType.transformer.decode) | ||
.Encode(DurationType.transformer.encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new DurationType(...args) | ||
return new DurationType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new DurationType(...args) | ||
return new DurationType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new DurationType(...args) | ||
return new DurationType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: Temporal.Duration) { | ||
return new DurationType( | ||
...this._with({ | ||
options: { default: DurationType.transformer.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new DurationType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: string[]) { | ||
return new DurationType(...this._with({ options: { examples } })) | ||
} | ||
} | ||
@@ -168,31 +362,64 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Temporal.PlainYearMonth>, N, O> { | ||
constructor(nullable: N = false as N, optional: O = false as O) { | ||
super( | ||
Type.Transform( | ||
Type.String({ | ||
/* TODO: duration format, or regex? */ | ||
}), | ||
) | ||
.Decode((value) => Temporal.PlainYearMonth.from(value)) | ||
.Encode((value) => value.toString({ calendarName: 'never' })), | ||
nullable, | ||
optional, | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TTransform<TString, Temporal.PlainYearMonth>, | ||
N, | ||
O, | ||
D, | ||
StringOptions | ||
> { | ||
static readonly transformer = createTemporalTransformer('PlainYearMonth') | ||
constructor( | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
): TTransform<TString, Temporal.PlainYearMonth> { | ||
return Type.Transform( | ||
Type.String({ | ||
...options, | ||
// TODO: duration format, or regex? | ||
}), | ||
) | ||
.Decode(PlainYearMonthType.transformer.decode) | ||
.Encode(PlainYearMonthType.transformer.encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new PlainYearMonthType(...args) | ||
return new PlainYearMonthType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new PlainYearMonthType(...args) | ||
return new PlainYearMonthType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new PlainYearMonthType(...args) | ||
return new PlainYearMonthType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: Temporal.PlainYearMonth) { | ||
return new PlainYearMonthType( | ||
...this._with({ | ||
options: { default: PlainYearMonthType.transformer.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new PlainYearMonthType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: string[]) { | ||
return new PlainYearMonthType(...this._with({ options: { examples } })) | ||
} | ||
} | ||
@@ -203,31 +430,64 @@ | ||
O extends boolean = false, | ||
> extends BaseType<TTransform<TString, Temporal.PlainMonthDay>, N, O> { | ||
constructor(nullable: N = false as N, optional: O = false as O) { | ||
super( | ||
Type.Transform( | ||
Type.String({ | ||
/* TODO: duration format, or regex? */ | ||
}), | ||
) | ||
.Decode((value) => Temporal.PlainMonthDay.from(value)) | ||
.Encode((value) => value.toString({ calendarName: 'never' })), | ||
nullable, | ||
optional, | ||
D extends boolean = false, | ||
> extends BaseType< | ||
TTransform<TString, Temporal.PlainMonthDay>, | ||
N, | ||
O, | ||
D, | ||
StringOptions | ||
> { | ||
static readonly transformer = createTemporalTransformer('PlainMonthDay') | ||
constructor( | ||
options: StringOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
): TTransform<TString, Temporal.PlainMonthDay> { | ||
return Type.Transform( | ||
Type.String({ | ||
...options, | ||
// TODO: duration format, or regex? | ||
}), | ||
) | ||
.Decode(PlainMonthDayType.transformer.decode) | ||
.Encode(PlainMonthDayType.transformer.encode) | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new PlainMonthDayType(...args) | ||
return new PlainMonthDayType(...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new PlainMonthDayType(...args) | ||
return new PlainMonthDayType(...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new PlainMonthDayType(...args) | ||
return new PlainMonthDayType( | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: Temporal.PlainMonthDay) { | ||
return new PlainMonthDayType( | ||
...this._with({ | ||
options: { default: PlainMonthDayType.transformer.encode(value) }, | ||
hasDefault: true, | ||
}), | ||
) | ||
} | ||
description(description: string) { | ||
return new PlainMonthDayType(...this._with({ options: { description } })) | ||
} | ||
examples(...examples: string[]) { | ||
return new PlainMonthDayType(...this._with({ options: { examples } })) | ||
} | ||
} |
@@ -1,4 +0,11 @@ | ||
import { type TIntersect, type TUnion, Type } from '@sinclair/typebox' | ||
import { | ||
type SchemaOptions, | ||
type TIntersect, | ||
type TUnion, | ||
Type, | ||
// type UnionToTuple, | ||
} from '@sinclair/typebox' | ||
import type { typeStatic } from '../constants.ts' | ||
import type { UnionToTuple } from '../utils.ts' | ||
import { BaseType, typeFinalSchema } from './base.ts' | ||
import { BaseType, getTypeSchema } from './base.ts' | ||
@@ -13,30 +20,61 @@ export class UnionType< | ||
O extends boolean = false, | ||
// @ts-expect-error | ||
> extends BaseType<TUnion<UnionToTuple<T[number][typeFinal]>>, N, O> { | ||
D extends boolean = false, | ||
> extends BaseType< | ||
//@ts-expect-error | ||
TUnion<UnionToTuple<T[number][typeStatic]['schema']>>, | ||
N, | ||
O, | ||
D | ||
> { | ||
constructor( | ||
readonly types: T, | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super( | ||
Type.Union(types.map((t) => t[typeFinalSchema])) as any, | ||
nullable, | ||
optional, | ||
) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
//@ts-expect-error | ||
): TUnion<UnionToTuple<T[number][typeStatic]['schema']>> { | ||
return Type.Union(this.types.map(getTypeSchema), options) as any | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new UnionType(this.types, ...args) | ||
return new UnionType(this.types, ...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new UnionType(this.types, ...args) | ||
return new UnionType(this.types, ...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new UnionType(this.types, ...args) | ||
return new UnionType( | ||
this.types, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: this[typeStatic]['encoded']) { | ||
return new UnionType( | ||
this.types, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new UnionType( | ||
this.types, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples( | ||
...examples: [this[typeStatic]['encoded'], ...this[typeStatic]['encoded'][]] | ||
) { | ||
return new UnionType(this.types, ...this._with({ options: { examples } })) | ||
} | ||
} | ||
@@ -52,30 +90,64 @@ | ||
O extends boolean = false, | ||
D extends boolean = false, | ||
> extends BaseType< | ||
// @ts-expect-error | ||
> extends BaseType<TIntersect<UnionToTuple<T[number][typeFinal]>>, N, O> { | ||
TIntersect<UnionToTuple<T[number][typeStatic]['schema']>>, | ||
N, | ||
O, | ||
D | ||
> { | ||
constructor( | ||
readonly types: T, | ||
nullable: N = false as N, | ||
optional: O = false as O, | ||
options: SchemaOptions = {}, | ||
isNullable: N = false as N, | ||
isOptional: O = false as O, | ||
hasDefault: D = false as D, | ||
) { | ||
super( | ||
Type.Intersect(types.map((t) => t[typeFinalSchema])) as any, | ||
nullable, | ||
optional, | ||
) | ||
super(options, isNullable, isOptional, hasDefault) | ||
} | ||
protected _constructSchema( | ||
options: SchemaOptions, | ||
// @ts-expect-error | ||
): TIntersect<UnionToTuple<T[number][typeStatic]['schema']>> { | ||
return Type.Intersect(this.types.map(getTypeSchema), options) as any | ||
} | ||
nullable() { | ||
const [_, ...args] = this._nullable() | ||
return new IntersactionType(this.types, ...args) | ||
return new IntersactionType(this.types, ...this._with({ isNullable: true })) | ||
} | ||
optional() { | ||
const [_, ...args] = this._optional() | ||
return new IntersactionType(this.types, ...args) | ||
return new IntersactionType(this.types, ...this._with({ isOptional: true })) | ||
} | ||
nullish() { | ||
const [_, ...args] = this._nullish() | ||
return new IntersactionType(this.types, ...args) | ||
return new IntersactionType( | ||
this.types, | ||
...this._with({ isNullable: true, isOptional: true }), | ||
) | ||
} | ||
default(value: this[typeStatic]['encoded']) { | ||
return new IntersactionType( | ||
this.types, | ||
...this._with({ options: { default: value }, hasDefault: true }), | ||
) | ||
} | ||
description(description: string) { | ||
return new IntersactionType( | ||
this.types, | ||
...this._with({ options: { description } }), | ||
) | ||
} | ||
examples( | ||
...values: [this[typeStatic]['encoded'], ...this[typeStatic]['encoded'][]] | ||
) { | ||
return new IntersactionType( | ||
this.types, | ||
...this._with({ options: { examples: values } }), | ||
) | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
214335
73
3493