@quentinadam/zod 0.1.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/README.md +24 -0
- package/dist/zod.d.ts +57 -0
- package/dist/zod.js +252 -0
- package/package.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# @quentinadam/zod
|
|
2
|
+
|
|
3
|
+
[![JSR][jsr-image]][jsr-url] [![NPM][npm-image]][npm-url] [![CI][ci-image]][ci-url]
|
|
4
|
+
|
|
5
|
+
A simple library to parse data, inspired by [https://zod.dev/](zod).
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import * as z from '@quentinadam/zod';
|
|
11
|
+
|
|
12
|
+
const data: unknown = { age: 30, name: 'John', email: 'john@example.com' };
|
|
13
|
+
|
|
14
|
+
const schema: z.Schema<{ age: number; name: string }> = z.object({ age: z.number(), name: z.string() });
|
|
15
|
+
|
|
16
|
+
const parsed: { age: number; name: string } = schema.parse(data);
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
[ci-image]: https://img.shields.io/github/actions/workflow/status/quentinadam/deno-zod/ci.yml?branch=main&logo=github&style=flat-square
|
|
20
|
+
[ci-url]: https://github.com/quentinadam/deno-zod/actions/workflows/ci.yml
|
|
21
|
+
[npm-image]: https://img.shields.io/npm/v/@quentinadam/zod.svg?style=flat-square
|
|
22
|
+
[npm-url]: https://npmjs.org/package/@quentinadam/zod
|
|
23
|
+
[jsr-image]: https://jsr.io/badges/@quentinadam/zod?style=flat-square
|
|
24
|
+
[jsr-url]: https://jsr.io/@quentinadam/zod
|
package/dist/zod.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export declare class Schema<T> {
|
|
2
|
+
#private;
|
|
3
|
+
readonly inputType: string;
|
|
4
|
+
constructor({ inputType, parseFn }: {
|
|
5
|
+
inputType: string;
|
|
6
|
+
parseFn: (value: unknown) => T;
|
|
7
|
+
});
|
|
8
|
+
parse(value: unknown): T;
|
|
9
|
+
safeParse(value: unknown): {
|
|
10
|
+
success: true;
|
|
11
|
+
data: T;
|
|
12
|
+
} | {
|
|
13
|
+
success: false;
|
|
14
|
+
error: unknown;
|
|
15
|
+
};
|
|
16
|
+
transform<U>(transform: (value: T) => U): Schema<U>;
|
|
17
|
+
optional(): Schema<T | undefined>;
|
|
18
|
+
nullable(): Schema<T | null>;
|
|
19
|
+
}
|
|
20
|
+
export declare class ObjectSchema<T extends Record<string, unknown>> extends Schema<T> {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(schema: {
|
|
23
|
+
[K in keyof T]: Schema<T[K]>;
|
|
24
|
+
}, strict?: boolean);
|
|
25
|
+
extend<U extends Record<string, unknown>>(newSchema: {
|
|
26
|
+
[K in keyof U]: Schema<U[K]>;
|
|
27
|
+
}): ObjectSchema<T & U>;
|
|
28
|
+
strict(): ObjectSchema<T>;
|
|
29
|
+
strip(): ObjectSchema<T>;
|
|
30
|
+
partial(): ObjectSchema<{
|
|
31
|
+
[K in keyof T]: T[K] | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
declare function createStringSchema(): Schema<string>;
|
|
35
|
+
declare function createNumberSchema(): Schema<number>;
|
|
36
|
+
declare function createBigIntSchema(): Schema<bigint>;
|
|
37
|
+
declare function createUnknownSchema(): Schema<unknown>;
|
|
38
|
+
declare function createBooleanSchema(): Schema<boolean>;
|
|
39
|
+
declare function createNullSchema(): Schema<null>;
|
|
40
|
+
declare function createUndefinedSchema(): Schema<undefined>;
|
|
41
|
+
declare function createDateSchema(): Schema<Date>;
|
|
42
|
+
declare function createTupleSchema<T extends unknown[]>(schema: {
|
|
43
|
+
[K in keyof T]: Schema<T[K]>;
|
|
44
|
+
}): Schema<T>;
|
|
45
|
+
declare function createObjectSchema<T extends Record<string, unknown>>(schema: {
|
|
46
|
+
[K in keyof T]: Schema<T[K]>;
|
|
47
|
+
}): ObjectSchema<T>;
|
|
48
|
+
declare function createInstanceofSchema<T>(schema: {
|
|
49
|
+
new (...args: unknown[]): T;
|
|
50
|
+
}): Schema<T>;
|
|
51
|
+
declare function createArraySchema<T>(schema: Schema<T>): Schema<T[]>;
|
|
52
|
+
declare function createRecordSchema<T>(schema: Schema<T>): Schema<Record<string, T>>;
|
|
53
|
+
declare function createUnionSchema<T extends unknown[]>(schemas: {
|
|
54
|
+
[K in keyof T]: Schema<T[K]>;
|
|
55
|
+
}): Schema<T[number]>;
|
|
56
|
+
declare function createLiteralSchema<T extends string | number | boolean | null>(value: T): Schema<T>;
|
|
57
|
+
export { createArraySchema as array, createBigIntSchema as bigint, createBooleanSchema as boolean, createDateSchema as date, createInstanceofSchema as instanceof, createLiteralSchema as literal, createNullSchema as null, createNumberSchema as number, createObjectSchema as object, createRecordSchema as record, createStringSchema as string, createTupleSchema as tuple, createUndefinedSchema as undefined, createUnionSchema as union, createUnknownSchema as unknown, };
|
package/dist/zod.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
export class Schema {
|
|
2
|
+
#parseFn;
|
|
3
|
+
inputType;
|
|
4
|
+
constructor({ inputType, parseFn }) {
|
|
5
|
+
this.#parseFn = parseFn;
|
|
6
|
+
this.inputType = inputType;
|
|
7
|
+
}
|
|
8
|
+
parse(value) {
|
|
9
|
+
return this.#parseFn(value);
|
|
10
|
+
}
|
|
11
|
+
safeParse(value) {
|
|
12
|
+
try {
|
|
13
|
+
return { success: true, data: this.parse(value) };
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return { success: false, error };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
transform(transform) {
|
|
20
|
+
return new Schema({ inputType: this.inputType, parseFn: (value) => transform(this.parse(value)) });
|
|
21
|
+
}
|
|
22
|
+
optional() {
|
|
23
|
+
return new Schema({
|
|
24
|
+
inputType: `${this.inputType} | undefined`,
|
|
25
|
+
parseFn: (value) => value === undefined ? undefined : this.parse(value),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
nullable() {
|
|
29
|
+
return new Schema({
|
|
30
|
+
inputType: `${this.inputType} | null`,
|
|
31
|
+
parseFn: (value) => value === null ? null : this.parse(value),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class ObjectSchema extends Schema {
|
|
36
|
+
#schema;
|
|
37
|
+
#strict;
|
|
38
|
+
constructor(schema, strict = false) {
|
|
39
|
+
const inputType = `{ ${Object.entries(schema).map(([key, schema]) => `"${key}": ${schema.inputType}`).join(', ')} }`;
|
|
40
|
+
super({
|
|
41
|
+
inputType,
|
|
42
|
+
parseFn: (value) => {
|
|
43
|
+
if (typeof value !== 'object' || value === null) {
|
|
44
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
45
|
+
}
|
|
46
|
+
return ((value) => {
|
|
47
|
+
if (strict) {
|
|
48
|
+
for (const key of Object.keys(value)) {
|
|
49
|
+
if (!(key in schema)) {
|
|
50
|
+
throw new Error(`Expected strict ${this.inputType}, got ${JSON.stringify(value)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const result = {};
|
|
55
|
+
Object.entries(schema).forEach(([key, schema]) => {
|
|
56
|
+
result[key] = schema.parse(value[key]);
|
|
57
|
+
});
|
|
58
|
+
return result;
|
|
59
|
+
})(value);
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
this.#schema = schema;
|
|
63
|
+
this.#strict = strict;
|
|
64
|
+
}
|
|
65
|
+
extend(newSchema) {
|
|
66
|
+
return new ObjectSchema({ ...this.#schema, ...newSchema }, this.#strict);
|
|
67
|
+
}
|
|
68
|
+
strict() {
|
|
69
|
+
return new ObjectSchema(this.#schema, true);
|
|
70
|
+
}
|
|
71
|
+
strip() {
|
|
72
|
+
return new ObjectSchema(this.#schema, false);
|
|
73
|
+
}
|
|
74
|
+
partial() {
|
|
75
|
+
const schema = Object.fromEntries(Object.entries(this.#schema).map(([key, schema]) => [key, schema.optional()]));
|
|
76
|
+
return new ObjectSchema(schema, this.#strict);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function createStringSchema() {
|
|
80
|
+
const inputType = 'string';
|
|
81
|
+
return new Schema({
|
|
82
|
+
inputType,
|
|
83
|
+
parseFn: (value) => {
|
|
84
|
+
if (typeof value !== 'string') {
|
|
85
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function createNumberSchema() {
|
|
92
|
+
const inputType = 'number';
|
|
93
|
+
return new Schema({
|
|
94
|
+
inputType,
|
|
95
|
+
parseFn: (value) => {
|
|
96
|
+
if (typeof value !== 'number') {
|
|
97
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function createBigIntSchema() {
|
|
104
|
+
const inputType = 'bigint';
|
|
105
|
+
return new Schema({
|
|
106
|
+
inputType,
|
|
107
|
+
parseFn: (value) => {
|
|
108
|
+
if (typeof value !== 'bigint') {
|
|
109
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
110
|
+
}
|
|
111
|
+
return value;
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function createUnknownSchema() {
|
|
116
|
+
const inputType = 'unknown';
|
|
117
|
+
return new Schema({
|
|
118
|
+
inputType,
|
|
119
|
+
parseFn: (value) => {
|
|
120
|
+
return value;
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function createBooleanSchema() {
|
|
125
|
+
const inputType = 'boolean';
|
|
126
|
+
return new Schema({
|
|
127
|
+
inputType,
|
|
128
|
+
parseFn: (value) => {
|
|
129
|
+
if (typeof value !== 'boolean') {
|
|
130
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
131
|
+
}
|
|
132
|
+
return value;
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function createNullSchema() {
|
|
137
|
+
const inputType = 'null';
|
|
138
|
+
return new Schema({
|
|
139
|
+
inputType,
|
|
140
|
+
parseFn: (value) => {
|
|
141
|
+
if (value !== null) {
|
|
142
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
143
|
+
}
|
|
144
|
+
return value;
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function createUndefinedSchema() {
|
|
149
|
+
const inputType = 'undefined';
|
|
150
|
+
return new Schema({
|
|
151
|
+
inputType,
|
|
152
|
+
parseFn: (value) => {
|
|
153
|
+
if (value !== undefined) {
|
|
154
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
155
|
+
}
|
|
156
|
+
return value;
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function createDateSchema() {
|
|
161
|
+
const inputType = 'Date';
|
|
162
|
+
return new Schema({
|
|
163
|
+
inputType,
|
|
164
|
+
parseFn: (value) => {
|
|
165
|
+
if (!(value instanceof Date)) {
|
|
166
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
167
|
+
}
|
|
168
|
+
return value;
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function createTupleSchema(schema) {
|
|
173
|
+
const inputType = `[ ${schema.map((schema) => schema.inputType).join(', ')} ]`;
|
|
174
|
+
return new Schema({
|
|
175
|
+
inputType,
|
|
176
|
+
parseFn: (value) => {
|
|
177
|
+
if (!Array.isArray(value) || value.length !== schema.length) {
|
|
178
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
179
|
+
}
|
|
180
|
+
return schema.map((schema, index) => schema.parse(value[index]));
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function createObjectSchema(schema) {
|
|
185
|
+
return new ObjectSchema(schema);
|
|
186
|
+
}
|
|
187
|
+
function createInstanceofSchema(schema) {
|
|
188
|
+
const inputType = schema.name;
|
|
189
|
+
return new Schema({
|
|
190
|
+
inputType,
|
|
191
|
+
parseFn: (value) => {
|
|
192
|
+
if (!(value instanceof schema)) {
|
|
193
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
194
|
+
}
|
|
195
|
+
return value;
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function createArraySchema(schema) {
|
|
200
|
+
const inputType = `Array<${schema.inputType}>`;
|
|
201
|
+
return new Schema({
|
|
202
|
+
inputType,
|
|
203
|
+
parseFn: (value) => {
|
|
204
|
+
if (!Array.isArray(value)) {
|
|
205
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
206
|
+
}
|
|
207
|
+
return value.map((item) => schema.parse(item));
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
function createRecordSchema(schema) {
|
|
212
|
+
const inputType = `Record<string, ${schema.inputType}>`;
|
|
213
|
+
return new Schema({
|
|
214
|
+
inputType,
|
|
215
|
+
parseFn: (value) => {
|
|
216
|
+
if (typeof value !== 'object' || value === null) {
|
|
217
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
218
|
+
}
|
|
219
|
+
return Object.fromEntries(Object.entries(value).map(([key, value]) => [key, schema.parse(value)]));
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
function createUnionSchema(schemas) {
|
|
224
|
+
const inputType = schemas.map((schema) => schema.inputType).join(' | ');
|
|
225
|
+
return new Schema({
|
|
226
|
+
inputType,
|
|
227
|
+
parseFn: (value) => {
|
|
228
|
+
for (const schema of schemas) {
|
|
229
|
+
try {
|
|
230
|
+
return schema.parse(value);
|
|
231
|
+
}
|
|
232
|
+
catch (_) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
throw new Error(`Expected ${inputType}, got ${JSON.stringify(value)}`);
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
function createLiteralSchema(value) {
|
|
241
|
+
const inputType = JSON.stringify(value);
|
|
242
|
+
return new Schema({
|
|
243
|
+
inputType,
|
|
244
|
+
parseFn: (input) => {
|
|
245
|
+
if (input !== value) {
|
|
246
|
+
throw new Error(`Expected ${inputType}, got ${input}`);
|
|
247
|
+
}
|
|
248
|
+
return value;
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
export { createArraySchema as array, createBigIntSchema as bigint, createBooleanSchema as boolean, createDateSchema as date, createInstanceofSchema as instanceof, createLiteralSchema as literal, createNullSchema as null, createNumberSchema as number, createObjectSchema as object, createRecordSchema as record, createStringSchema as string, createTupleSchema as tuple, createUndefinedSchema as undefined, createUnionSchema as union, createUnknownSchema as unknown, };
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quentinadam/zod",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A simple library to parse data, inspired by zod",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Quentin Adam",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/quentinadam/deno-zod.git"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": "./dist/zod.js",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md"
|
|
16
|
+
]
|
|
17
|
+
}
|