-
-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Close #288, generated functions are optimized #289
Conversation
@samchon That's cool :) Btw, were you going to update these schemas? AjvAjvArrayRecursiveUnionImplicit.tsimport { TSchema, Type } from "@sinclair/typebox";
import Ajv from "ajv";
const ImageFile = Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
width: Type.Number(),
height: Type.Number(),
url: Type.String(),
size: Type.Number(),
},
{
additionalProperties: false,
},
);
const TextFile = Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
size: Type.Number(),
content: Type.String(),
},
{
additionalProperties: false,
},
);
const ZipFile = Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
size: Type.Number(),
count: Type.Number(),
},
{
additionalProperties: false,
},
);
const Shortcut = <T extends TSchema>(bucket: T) =>
Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
target: bucket,
},
{
additionalProperties: false,
},
);
const Directory = (bucket: TSchema) =>
Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
children: Type.Array(bucket),
},
{
additionalProperties: false,
},
);
const SharedDirectory = (bucket: TSchema) =>
Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
children: Type.Array(bucket),
access: Type.Union([Type.Literal("read"), Type.Literal("write")]),
},
{
additionalProperties: false,
},
);
const Bucket = Type.Recursive((bucket) =>
Type.Union([
ImageFile,
TextFile,
ZipFile,
Shortcut(bucket),
Directory(bucket),
SharedDirectory(bucket),
]),
);
export const __AjvArrayRecursiveUnionImplicit = Type.Array(Bucket);
const ajv = new Ajv();
const validate = ajv.compile(__AjvArrayRecursiveUnionImplicit);
export const AjvArrayRecursiveUnionImplicit = {
Check: (input: unknown) => validate(input) as boolean,
}; TypeBox
TypeBoxArrayRecursiveUnionImplicit.tsimport { TSchema, Type } from "@sinclair/typebox";
import { TypeCompiler } from "@sinclair/typebox/compiler";
const ImageFile = Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
width: Type.Number(),
height: Type.Number(),
url: Type.String(),
size: Type.Number(),
},
{
additionalProperties: false,
},
);
const TextFile = Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
size: Type.Number(),
content: Type.String(),
},
{
additionalProperties: false,
},
);
const ZipFile = Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
size: Type.Number(),
count: Type.Number(),
},
{
additionalProperties: false,
},
);
const Shortcut = <T extends TSchema>(bucket: T) =>
Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
target: bucket,
},
{
additionalProperties: false,
},
);
const Directory = (bucket: TSchema) =>
Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
children: Type.Array(bucket),
},
{
additionalProperties: false,
},
);
const SharedDirectory = (bucket: TSchema) =>
Type.Object(
{
id: Type.Number(),
name: Type.String(),
path: Type.String(),
children: Type.Array(bucket),
access: Type.Union([Type.Literal("read"), Type.Literal("write")]),
},
{
additionalProperties: false,
},
);
const Bucket = Type.Recursive((bucket) =>
Type.Union([
ImageFile,
TextFile,
ZipFile,
Shortcut(bucket),
Directory(bucket),
SharedDirectory(bucket),
]),
);
export const __TypeBoxArrayRecursiveUnionImplicit = Type.Array(Bucket);
export const TypeBoxArrayRecursiveUnionImplicit = TypeCompiler.Compile(
__TypeBoxArrayRecursiveUnionImplicit,
); TypeBoxObjectUnionImplicit.tsimport { Type } from "@sinclair/typebox";
import { TypeCompiler } from "@sinclair/typebox/compiler";
const Point = Type.Object(
{
x: Type.Number(),
y: Type.Number(),
slope: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
},
{ additionalProperties: Type.Undefined() },
);
const Line = Type.Object(
{
p1: Point,
p2: Point,
distance: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
},
{ additionalProperties: Type.Undefined() },
);
const Triangle = Type.Object(
{
p1: Point,
p2: Point,
p3: Point,
width: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
height: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
area: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
},
{ additionalProperties: Type.Undefined() },
);
const Rectangle = Type.Object(
{
p1: Point,
p2: Point,
p3: Point,
p4: Point,
width: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
height: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
area: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
},
{ additionalProperties: Type.Undefined() },
);
const Polyline = Type.Object(
{
points: Type.Array(Point),
length: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
},
{ additionalProperties: Type.Undefined() },
);
const Polygon = Type.Object(
{
outer: Polyline,
inner: Type.Optional(Type.Array(Polyline)),
area: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
},
{ additionalProperties: Type.Undefined() },
);
const Circle = Type.Object(
{
centroid: Type.Optional(Point),
radius: Type.Number(),
area: Type.Optional(Type.Union([Type.Null(), Type.Number()])),
},
{ additionalProperties: Type.Undefined() },
);
const Union = Type.Union([
Point,
Line,
Triangle,
Rectangle,
Polyline,
Polygon,
Circle,
]);
export const __TypeBoxObjectUnionImplicit = Type.Array(Union);
export const TypeBoxObjectUnionImplicit = TypeCompiler.Compile(
__TypeBoxObjectUnionImplicit,
); TypeBoxUltimateUnion.tsimport { TSchema, Type } from "@sinclair/typebox";
import { TypeCompiler } from "@sinclair/typebox/compiler";
const Attribute = {
description: Type.Optional(Type.String()),
"x-tson-metaTags": Type.Optional(
Type.Array(
Type.Object({
// @todo - must be specified, but too hard
kind: Type.String(),
}),
),
),
"x-tson-jsDocTags": Type.Optional(
Type.Array(
Type.Object({
name: Type.String(),
text: Type.Optional(
Type.Array(
Type.Object({
text: Type.String(),
kind: Type.String(),
}),
),
),
}),
),
),
};
const Unknown = Type.Object(
{
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
const NullOnly = Type.Object(
{
type: Type.Literal("null"),
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
const Atomic = (literal: string, type: () => any) => {
return Type.Object(
{
type: Type.Literal(literal),
nullable: Type.Boolean(),
default: Type.Optional(type()),
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
};
const Constant = (literal: string, type: () => any) =>
Type.Intersect(
[
Atomic(literal, type),
Type.Object({
enum: Type.Array(type()),
}),
],
{ additionalProperties: Type.Undefined() },
);
const Array = <T extends TSchema>(schema: T) =>
Type.Object(
{
type: Type.Literal("array"),
items: schema,
nullable: Type.Boolean(),
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
const Tuple = <T extends TSchema>(schema: T) =>
Type.Object(
{
type: Type.Literal("array"),
items: Type.Array(schema),
nullable: Type.Boolean(),
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
const Reference = Type.Object(
{
$ref: Type.String(),
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
const RecursiveReference = Type.Object(
{
$recursiveRef: Type.String(),
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
const OneOf = <T extends TSchema>(schema: T) =>
Type.Object(
{
oneOf: Type.Array(schema),
...Attribute,
},
{ additionalProperties: Type.Undefined() },
);
const ObjectDef = <T extends TSchema>(schema: T) =>
Type.Object(
{
$id: Type.Optional(Type.String()),
type: Type.Literal("object"),
nullable: Type.Boolean(),
properties: Type.Record(Type.String(), schema),
patternProperties: Type.Optional(
Type.Record(Type.String(), schema),
),
additionalProperties: Type.Optional(schema),
required: Type.Optional(Type.Array(Type.String())),
description: Type.Optional(Type.String()),
"x-tson_jsDocTags": Type.Optional(Type.Array(Type.Any())),
$recursiveAnchor: Type.Optional(Type.Boolean()),
},
{ additionalProperties: Type.Undefined() },
);
const Components = <T extends TSchema>(schema: T) =>
Type.Object(
{
schemas: Type.Record(Type.String(), ObjectDef(schema)),
},
{ additionalProperties: Type.Undefined() },
);
const Application = <T extends TSchema>(schema: T) =>
Type.Object(
{
schemas: Type.Array(schema),
components: Components(schema),
purpose: Type.Union([Type.Literal("swagger"), Type.Literal("ajv")]),
prefix: Type.String(),
},
{ additionalProperties: Type.Undefined() },
);
const Schema = Type.Recursive((schema) =>
Type.Union([
Atomic("boolean", () => Type.Boolean()),
Atomic("integer", () => Type.Number()),
Atomic("bigint", () => Type.Number()),
Atomic("number", () => Type.Number()),
Atomic("string", () => Type.String()),
Constant("boolean", () => Type.Boolean()),
Constant("integer", () => Type.Number()),
Constant("bigint", () => Type.Number()),
Constant("number", () => Type.Number()),
Constant("string", () => Type.String()),
Array(schema),
Tuple(schema),
Reference,
RecursiveReference,
OneOf(schema),
Unknown,
NullOnly,
]),
);
export const __TypeBoxUltimateUnion = Type.Array(Application(Schema));
export const TypeBoxUltimateUnion = TypeCompiler.Compile(
__TypeBoxUltimateUnion,
); I'm actually super keen to see TSON / Ajv validation alignment most of all. Would be great get the schemas aligned as good as possible so they might serve as a good reference point for future updates to See comment #258 (comment) for a possible Feature Request (and reference implementation TS compiler codegen project here which you're free to use and extend) Cheers mate! |
@sinclairzx81: found a million percent faster case in
TypeBox
.