lightv-schema 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Danil Yeremenchuk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # LightvSchema
2
+
3
+ LightvSchema is a lightweight schema validation library for TypeScript. It provides a simple and efficient way to validate data structures.
4
+
5
+ ## Features
6
+
7
+ - Lightweight: Minimal footprint with no external dependencies.
8
+ - Type-safe: Leverages TypeScript's type system for compile-time validation.
9
+ - Flexible: Supports custom validation functions and error messages.
10
+ - Extensible: Easily extendable to accommodate new validation rules.
11
+
12
+ ## Warning
13
+
14
+ This library is my educational project. It is not intended for production use. Use at your own risk.
15
+
16
+ ## Installation
17
+
18
+ You can install LightvSchema using npm or bun:
19
+
20
+ ```bash
21
+ npm install lightv-schema
22
+ ```
23
+
24
+ or
25
+
26
+ ```bash
27
+ bun add lightv-schema
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ LightvSchema provides a simple API for defining and validating data structures. Here's a quick example:
33
+
34
+ ```typescript
35
+ import { type, transform, validate, parse } from "lightv-schema";
36
+
37
+ const User = type.Object({
38
+ id: type.Int(),
39
+ name: validate.Min(type.String(), 5),
40
+ email: type.String(),
41
+ age: transform.ToInt(type.String()),
42
+ isActive: type.Boolean(),
43
+ friends: type.Array(type.Object({ id: type.Int(), name: type.String() })),
44
+ role: type.Union([type.Literal("admin"), type.Literal("user")]),
45
+ });
46
+
47
+ type User = typeof User.infer;
48
+
49
+ const userString = `{
50
+ "id": 1,
51
+ "name": "John Doe",
52
+ "email": "test@some.com",
53
+ "age": "123",
54
+ "isActive": true,
55
+ "friends": [
56
+ { "id": 2, "name": "Jane Doe" },
57
+ { "id": 3, "name": "Jack Doe" }
58
+ ],
59
+ "role": "admin"
60
+ }`;
61
+ const result = parse(User, JSON.parse(userString));
62
+
63
+ if ("success" in result) {
64
+ console.log("Parsed user:", result.success);
65
+ } else {
66
+ console.log("Failed to parse user:", result.failure);
67
+ }
68
+
69
+ export { type, transform, validate, parse };
70
+ ```
71
+
72
+ Also easy to extend:
73
+
74
+ ```typescript
75
+ import type { Scheme } from "lightv-schema/scheme";
76
+ import { validate } from "lightv-schema";
77
+
78
+ export function Min<const Item extends Scheme>(
79
+ item: Item,
80
+ min: number,
81
+ message?: string
82
+ ) {
83
+ return validate.Validator(item, (value) => {
84
+ if (typeof value === "number" && value < min) {
85
+ return {
86
+ failure: [message ?? `Number must be greater than or equal to ${min}`],
87
+ };
88
+ } else if (typeof value === "string" && value.length < min) {
89
+ return {
90
+ failure: [message ?? `String must be at least ${min} characters long`],
91
+ };
92
+ } else if (Array.isArray(value) && value.length < min) {
93
+ return {
94
+ failure: [message ?? `Array must have at least ${min} elements`],
95
+ };
96
+ }
97
+ return { success: value };
98
+ });
99
+ }
100
+ ```
@@ -0,0 +1,5 @@
1
+ import * as type from "./types";
2
+ import * as transform from "./transformers";
3
+ import * as validate from "./validators";
4
+ import { parse } from "./utils";
5
+ export { type, transform, validate, parse };
package/dist/index.js ADDED
@@ -0,0 +1,367 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+
12
+ // src/types.ts
13
+ var exports_types = {};
14
+ __export(exports_types, {
15
+ Union: () => Union,
16
+ Tuple: () => Tuple,
17
+ String: () => String,
18
+ Object: () => Object2,
19
+ Nullable: () => Nullable,
20
+ None: () => None,
21
+ Literal: () => Literal,
22
+ Int: () => Int,
23
+ Float: () => Float,
24
+ Boolean: () => Boolean,
25
+ Array: () => Array2
26
+ });
27
+ function Literal(literal, message) {
28
+ return {
29
+ type: "literal",
30
+ literal,
31
+ message
32
+ };
33
+ }
34
+ function None() {
35
+ return {
36
+ type: "none"
37
+ };
38
+ }
39
+ function Int(message) {
40
+ return {
41
+ type: "int",
42
+ message
43
+ };
44
+ }
45
+ function Float(message) {
46
+ return {
47
+ type: "float",
48
+ message
49
+ };
50
+ }
51
+ function String(message) {
52
+ return {
53
+ type: "string",
54
+ message
55
+ };
56
+ }
57
+ function Boolean(message) {
58
+ return {
59
+ type: "boolean",
60
+ message
61
+ };
62
+ }
63
+ function Array2(item, message) {
64
+ return {
65
+ type: "array",
66
+ item,
67
+ message
68
+ };
69
+ }
70
+ function Union(items, message) {
71
+ return {
72
+ type: "union",
73
+ items,
74
+ message
75
+ };
76
+ }
77
+ function Tuple(items, message) {
78
+ return {
79
+ type: "tuple",
80
+ items,
81
+ message
82
+ };
83
+ }
84
+ function Object2(props, message) {
85
+ return {
86
+ type: "object",
87
+ props,
88
+ message
89
+ };
90
+ }
91
+ function Nullable(item, message) {
92
+ return {
93
+ type: "nullable",
94
+ item,
95
+ message
96
+ };
97
+ }
98
+
99
+ // src/transformers.ts
100
+ var exports_transformers = {};
101
+ __export(exports_transformers, {
102
+ Transformer: () => Transformer,
103
+ ToString: () => ToString,
104
+ ToInt: () => ToInt
105
+ });
106
+ function Transformer(from, to, transformer) {
107
+ return {
108
+ type: "transform",
109
+ from,
110
+ to,
111
+ transformer
112
+ };
113
+ }
114
+ function ToString(from, message) {
115
+ return Transformer(from, String(), (value) => {
116
+ if (value === null || value === undefined) {
117
+ return { success: "" };
118
+ }
119
+ return { success: value.toString() };
120
+ });
121
+ }
122
+ function ToInt(from, message) {
123
+ return Transformer(from, Int(), (value) => {
124
+ if (value === null || value === undefined) {
125
+ return { failure: [message ?? `Expected integer`] };
126
+ }
127
+ if (typeof value === "number") {
128
+ return { success: Math.floor(value) };
129
+ } else if (typeof value === "string") {
130
+ const parsed = parseInt(value, 10);
131
+ if (isNaN(parsed)) {
132
+ return { failure: [message ?? `Expected integer`] };
133
+ }
134
+ return { success: parsed };
135
+ }
136
+ return { failure: [message ?? `Expected integer`] };
137
+ });
138
+ }
139
+
140
+ // src/validators.ts
141
+ var exports_validators = {};
142
+ __export(exports_validators, {
143
+ Validator: () => Validator,
144
+ Min: () => Min,
145
+ Max: () => Max
146
+ });
147
+ function Validator(item, validator) {
148
+ return {
149
+ type: "validation",
150
+ item,
151
+ validator
152
+ };
153
+ }
154
+ function Min(item, min, message) {
155
+ return Validator(item, (value) => {
156
+ if (typeof value === "number" && value < min) {
157
+ return {
158
+ failure: [message ?? `Number must be greater than or equal to ${min}`]
159
+ };
160
+ } else if (typeof value === "string" && value.length < min) {
161
+ return {
162
+ failure: [message ?? `String must be at least ${min} characters long`]
163
+ };
164
+ } else if (Array.isArray(value) && value.length < min) {
165
+ return {
166
+ failure: [message ?? `Array must have at least ${min} elements`]
167
+ };
168
+ }
169
+ return { success: value };
170
+ });
171
+ }
172
+ function Max(item, max, message) {
173
+ return Validator(item, (value) => {
174
+ if (typeof value === "number" && value > max) {
175
+ return {
176
+ failure: [message ?? `Number must be less than or equal to ${max}`]
177
+ };
178
+ } else if (typeof value === "string" && value.length > max) {
179
+ return {
180
+ failure: [message ?? `String must be at most ${max} characters long`]
181
+ };
182
+ } else if (Array.isArray(value) && value.length > max) {
183
+ return {
184
+ failure: [message ?? `Array must have at most ${max} elements`]
185
+ };
186
+ }
187
+ return { success: value };
188
+ });
189
+ }
190
+
191
+ // src/result.ts
192
+ function isSuccess(result) {
193
+ return "success" in result;
194
+ }
195
+ function isFailure(result) {
196
+ return "failure" in result;
197
+ }
198
+
199
+ // src/utils.ts
200
+ function parse(schema, value) {
201
+ if (schema.type === "literal") {
202
+ if (value !== schema.literal) {
203
+ return {
204
+ failure: [
205
+ schema.message ?? `Expected ${schema.literal}`
206
+ ]
207
+ };
208
+ }
209
+ return { success: schema.literal };
210
+ } else if (schema.type === "none") {
211
+ if (value !== null && value !== undefined) {
212
+ return {
213
+ failure: [
214
+ schema.message ?? `Expected null or undefined`
215
+ ]
216
+ };
217
+ }
218
+ } else if (schema.type === "int") {
219
+ if (typeof value !== "number" || !Number.isInteger(value)) {
220
+ return {
221
+ failure: [schema.message ?? `Expected integer`]
222
+ };
223
+ }
224
+ return { success: value };
225
+ } else if (schema.type === "float") {
226
+ if (typeof value !== "number") {
227
+ return {
228
+ failure: [schema.message ?? `Expected float`]
229
+ };
230
+ }
231
+ return { success: value };
232
+ } else if (schema.type === "string") {
233
+ if (typeof value !== "string") {
234
+ return {
235
+ failure: [schema.message ?? `Expected string`]
236
+ };
237
+ }
238
+ return { success: value };
239
+ } else if (schema.type === "boolean") {
240
+ if (typeof value !== "boolean") {
241
+ return {
242
+ failure: [schema.message ?? `Expected boolean`]
243
+ };
244
+ }
245
+ return { success: value };
246
+ } else if (schema.type === "array") {
247
+ if (!Array.isArray(value)) {
248
+ return {
249
+ failure: [schema.message ?? `Expected array`]
250
+ };
251
+ }
252
+ const results = value.map((item) => parse(schema.item, item));
253
+ const failures = results.filter(isFailure);
254
+ if (failures.length > 0) {
255
+ return {
256
+ failure: failures.map((result) => result.failure).flat()
257
+ };
258
+ }
259
+ return {
260
+ success: results.filter(isSuccess).map((result) => result.success)
261
+ };
262
+ } else if (schema.type === "tuple") {
263
+ if (!Array.isArray(value)) {
264
+ return {
265
+ failure: [schema.message ?? `Expected tuple`]
266
+ };
267
+ }
268
+ if (value.length !== schema.items.length) {
269
+ return {
270
+ failure: [
271
+ schema.message ?? `Expected tuple of length ${schema.items.length}`
272
+ ]
273
+ };
274
+ }
275
+ const results = value.map((item, index) => parse(schema.items[index], item));
276
+ const failures = results.filter(isFailure);
277
+ if (failures.length > 0) {
278
+ return {
279
+ failure: failures.map((result) => result.failure).flat()
280
+ };
281
+ }
282
+ return {
283
+ success: results.filter((result) => ("success" in result)).map((result) => result.success)
284
+ };
285
+ } else if (schema.type === "union") {
286
+ const results = schema.items.map((item) => parse(item, value));
287
+ const failures = results.filter(isFailure);
288
+ if (failures.length === schema.items.length) {
289
+ return {
290
+ failure: failures.map((result) => result.failure).flat()
291
+ };
292
+ }
293
+ const successes = results.filter(isSuccess);
294
+ if (successes.length > 0) {
295
+ return {
296
+ success: successes[0].success
297
+ };
298
+ }
299
+ return {
300
+ failure: [
301
+ schema.message ?? `Expected one of ${schema.items.map((item) => item.type)}`
302
+ ]
303
+ };
304
+ } else if (schema.type === "object") {
305
+ if (typeof value !== "object" || value === null || value === undefined) {
306
+ return {
307
+ failure: [schema.message ?? `Expected object`]
308
+ };
309
+ }
310
+ const results = Object.entries(schema.props).map(([key, item]) => [key, parse(item, value[key])]);
311
+ const failureValues = {};
312
+ const successValues = {};
313
+ for (const [key, result] of results) {
314
+ if (isFailure(result)) {
315
+ failureValues[key] = result.failure;
316
+ } else {
317
+ successValues[key] = result.success;
318
+ }
319
+ }
320
+ if (Object.keys(failureValues).length > 0) {
321
+ return {
322
+ failure: failureValues
323
+ };
324
+ }
325
+ return { success: successValues };
326
+ } else if (schema.type === "validation") {
327
+ const result = parse(schema.item, value);
328
+ if (isFailure(result)) {
329
+ return result;
330
+ }
331
+ const validationResult = schema.validator(result.success);
332
+ if (isFailure(validationResult)) {
333
+ return {
334
+ failure: validationResult.failure
335
+ };
336
+ }
337
+ return { success: validationResult.success };
338
+ } else if (schema.type === "nullable") {
339
+ if (value === null || value === undefined) {
340
+ return { success: null };
341
+ }
342
+ const result = parse(schema.item, value);
343
+ if (isFailure(result)) {
344
+ return result;
345
+ }
346
+ return { success: result.success };
347
+ } else if (schema.type === "transform") {
348
+ const result = parse(schema.from, value);
349
+ if (isFailure(result)) {
350
+ return result;
351
+ }
352
+ const transformedResult = schema.transformer(result.success);
353
+ if (isFailure(transformedResult)) {
354
+ return {
355
+ failure: transformedResult.failure
356
+ };
357
+ }
358
+ return { success: transformedResult.success };
359
+ }
360
+ throw new Error(`Unsupported scheme type: ${schema.type}`);
361
+ }
362
+ export {
363
+ exports_validators as validate,
364
+ exports_types as type,
365
+ exports_transformers as transform,
366
+ parse
367
+ };
@@ -0,0 +1,13 @@
1
+ export type Success<Value extends unknown> = {
2
+ success: Value;
3
+ };
4
+ export type Failure<Error extends unknown> = {
5
+ failure: Error;
6
+ };
7
+ export type Result<Value extends unknown, Error extends unknown> = Success<Value> | Failure<Error>;
8
+ export declare function isSuccess<Value extends unknown, Error extends unknown>(result: Result<Value, Error>): result is Success<Value>;
9
+ export declare function isFailure<Value extends unknown, Error extends unknown>(result: Result<Value, Error>): result is Failure<Error>;
10
+ export declare function expectSuccess<Value extends unknown, Error extends unknown>(result: Result<Value, Error>, message?: string): Value;
11
+ export declare function expectFailure<Value extends unknown, Error extends unknown>(result: Result<Value, Error>, message?: string): Error;
12
+ export declare function successOr<Value extends unknown, Error extends unknown>(result: Result<Value, Error>, defaultValue: Value): Value;
13
+ export declare function failureOr<Value extends unknown, Error extends unknown>(result: Result<Value, Error>, defaultError: Error): Error;
@@ -0,0 +1,87 @@
1
+ import type { Result } from "./result";
2
+ export type Validator<T extends unknown> = (value: T) => Result<T, string[]>;
3
+ export type Transformer<T extends unknown, U extends unknown> = (value: T) => Result<U, string[]>;
4
+ export type Fold<T extends unknown> = {} & {
5
+ [P in keyof T]: T[P];
6
+ };
7
+ export type LiteralSchema<Literal extends unknown> = {
8
+ readonly type: "literal";
9
+ readonly literal: Literal;
10
+ readonly infer: Literal;
11
+ readonly message?: string;
12
+ };
13
+ export type NoneSchema = {
14
+ readonly type: "none";
15
+ readonly infer: null | undefined;
16
+ readonly message?: string;
17
+ };
18
+ export type IntSchema = {
19
+ readonly type: "int";
20
+ readonly infer: number;
21
+ readonly message?: string;
22
+ };
23
+ export type FloatSchema = {
24
+ readonly type: "float";
25
+ readonly infer: number;
26
+ readonly message?: string;
27
+ };
28
+ export type StringSchema = {
29
+ readonly type: "string";
30
+ readonly infer: string;
31
+ readonly message?: string;
32
+ };
33
+ export type BooleanSchema = {
34
+ readonly type: "boolean";
35
+ readonly infer: boolean;
36
+ readonly message?: string;
37
+ };
38
+ export type ArraySchema<Item extends Schema> = {
39
+ readonly type: "array";
40
+ readonly item: Item;
41
+ readonly infer: Item["infer"][];
42
+ readonly message?: string;
43
+ };
44
+ export type UnionSchema<Items extends ReadonlyArray<Schema>> = {
45
+ readonly type: "union";
46
+ readonly items: Items;
47
+ readonly infer: Items[number]["infer"];
48
+ readonly message?: string;
49
+ };
50
+ export type TupleSchema<Items extends ReadonlyArray<Schema>> = {
51
+ readonly type: "tuple";
52
+ readonly items: Items;
53
+ readonly infer: {
54
+ [Index in keyof Items]: Items[Index]["infer"];
55
+ };
56
+ readonly message?: string;
57
+ };
58
+ export type ObjectSchema<Props extends Record<string, Schema>> = {
59
+ readonly type: "object";
60
+ readonly props: Props;
61
+ readonly infer: Fold<{
62
+ -readonly [Key in keyof Props as Props[Key] extends NullableSchema<any> ? never : Key]: Props[Key]["infer"];
63
+ } & {
64
+ -readonly [Key in keyof Props as Props[Key] extends NullableSchema<any> ? Key : never]?: Props[Key]["infer"];
65
+ }>;
66
+ readonly message?: string;
67
+ };
68
+ export type NullableSchema<Item extends Schema> = {
69
+ readonly type: "nullable";
70
+ readonly item: Item;
71
+ readonly infer: Item["infer"] | null | undefined;
72
+ readonly message?: string;
73
+ };
74
+ export type ValidationSchema<Item extends Schema> = {
75
+ readonly type: "validation";
76
+ readonly item: Item;
77
+ readonly validator: Validator<Item>;
78
+ readonly infer: Item["infer"];
79
+ };
80
+ export type TransformSchema<From extends Schema, To extends Schema> = {
81
+ readonly type: "transform";
82
+ readonly from: From;
83
+ readonly to: To;
84
+ readonly transformer: Transformer<From["infer"], To["infer"]>;
85
+ readonly infer: To["infer"];
86
+ };
87
+ export type Schema = LiteralSchema<any> | NoneSchema | IntSchema | FloatSchema | StringSchema | BooleanSchema | ArraySchema<any> | UnionSchema<any[]> | TupleSchema<any[]> | ObjectSchema<any> | NullableSchema<any> | ValidationSchema<any> | TransformSchema<any, any>;
@@ -0,0 +1,4 @@
1
+ import type { Schema, Transformer, TransformSchema } from "./schema";
2
+ export declare function Transformer<const From extends Schema, const To extends Schema>(from: From, to: To, transformer: Transformer<From["infer"], To["infer"]>): TransformSchema<From, To>;
3
+ export declare function ToString<const From extends Schema>(from: From, message?: string): TransformSchema<From, import("./schema").StringSchema>;
4
+ export declare function ToInt<const From extends Schema>(from: From, message?: string): TransformSchema<From, import("./schema").IntSchema>;
@@ -0,0 +1,12 @@
1
+ import type { Schema, ArraySchema, BooleanSchema, FloatSchema, IntSchema, NullableSchema, ObjectSchema, StringSchema, TupleSchema, UnionSchema, LiteralSchema, NoneSchema } from "./schema";
2
+ export declare function Literal<T extends string | number | boolean>(literal: T, message?: string): LiteralSchema<T>;
3
+ export declare function None(): NoneSchema;
4
+ export declare function Int(message?: string): IntSchema;
5
+ export declare function Float(message?: string): FloatSchema;
6
+ export declare function String(message?: string): StringSchema;
7
+ export declare function Boolean(message?: string): BooleanSchema;
8
+ export declare function Array<const Item extends Schema>(item: Item, message?: string): ArraySchema<Item>;
9
+ export declare function Union<const Items extends ReadonlyArray<Schema>>(items: Items, message?: string): UnionSchema<Items>;
10
+ export declare function Tuple<const Items extends ReadonlyArray<Schema>>(items: Items, message?: string): TupleSchema<Items>;
11
+ export declare function Object<Props extends Record<string, Schema>>(props: Props, message?: string): ObjectSchema<Props>;
12
+ export declare function Nullable<S extends Schema>(item: S, message?: string): NullableSchema<S>;
@@ -0,0 +1,7 @@
1
+ import { type Result } from "./result";
2
+ import type { Schema } from "./schema";
3
+ type ParseError<Value extends unknown = unknown> = Value extends Record<string, unknown> ? {
4
+ [K in keyof Value]: ParseError<Value[K]>;
5
+ } : string[];
6
+ export declare function parse<const S extends Schema, Infer extends unknown = S["infer"]>(schema: S, value: unknown): Result<Infer, ParseError<Infer>>;
7
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { Schema, ValidationSchema, Validator } from "./schema";
2
+ export declare function Validator<const Item extends Schema>(item: Item, validator: Validator<Item["infer"]>): ValidationSchema<Item>;
3
+ export declare function Min<const Item extends Schema>(item: Item, min: number, message?: string): ValidationSchema<Item>;
4
+ export declare function Max<const Item extends Schema>(item: Item, max: number, message?: string): ValidationSchema<Item>;
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "lightv-schema",
3
+ "version": "0.0.1",
4
+ "description": "A lightweight schema validation library for TypeScript.",
5
+ "module": "src/index.ts",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist/*.js",
11
+ "dist/*.d.ts"
12
+ ],
13
+ "scripts": {
14
+ "build": "bun build --target=node ./src/index.ts --outfile=dist/index.js && bun run build:declaration",
15
+ "build:declaration": "tsc --emitDeclarationOnly --project tsconfig.types.json",
16
+ "postbuild": "rimraf tsconfig.types.tsbuildinfo"
17
+ },
18
+ "license": "MIT",
19
+ "exports": {
20
+ ".": {
21
+ "import": "./dist/index.js",
22
+ "types": "./dist/index.d.ts"
23
+ },
24
+ "./scheme": {
25
+ "types": "./dist/scheme.d.ts"
26
+ }
27
+ },
28
+ "devDependencies": {
29
+ "@types/bun": "latest"
30
+ },
31
+ "peerDependencies": {
32
+ "typescript": "^5.0.0"
33
+ }
34
+ }