Skip to content

Commit 925af75

Browse files
committed
feat: add TypeScript configuration files and schemas for arktype, valibot, zod3, and zod4
- Introduced new tsconfig files for arktype, valibot, zod3, and zod4 with appropriate compiler options. - Added user, product, order, address, customer, blog post, configuration, event, image metadata, employee, and task schemas for arktype, valibot, zod3, and zod4. - Updated package.json to include new benchmarking script for TypeScript checks.
1 parent b7a01c9 commit 925af75

File tree

11 files changed

+637
-8
lines changed

11 files changed

+637
-8
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,16 @@
4949
"scripts": {
5050
"bench": "bun bench:bun --warmup 5 --runs 10",
5151
"bench:bun": "hyperfine 'bun src/arktype.ts' 'bun src/suretype.ts' 'bun src/valibot.ts' 'bun src/zod-mini.ts' 'bun src/zod3.ts' 'bun src/zod4.ts'",
52+
"bench:types": "hyperfine --warmup 5 --runs 10 'npx tsc -p tsconfig.arktype.json' 'npx tsc -p tsconfig.valibot.json' 'npx tsc -p tsconfig.zod3.json' 'npx tsc -p tsconfig.zod4.json'",
5253
"bench:node": "hyperfine --runs 10 'node dist/arktype.js' 'node dist/valibot.js' 'node dist/zod-mini.js' 'node dist/zod3.js' 'node dist/zod4.js'",
5354
"bench:node:strip": "hyperfine --runs 10 'node --experimental-strip-types src/arktype.ts' 'node --experimental-strip-types src/valibot.ts' 'node --experimental-strip-types src/zod-mini.ts' 'node --experimental-strip-types src/zod3.ts' 'node --experimental-strip-types src/zod4.ts'",
5455
"build": "bun scripts/build.ts && echo build success",
5556
"check": "pnpm i && bun check:tsc && bun check:biome && bun run build && bun check:once && echo check success",
5657
"check:biome": "biome check --error-on-warnings --write --unsafe src && echo check:biome success",
5758
"check:once": "bun src/arktype.ts && bun src/suretype.ts && bun src/valibot.ts && bun src/zod-mini.ts && bun src/zod3.ts && bun src/zod4.ts && echo check:once success",
5859
"check:repo": "repo-check && echo check:repo success",
59-
"check:tsc": "tsc --noEmit && echo check:tsc success"
60+
"check:tsc": "tsc --noEmit -p tsconfig.app.json && echo check:tsc success"
6061
},
6162
"type": "module",
6263
"version": "1.0.0"
63-
}
64+
}

src/schemas/arktype.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import { type } from "arktype";
2+
3+
export const userSchema = type({
4+
name: type.string,
5+
age: type.number.default(42),
6+
phone: type.string
7+
.or(type.number)
8+
.pipe((phone: string | number) =>
9+
typeof phone === "number" ? phone.toString() : phone
10+
)
11+
.default("123-456-7890"),
12+
});
13+
14+
export type User = typeof userSchema.inferOut;
15+
16+
export type UserInput = typeof userSchema.inferIn;
17+
18+
// 1. Product Schema
19+
export const productSchema = type({
20+
id: type.string,
21+
name: type.string,
22+
price: type.number.moreThan(0),
23+
inStock: type.boolean,
24+
tags: type.string.array(),
25+
});
26+
export type Product = typeof productSchema.infer;
27+
28+
// 2. Order Schema
29+
export const orderSchema = type({
30+
orderId: "string.uuid.v4",
31+
userId: type.string,
32+
items: productSchema.array(),
33+
totalAmount: type.number,
34+
orderDate: type.Date,
35+
status: type("'pending'|'shipped'|'delivered'|'cancelled'"),
36+
});
37+
export type Order = typeof orderSchema.infer;
38+
39+
// 3. Address Schema
40+
export const addressSchema = type({
41+
street: type.string,
42+
city: type.string,
43+
state: type.string,
44+
zipCode: /^[0-9]{5}(?:-[0-9]{4})?$/,
45+
country: type.string.default("USA"),
46+
});
47+
export type Address = typeof addressSchema.infer;
48+
49+
// 4. Customer Schema
50+
export const customerSchema = type({
51+
customerId: type.string,
52+
basicInfo: userSchema,
53+
shippingAddress: addressSchema,
54+
billingAddress: addressSchema.or(type.null),
55+
purchaseHistory: orderSchema.array().optional(),
56+
});
57+
export type Customer = typeof customerSchema.inferOut;
58+
export type CustomerInput = typeof customerSchema.inferIn;
59+
60+
// 5. BlogPost Schema
61+
export const blogPostSchema = type({
62+
postId: type.number.moreThan(0),
63+
title: type.string,
64+
content: type.string,
65+
authorId: type.string,
66+
publishDate: type.Date.or(type.undefined),
67+
metadata: {
68+
views: type.number.atLeast(0),
69+
likes: type.number.atLeast(0),
70+
category: type.string,
71+
},
72+
});
73+
export type BlogPost = typeof blogPostSchema.infer;
74+
75+
// 6. Configuration Schema
76+
export const configSchema = type({
77+
apiKey: type.string,
78+
timeoutMs: type.number.moreThan(0).default(5000),
79+
retries: type.number.atLeast(0).atMost(5),
80+
featureFlags: {
81+
"betaFeature?": type.boolean,
82+
newUI: type.boolean.default(false),
83+
},
84+
"logLevel?": type("'debug'|'info'|'warn'|'error'"),
85+
});
86+
export type Config = typeof configSchema.inferOut;
87+
export type ConfigInput = typeof configSchema.inferIn;
88+
89+
// 7. Event Schema
90+
export const eventSchema = type({
91+
eventId: type.string,
92+
eventName: type.string,
93+
timestamp: type.number,
94+
payload: type.unknown,
95+
source: type("'web'|'mobile'|'server'"),
96+
});
97+
export type Event = typeof eventSchema.infer;
98+
99+
// 8. Image Metadata Schema
100+
export const imageMetadataSchema = type({
101+
url: "string.url",
102+
width: type.number.moreThan(0),
103+
height: type.number.moreThan(0),
104+
format: type("'jpeg'|'png'|'gif'|'webp'"),
105+
"caption?": type.string.atMostLength(255),
106+
});
107+
export type ImageMetadata = typeof imageMetadataSchema.infer;
108+
109+
// 9. Employee Schema
110+
export const employeeSchema = type({
111+
employeeId: type.string,
112+
firstName: type.string,
113+
lastName: type.string,
114+
email: "string.email",
115+
department: type.string,
116+
startDate: type.Date,
117+
isActive: type.boolean,
118+
"managerId?": type.string.or(type.null),
119+
});
120+
export type Employee = typeof employeeSchema.infer;
121+
122+
// 10. Task Schema
123+
export const taskSchema = type({
124+
taskId: type.string,
125+
description: type.string,
126+
dueDate: type.Date.optional(),
127+
priority: type("'low'|'medium'|'high'"),
128+
completed: type.boolean.default(false),
129+
assignee: employeeSchema.or(type.null),
130+
});
131+
export type Task = typeof taskSchema.inferOut;
132+
export type TaskInput = typeof taskSchema.inferIn;

src/schemas/valibot.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import * as v from "valibot";
2+
3+
// User Schema
4+
export const userSchema = v.object({
5+
name: v.string(),
6+
age: v.optional(v.number(), 42),
7+
phone: v.pipe(
8+
v.optional(v.union([v.string(), v.number()]), "123-456-7890"),
9+
v.transform((phone: string | number) =>
10+
typeof phone === "number" ? phone.toString() : phone
11+
)
12+
),
13+
});
14+
15+
export type User = v.InferOutput<typeof userSchema>;
16+
export type UserInput = v.InferInput<typeof userSchema>;
17+
18+
// 1. Product Schema
19+
export const productSchema = v.object({
20+
id: v.string(),
21+
name: v.string(),
22+
price: v.pipe(v.number(), v.minValue(0.01)),
23+
inStock: v.boolean(),
24+
tags: v.array(v.string()),
25+
});
26+
export type Product = v.InferOutput<typeof productSchema>;
27+
28+
// 2. Order Schema
29+
export const orderSchema = v.object({
30+
orderId: v.pipe(v.string(), v.uuid()),
31+
userId: v.string(),
32+
items: v.array(productSchema),
33+
totalAmount: v.number(),
34+
orderDate: v.date(),
35+
status: v.picklist(["pending", "shipped", "delivered", "cancelled"]),
36+
});
37+
export type Order = v.InferOutput<typeof orderSchema>;
38+
39+
// 3. Address Schema
40+
export const addressSchema = v.object({
41+
street: v.string(),
42+
city: v.string(),
43+
state: v.string(),
44+
zipCode: v.pipe(v.string(), v.regex(/^[0-9]{5}(?:-[0-9]{4})?$/)),
45+
country: v.optional(v.string(), "USA"),
46+
});
47+
export type Address = v.InferOutput<typeof addressSchema>;
48+
49+
// 4. Customer Schema
50+
export const customerSchema = v.object({
51+
customerId: v.string(),
52+
basicInfo: userSchema,
53+
shippingAddress: addressSchema,
54+
billingAddress: v.nullable(addressSchema),
55+
purchaseHistory: v.optional(v.array(orderSchema)),
56+
});
57+
export type Customer = v.InferOutput<typeof customerSchema>;
58+
export type CustomerInput = v.InferInput<typeof customerSchema>;
59+
60+
// 5. BlogPost Schema
61+
export const blogPostSchema = v.object({
62+
postId: v.pipe(v.number(), v.minValue(1)),
63+
title: v.string(),
64+
content: v.string(),
65+
authorId: v.string(),
66+
publishDate: v.optional(v.date()),
67+
metadata: v.object({
68+
views: v.pipe(v.number(), v.integer(), v.minValue(0)),
69+
likes: v.pipe(v.number(), v.integer(), v.minValue(0)),
70+
category: v.string(),
71+
}),
72+
});
73+
export type BlogPost = v.InferOutput<typeof blogPostSchema>;
74+
75+
// 6. Configuration Schema
76+
export const configSchema = v.object({
77+
apiKey: v.string(),
78+
timeoutMs: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1)), 5000),
79+
retries: v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(5)),
80+
featureFlags: v.object({
81+
betaFeature: v.optional(v.boolean()),
82+
newUI: v.optional(v.boolean(), false),
83+
}),
84+
logLevel: v.optional(v.picklist(["debug", "info", "warn", "error"])),
85+
});
86+
export type Config = v.InferOutput<typeof configSchema>;
87+
export type ConfigInput = v.InferInput<typeof configSchema>;
88+
89+
// 7. Event Schema
90+
export const eventSchema = v.object({
91+
eventId: v.string(),
92+
eventName: v.string(),
93+
timestamp: v.number(),
94+
payload: v.unknown(),
95+
source: v.picklist(["web", "mobile", "server"]),
96+
});
97+
export type Event = v.InferOutput<typeof eventSchema>;
98+
99+
// 8. Image Metadata Schema
100+
export const imageMetadataSchema = v.object({
101+
url: v.pipe(v.string(), v.url()),
102+
width: v.pipe(v.number(), v.integer(), v.minValue(1)),
103+
height: v.pipe(v.number(), v.integer(), v.minValue(1)),
104+
format: v.picklist(["jpeg", "png", "gif", "webp"]),
105+
caption: v.optional(v.pipe(v.string(), v.maxLength(255))),
106+
});
107+
export type ImageMetadata = v.InferOutput<typeof imageMetadataSchema>;
108+
109+
// 9. Employee Schema
110+
export const employeeSchema = v.object({
111+
employeeId: v.string(),
112+
firstName: v.string(),
113+
lastName: v.string(),
114+
email: v.pipe(v.string(), v.email()),
115+
department: v.string(),
116+
startDate: v.date(),
117+
isActive: v.boolean(),
118+
managerId: v.optional(v.nullable(v.string())),
119+
});
120+
export type Employee = v.InferOutput<typeof employeeSchema>;
121+
122+
// 10. Task Schema
123+
export const taskSchema = v.object({
124+
taskId: v.string(),
125+
description: v.string(),
126+
dueDate: v.optional(v.date()),
127+
priority: v.picklist(["low", "medium", "high"]),
128+
completed: v.optional(v.boolean(), false),
129+
assignee: v.nullable(employeeSchema),
130+
});
131+
export type Task = v.InferOutput<typeof taskSchema>;
132+
export type TaskInput = v.InferInput<typeof taskSchema>;

0 commit comments

Comments
 (0)