@zodyac/zod-mongoose 1.0.6
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 +102 -0
- package/dist/index.cjs +214 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +201 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Zod to mongoose schema converter
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/%40zodyac%2Fmongoose)
|
|
4
|
+
|
|
5
|
+
> A part of [Zodyac toolbox](https://npmjs.com/org/zodyac).
|
|
6
|
+
|
|
7
|
+
This package provides a function to convert [zod](https://www.npmjs.com/package/zod) object to [mongoose](https://www.npmjs.com/package/mongoose) schema.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm i @zodyac/mongoose
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
First, create your zod schema:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
import { zId } from '@zodyac/mongoose';
|
|
22
|
+
|
|
23
|
+
const zUser = z.object({
|
|
24
|
+
name: z.string().min(3).max(255),
|
|
25
|
+
age: z.number().min(18).max(100),
|
|
26
|
+
active: z.boolean().default(false),
|
|
27
|
+
access: z.enum(['admin', 'user']).default('user'),
|
|
28
|
+
companyId: zId.describe('ObjectId:Company'),
|
|
29
|
+
address: z.object({
|
|
30
|
+
street: z.string(),
|
|
31
|
+
city: z.string(),
|
|
32
|
+
state: z.enum(['CA', 'NY', 'TX']),
|
|
33
|
+
}),
|
|
34
|
+
tags: z.array(z.string()),
|
|
35
|
+
createdAt: z.date(),
|
|
36
|
+
updatedAt: z.date(),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then, convert it to mongoose schema and connect model:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { zodSchema } from '@zodyac/mongoose';
|
|
45
|
+
import { model } from 'mongoose';
|
|
46
|
+
|
|
47
|
+
const schema = zodSchema(zDoc);
|
|
48
|
+
const userModel = model('User', schema);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
That's it! Now you can use your mongoose model as usual:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
userModel.find({ name: 'John' });
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- ✅ Basic types
|
|
60
|
+
- ✅ Nested objects and schemas
|
|
61
|
+
- ✅ Arrays
|
|
62
|
+
- ✅ Enums (strings only)
|
|
63
|
+
- ✅ Default values
|
|
64
|
+
- ✅ Dates
|
|
65
|
+
- ✅ ObjectId
|
|
66
|
+
- ✅ ObjectId references
|
|
67
|
+
- ✅ ZodAny as SchemaTypes.Mixed
|
|
68
|
+
- ❗️ Unions (not supported by mongoose)
|
|
69
|
+
- ❗️ Intersection (not supported by mongoose)
|
|
70
|
+
- ❗️ Indexes (not supported by zod)
|
|
71
|
+
- ⏳ Number enums (comming soon)
|
|
72
|
+
- ⏳ Regex validation (comming soon)
|
|
73
|
+
- ⏳ Custom validators (comming soon)
|
|
74
|
+
- ⏳ instanceOf (comming soon)
|
|
75
|
+
- ⏳ Transform (comming soon)
|
|
76
|
+
- ⏳ Refine (comming soon)
|
|
77
|
+
|
|
78
|
+
## Checking schemas
|
|
79
|
+
|
|
80
|
+
To make sure nothing is missing, you can use ```Schema.obj```:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// schema is mongoose schema
|
|
84
|
+
console.log(schema.obj);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Raw object
|
|
88
|
+
|
|
89
|
+
If you want to get raw object from zod schema to modify it, you can use ```zodSchemaRaw``` function:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { zodSchemaRaw } from '@zodyac/mongoose';
|
|
93
|
+
import { model, Schema } from 'mongoose';
|
|
94
|
+
|
|
95
|
+
const schema = zodSchemaRaw(zDoc);
|
|
96
|
+
schema.age.validate = (v: number) => v > 18;
|
|
97
|
+
|
|
98
|
+
const model = model('User', new Schema(schema));
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
default: () => src_default,
|
|
24
|
+
zId: () => zId,
|
|
25
|
+
zodSchema: () => zodSchema,
|
|
26
|
+
zodSchemaRaw: () => zodSchemaRaw
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(src_exports);
|
|
29
|
+
var import_mongoose = require("mongoose");
|
|
30
|
+
var import_zod = require("zod");
|
|
31
|
+
function zodSchema(schema) {
|
|
32
|
+
const definition = parseObject(schema);
|
|
33
|
+
return new import_mongoose.Schema(definition);
|
|
34
|
+
}
|
|
35
|
+
function zodSchemaRaw(schema) {
|
|
36
|
+
return parseObject(schema);
|
|
37
|
+
}
|
|
38
|
+
var zId = import_zod.z.instanceof(import_mongoose.Types.ObjectId).describe("ObjectId").or(import_zod.z.string().refine((v) => (0, import_mongoose.isValidObjectId)(v), { message: "Invalid Id" }));
|
|
39
|
+
function parseObject(obj) {
|
|
40
|
+
const object = {};
|
|
41
|
+
for (const [key, field] of Object.entries(obj.shape)) {
|
|
42
|
+
if (field instanceof import_zod.ZodObject) {
|
|
43
|
+
object[key] = parseObject(field);
|
|
44
|
+
} else {
|
|
45
|
+
const f = parseField(field);
|
|
46
|
+
if (f)
|
|
47
|
+
object[key] = f;
|
|
48
|
+
else
|
|
49
|
+
console.error(
|
|
50
|
+
`Key ${key}: Unsupported field type: ${field.constructor}`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return object;
|
|
55
|
+
}
|
|
56
|
+
function parseField(field, required, def) {
|
|
57
|
+
if (field instanceof import_zod.ZodObject) {
|
|
58
|
+
return parseObject(field);
|
|
59
|
+
}
|
|
60
|
+
if (field instanceof import_zod.ZodNumber) {
|
|
61
|
+
return parseNumber(
|
|
62
|
+
field,
|
|
63
|
+
required,
|
|
64
|
+
def
|
|
65
|
+
// validate as (v: number) => boolean,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (field instanceof import_zod.ZodString) {
|
|
69
|
+
return parseString(
|
|
70
|
+
field,
|
|
71
|
+
required,
|
|
72
|
+
def
|
|
73
|
+
// validate as (v: string) => boolean,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (field instanceof import_zod.ZodEnum) {
|
|
77
|
+
return parseEnum(Object.keys(field.Values), required, def);
|
|
78
|
+
}
|
|
79
|
+
if (field instanceof import_zod.ZodBoolean) {
|
|
80
|
+
return parseBoolean(required, def);
|
|
81
|
+
}
|
|
82
|
+
if (field instanceof import_zod.ZodDate) {
|
|
83
|
+
return parseDate(required, def);
|
|
84
|
+
}
|
|
85
|
+
if (field instanceof import_zod.ZodArray) {
|
|
86
|
+
return [parseField(field.element)];
|
|
87
|
+
}
|
|
88
|
+
if (field instanceof import_zod.ZodDefault) {
|
|
89
|
+
return parseField(
|
|
90
|
+
field._def.innerType,
|
|
91
|
+
required,
|
|
92
|
+
field._def.defaultValue()
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (field instanceof import_zod.ZodOptional) {
|
|
96
|
+
return parseField(field._def.innerType, false, void 0);
|
|
97
|
+
}
|
|
98
|
+
if (field.description?.startsWith("ObjectId")) {
|
|
99
|
+
const ref = field.description.split(":")[1];
|
|
100
|
+
if (ref)
|
|
101
|
+
return parseObjectIdRef(required, ref);
|
|
102
|
+
return parseObjectId(required);
|
|
103
|
+
}
|
|
104
|
+
if (field instanceof import_zod.ZodUnion) {
|
|
105
|
+
return parseField(field._def.options[0]);
|
|
106
|
+
}
|
|
107
|
+
if (field instanceof import_zod.ZodAny) {
|
|
108
|
+
return parseMixed(required, def);
|
|
109
|
+
}
|
|
110
|
+
if (field instanceof import_zod.ZodEffects) {
|
|
111
|
+
if (field._def.effect.type === "refinement") {
|
|
112
|
+
return parseField(
|
|
113
|
+
field._def.schema,
|
|
114
|
+
required,
|
|
115
|
+
def
|
|
116
|
+
// field._def.effect.refinement as (v: T) => boolean,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
function parseNumber(field, required = true, def, validate) {
|
|
123
|
+
if (validate) {
|
|
124
|
+
return {
|
|
125
|
+
type: Number,
|
|
126
|
+
default: def,
|
|
127
|
+
min: field.minValue ?? void 0,
|
|
128
|
+
max: field.maxValue ?? void 0,
|
|
129
|
+
validation: {
|
|
130
|
+
validate
|
|
131
|
+
},
|
|
132
|
+
required
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
type: Number,
|
|
137
|
+
default: def,
|
|
138
|
+
min: field.minValue ?? void 0,
|
|
139
|
+
max: field.maxValue ?? void 0,
|
|
140
|
+
required
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function parseString(field, required = true, def, validate) {
|
|
144
|
+
if (validate) {
|
|
145
|
+
return {
|
|
146
|
+
type: String,
|
|
147
|
+
default: def,
|
|
148
|
+
required,
|
|
149
|
+
minLength: field.minLength ?? void 0,
|
|
150
|
+
maxLength: field.maxLength ?? void 0,
|
|
151
|
+
validation: {
|
|
152
|
+
validate
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
type: String,
|
|
158
|
+
default: def,
|
|
159
|
+
// TODO: match: field.regex(),
|
|
160
|
+
required,
|
|
161
|
+
minLength: field.minLength ?? void 0,
|
|
162
|
+
maxLength: field.maxLength ?? void 0
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function parseEnum(values, required = true, def) {
|
|
166
|
+
return {
|
|
167
|
+
type: String,
|
|
168
|
+
default: def,
|
|
169
|
+
enum: values,
|
|
170
|
+
required
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function parseBoolean(required = true, def) {
|
|
174
|
+
return {
|
|
175
|
+
type: Boolean,
|
|
176
|
+
default: def,
|
|
177
|
+
required
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function parseDate(required = true, def) {
|
|
181
|
+
return {
|
|
182
|
+
type: Date,
|
|
183
|
+
default: def,
|
|
184
|
+
required
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function parseObjectId(required = true) {
|
|
188
|
+
return {
|
|
189
|
+
type: import_mongoose.SchemaTypes.ObjectId,
|
|
190
|
+
required
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function parseObjectIdRef(required = true, ref) {
|
|
194
|
+
return {
|
|
195
|
+
type: import_mongoose.SchemaTypes.ObjectId,
|
|
196
|
+
ref,
|
|
197
|
+
required
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function parseMixed(required = true, def) {
|
|
201
|
+
return {
|
|
202
|
+
type: import_mongoose.SchemaTypes.Mixed,
|
|
203
|
+
default: def,
|
|
204
|
+
required
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
var src_default = zodSchema;
|
|
208
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
209
|
+
0 && (module.exports = {
|
|
210
|
+
zId,
|
|
211
|
+
zodSchema,
|
|
212
|
+
zodSchemaRaw
|
|
213
|
+
});
|
|
214
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { zm } from './mongoose.types.js';\nimport { Schema, SchemaTypes, Types, isValidObjectId } from 'mongoose';\nimport {\n ZodAny,\n ZodArray,\n ZodBoolean,\n ZodDate,\n ZodDefault,\n ZodEffects,\n ZodEnum,\n ZodNumber,\n ZodObject,\n ZodOptional,\n ZodRawShape,\n ZodString,\n ZodType,\n ZodUnion,\n z,\n} from 'zod';\n\n/**\n * Converts a Zod schema to a Mongoose schema\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { zId, zodSchema } from '@zodyac/mongoose';\n * import { model } from 'mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: zId.describe('ObjectId:Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const schema = zodSchema(zDoc);\n * const userModel = model('User', schema);\n */\nexport function zodSchema<T extends ZodRawShape>(\n schema: ZodObject<T>,\n): Schema<T> {\n const definition = parseObject(schema);\n return new Schema<T>(definition);\n}\n\n/**\n * Converts a Zod schema to a raw Mongoose schema object\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { zId, zodSchemaRaw } from '@zodyac/mongoose';\n * import { model, Schema } from 'mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: zId.describe('ObjectId:Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const rawSchema = zodSchemaRaw(zDoc);\n * const schema = new Schema(rawSchema);\n * const userModel = model('User', schema);\n */\nexport function zodSchemaRaw<T extends ZodRawShape>(\n schema: ZodObject<T>,\n): zm._Schema<T> {\n return parseObject(schema);\n}\n\n/**\n * Zod ObjectId type\n *\n * You can provide a reference to a model to enable population via zod .describe() method.\n * Description must start with 'ObjectId:' followed by the collection name.\n *\n * Can also be used for string validation for ObjectId.\n *\n * @example\n * import { zId } from '@zodyac/mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * companyId: zId.describe('ObjectId:Company'),\n * });\n */\nexport const zId = z\n .instanceof(Types.ObjectId)\n .describe('ObjectId')\n .or(z.string().refine((v) => isValidObjectId(v), { message: 'Invalid Id' }));\n\n// Helpers\nfunction parseObject<T extends ZodRawShape>(obj: ZodObject<T>): zm._Schema<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const object: any = {};\n for (const [key, field] of Object.entries(obj.shape)) {\n if (field instanceof ZodObject) {\n object[key] = parseObject(field);\n } else {\n const f = parseField(field);\n if (f) object[key] = f;\n else\n console.error(\n `Key ${key}: Unsupported field type: ${field.constructor}`,\n );\n }\n }\n return object;\n}\n\nfunction parseField<T>(\n field: ZodType<T>,\n required?: boolean,\n def?: T,\n // validate?: (v: T) => boolean,\n): zm.mField | null {\n if (field instanceof ZodObject) {\n return parseObject(field);\n }\n\n if (field instanceof ZodNumber) {\n return parseNumber(\n field,\n required,\n def as number,\n // validate as (v: number) => boolean,\n );\n }\n\n if (field instanceof ZodString) {\n return parseString(\n field,\n required,\n def as string,\n // validate as (v: string) => boolean,\n );\n }\n\n if (field instanceof ZodEnum) {\n return parseEnum(Object.keys(field.Values), required, def as string);\n }\n\n if (field instanceof ZodBoolean) {\n return parseBoolean(required, def as boolean);\n }\n\n if (field instanceof ZodDate) {\n return parseDate(required, def as Date);\n }\n\n if (field instanceof ZodArray) {\n return [parseField(field.element)];\n }\n\n if (field instanceof ZodDefault) {\n return parseField(\n field._def.innerType,\n required,\n field._def.defaultValue(),\n );\n }\n\n if (field instanceof ZodOptional) {\n return parseField(field._def.innerType, false, undefined);\n }\n\n if (field.description?.startsWith('ObjectId')) {\n const ref = field.description.split(':')[1];\n if (ref) return parseObjectIdRef(required, ref);\n return parseObjectId(required);\n }\n\n if (field instanceof ZodUnion) {\n return parseField(field._def.options[0]);\n }\n\n if (field instanceof ZodAny) {\n return parseMixed(required, def);\n }\n\n if (field instanceof ZodEffects) {\n if (field._def.effect.type === 'refinement') {\n return parseField(\n field._def.schema,\n required,\n def,\n // field._def.effect.refinement as (v: T) => boolean,\n );\n }\n }\n return null;\n}\n\nfunction parseNumber(\n field: ZodNumber,\n required: boolean = true,\n def?: number,\n validate?: (v: number) => boolean,\n): zm.mNumber {\n if (validate) {\n return {\n type: Number,\n default: def,\n min: field.minValue ?? undefined,\n max: field.maxValue ?? undefined,\n validation: {\n validate,\n },\n required,\n };\n }\n\n return {\n type: Number,\n default: def,\n min: field.minValue ?? undefined,\n max: field.maxValue ?? undefined,\n required,\n };\n}\n\nfunction parseString(\n field: ZodString,\n required: boolean = true,\n def?: string,\n validate?: ((v: string) => boolean) | undefined,\n): zm.mString {\n if (validate) {\n return {\n type: String,\n default: def,\n required,\n minLength: field.minLength ?? undefined,\n maxLength: field.maxLength ?? undefined,\n validation: {\n validate,\n },\n };\n }\n\n return {\n type: String,\n default: def,\n // TODO: match: field.regex(),\n required,\n minLength: field.minLength ?? undefined,\n maxLength: field.maxLength ?? undefined,\n };\n}\n\nfunction parseEnum(\n values: string[],\n required: boolean = true,\n def?: string,\n): zm.mString {\n return {\n type: String,\n default: def,\n enum: values,\n required,\n };\n}\n\nfunction parseBoolean(required: boolean = true, def?: boolean): zm.mBoolean {\n return {\n type: Boolean,\n default: def,\n required,\n };\n}\n\nfunction parseDate(required: boolean = true, def?: Date): zm.mDate {\n return {\n type: Date,\n default: def,\n required,\n };\n}\n\nfunction parseObjectId(required: boolean = true): zm.mObjectId {\n return {\n type: SchemaTypes.ObjectId,\n required,\n };\n}\n\nfunction parseObjectIdRef(required: boolean = true, ref: string): zm.mObjectId {\n return {\n type: SchemaTypes.ObjectId,\n ref,\n required,\n };\n}\n\nfunction parseMixed(\n required: boolean = true,\n def?: unknown,\n): zm.mMixed<unknown> {\n return {\n type: SchemaTypes.Mixed,\n default: def,\n required,\n };\n}\n\nexport { zm };\nexport default zodSchema;\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Types, SchemaTypes, Schema } from 'mongoose';
|
|
2
|
+
import { ZodRawShape, ZodObject, ZodUnion, ZodType, z, ZodEffects, ZodString } from 'zod';
|
|
3
|
+
|
|
4
|
+
declare namespace zm {
|
|
5
|
+
interface _Field<T> {
|
|
6
|
+
required: boolean;
|
|
7
|
+
default?: T;
|
|
8
|
+
validation?: {
|
|
9
|
+
validate: (v: T) => boolean;
|
|
10
|
+
message?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
interface mString extends _Field<string> {
|
|
14
|
+
type: StringConstructor;
|
|
15
|
+
enum?: string[];
|
|
16
|
+
match?: RegExp;
|
|
17
|
+
minLength?: number;
|
|
18
|
+
maxLength?: number;
|
|
19
|
+
}
|
|
20
|
+
interface mNumber extends _Field<number> {
|
|
21
|
+
type: NumberConstructor;
|
|
22
|
+
min?: number;
|
|
23
|
+
max?: number;
|
|
24
|
+
}
|
|
25
|
+
interface mBoolean extends _Field<boolean> {
|
|
26
|
+
type: BooleanConstructor;
|
|
27
|
+
}
|
|
28
|
+
interface mDate extends _Field<Date> {
|
|
29
|
+
type: DateConstructor;
|
|
30
|
+
}
|
|
31
|
+
interface mObjectId extends _Field<Types.ObjectId> {
|
|
32
|
+
type: typeof SchemaTypes.ObjectId;
|
|
33
|
+
ref?: string;
|
|
34
|
+
}
|
|
35
|
+
type mArray<K> = [_Field<K[]>];
|
|
36
|
+
interface mMixed<T> extends _Field<T> {
|
|
37
|
+
type: typeof SchemaTypes.Mixed;
|
|
38
|
+
}
|
|
39
|
+
type mField = mString | mNumber | mBoolean | mDate | mObjectId | mMixed<unknown> | mArray<unknown> | _Schema<unknown>;
|
|
40
|
+
type _Schema<T> = {
|
|
41
|
+
[K in keyof T]: _Field<T[K]> | _Schema<T[K]>;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
declare function zodSchema<T extends ZodRawShape>(schema: ZodObject<T>): Schema<T>;
|
|
46
|
+
declare function zodSchemaRaw<T extends ZodRawShape>(schema: ZodObject<T>): zm._Schema<T>;
|
|
47
|
+
declare const zId: ZodUnion<[ZodType<Types.ObjectId, z.ZodTypeDef, Types.ObjectId>, ZodEffects<ZodString, string, string>]>;
|
|
48
|
+
|
|
49
|
+
export { zodSchema as default, zId, zm, zodSchema, zodSchemaRaw };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Types, SchemaTypes, Schema } from 'mongoose';
|
|
2
|
+
import { ZodRawShape, ZodObject, ZodUnion, ZodType, z, ZodEffects, ZodString } from 'zod';
|
|
3
|
+
|
|
4
|
+
declare namespace zm {
|
|
5
|
+
interface _Field<T> {
|
|
6
|
+
required: boolean;
|
|
7
|
+
default?: T;
|
|
8
|
+
validation?: {
|
|
9
|
+
validate: (v: T) => boolean;
|
|
10
|
+
message?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
interface mString extends _Field<string> {
|
|
14
|
+
type: StringConstructor;
|
|
15
|
+
enum?: string[];
|
|
16
|
+
match?: RegExp;
|
|
17
|
+
minLength?: number;
|
|
18
|
+
maxLength?: number;
|
|
19
|
+
}
|
|
20
|
+
interface mNumber extends _Field<number> {
|
|
21
|
+
type: NumberConstructor;
|
|
22
|
+
min?: number;
|
|
23
|
+
max?: number;
|
|
24
|
+
}
|
|
25
|
+
interface mBoolean extends _Field<boolean> {
|
|
26
|
+
type: BooleanConstructor;
|
|
27
|
+
}
|
|
28
|
+
interface mDate extends _Field<Date> {
|
|
29
|
+
type: DateConstructor;
|
|
30
|
+
}
|
|
31
|
+
interface mObjectId extends _Field<Types.ObjectId> {
|
|
32
|
+
type: typeof SchemaTypes.ObjectId;
|
|
33
|
+
ref?: string;
|
|
34
|
+
}
|
|
35
|
+
type mArray<K> = [_Field<K[]>];
|
|
36
|
+
interface mMixed<T> extends _Field<T> {
|
|
37
|
+
type: typeof SchemaTypes.Mixed;
|
|
38
|
+
}
|
|
39
|
+
type mField = mString | mNumber | mBoolean | mDate | mObjectId | mMixed<unknown> | mArray<unknown> | _Schema<unknown>;
|
|
40
|
+
type _Schema<T> = {
|
|
41
|
+
[K in keyof T]: _Field<T[K]> | _Schema<T[K]>;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
declare function zodSchema<T extends ZodRawShape>(schema: ZodObject<T>): Schema<T>;
|
|
46
|
+
declare function zodSchemaRaw<T extends ZodRawShape>(schema: ZodObject<T>): zm._Schema<T>;
|
|
47
|
+
declare const zId: ZodUnion<[ZodType<Types.ObjectId, z.ZodTypeDef, Types.ObjectId>, ZodEffects<ZodString, string, string>]>;
|
|
48
|
+
|
|
49
|
+
export { zodSchema as default, zId, zm, zodSchema, zodSchemaRaw };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { Schema, SchemaTypes, Types, isValidObjectId } from "mongoose";
|
|
3
|
+
import {
|
|
4
|
+
ZodAny,
|
|
5
|
+
ZodArray,
|
|
6
|
+
ZodBoolean,
|
|
7
|
+
ZodDate,
|
|
8
|
+
ZodDefault,
|
|
9
|
+
ZodEffects,
|
|
10
|
+
ZodEnum,
|
|
11
|
+
ZodNumber,
|
|
12
|
+
ZodObject,
|
|
13
|
+
ZodOptional,
|
|
14
|
+
ZodString,
|
|
15
|
+
ZodUnion,
|
|
16
|
+
z
|
|
17
|
+
} from "zod";
|
|
18
|
+
function zodSchema(schema) {
|
|
19
|
+
const definition = parseObject(schema);
|
|
20
|
+
return new Schema(definition);
|
|
21
|
+
}
|
|
22
|
+
function zodSchemaRaw(schema) {
|
|
23
|
+
return parseObject(schema);
|
|
24
|
+
}
|
|
25
|
+
var zId = z.instanceof(Types.ObjectId).describe("ObjectId").or(z.string().refine((v) => isValidObjectId(v), { message: "Invalid Id" }));
|
|
26
|
+
function parseObject(obj) {
|
|
27
|
+
const object = {};
|
|
28
|
+
for (const [key, field] of Object.entries(obj.shape)) {
|
|
29
|
+
if (field instanceof ZodObject) {
|
|
30
|
+
object[key] = parseObject(field);
|
|
31
|
+
} else {
|
|
32
|
+
const f = parseField(field);
|
|
33
|
+
if (f)
|
|
34
|
+
object[key] = f;
|
|
35
|
+
else
|
|
36
|
+
console.error(
|
|
37
|
+
`Key ${key}: Unsupported field type: ${field.constructor}`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return object;
|
|
42
|
+
}
|
|
43
|
+
function parseField(field, required, def) {
|
|
44
|
+
if (field instanceof ZodObject) {
|
|
45
|
+
return parseObject(field);
|
|
46
|
+
}
|
|
47
|
+
if (field instanceof ZodNumber) {
|
|
48
|
+
return parseNumber(
|
|
49
|
+
field,
|
|
50
|
+
required,
|
|
51
|
+
def
|
|
52
|
+
// validate as (v: number) => boolean,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (field instanceof ZodString) {
|
|
56
|
+
return parseString(
|
|
57
|
+
field,
|
|
58
|
+
required,
|
|
59
|
+
def
|
|
60
|
+
// validate as (v: string) => boolean,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (field instanceof ZodEnum) {
|
|
64
|
+
return parseEnum(Object.keys(field.Values), required, def);
|
|
65
|
+
}
|
|
66
|
+
if (field instanceof ZodBoolean) {
|
|
67
|
+
return parseBoolean(required, def);
|
|
68
|
+
}
|
|
69
|
+
if (field instanceof ZodDate) {
|
|
70
|
+
return parseDate(required, def);
|
|
71
|
+
}
|
|
72
|
+
if (field instanceof ZodArray) {
|
|
73
|
+
return [parseField(field.element)];
|
|
74
|
+
}
|
|
75
|
+
if (field instanceof ZodDefault) {
|
|
76
|
+
return parseField(
|
|
77
|
+
field._def.innerType,
|
|
78
|
+
required,
|
|
79
|
+
field._def.defaultValue()
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (field instanceof ZodOptional) {
|
|
83
|
+
return parseField(field._def.innerType, false, void 0);
|
|
84
|
+
}
|
|
85
|
+
if (field.description?.startsWith("ObjectId")) {
|
|
86
|
+
const ref = field.description.split(":")[1];
|
|
87
|
+
if (ref)
|
|
88
|
+
return parseObjectIdRef(required, ref);
|
|
89
|
+
return parseObjectId(required);
|
|
90
|
+
}
|
|
91
|
+
if (field instanceof ZodUnion) {
|
|
92
|
+
return parseField(field._def.options[0]);
|
|
93
|
+
}
|
|
94
|
+
if (field instanceof ZodAny) {
|
|
95
|
+
return parseMixed(required, def);
|
|
96
|
+
}
|
|
97
|
+
if (field instanceof ZodEffects) {
|
|
98
|
+
if (field._def.effect.type === "refinement") {
|
|
99
|
+
return parseField(
|
|
100
|
+
field._def.schema,
|
|
101
|
+
required,
|
|
102
|
+
def
|
|
103
|
+
// field._def.effect.refinement as (v: T) => boolean,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
function parseNumber(field, required = true, def, validate) {
|
|
110
|
+
if (validate) {
|
|
111
|
+
return {
|
|
112
|
+
type: Number,
|
|
113
|
+
default: def,
|
|
114
|
+
min: field.minValue ?? void 0,
|
|
115
|
+
max: field.maxValue ?? void 0,
|
|
116
|
+
validation: {
|
|
117
|
+
validate
|
|
118
|
+
},
|
|
119
|
+
required
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
type: Number,
|
|
124
|
+
default: def,
|
|
125
|
+
min: field.minValue ?? void 0,
|
|
126
|
+
max: field.maxValue ?? void 0,
|
|
127
|
+
required
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function parseString(field, required = true, def, validate) {
|
|
131
|
+
if (validate) {
|
|
132
|
+
return {
|
|
133
|
+
type: String,
|
|
134
|
+
default: def,
|
|
135
|
+
required,
|
|
136
|
+
minLength: field.minLength ?? void 0,
|
|
137
|
+
maxLength: field.maxLength ?? void 0,
|
|
138
|
+
validation: {
|
|
139
|
+
validate
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
type: String,
|
|
145
|
+
default: def,
|
|
146
|
+
// TODO: match: field.regex(),
|
|
147
|
+
required,
|
|
148
|
+
minLength: field.minLength ?? void 0,
|
|
149
|
+
maxLength: field.maxLength ?? void 0
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function parseEnum(values, required = true, def) {
|
|
153
|
+
return {
|
|
154
|
+
type: String,
|
|
155
|
+
default: def,
|
|
156
|
+
enum: values,
|
|
157
|
+
required
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function parseBoolean(required = true, def) {
|
|
161
|
+
return {
|
|
162
|
+
type: Boolean,
|
|
163
|
+
default: def,
|
|
164
|
+
required
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function parseDate(required = true, def) {
|
|
168
|
+
return {
|
|
169
|
+
type: Date,
|
|
170
|
+
default: def,
|
|
171
|
+
required
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function parseObjectId(required = true) {
|
|
175
|
+
return {
|
|
176
|
+
type: SchemaTypes.ObjectId,
|
|
177
|
+
required
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function parseObjectIdRef(required = true, ref) {
|
|
181
|
+
return {
|
|
182
|
+
type: SchemaTypes.ObjectId,
|
|
183
|
+
ref,
|
|
184
|
+
required
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function parseMixed(required = true, def) {
|
|
188
|
+
return {
|
|
189
|
+
type: SchemaTypes.Mixed,
|
|
190
|
+
default: def,
|
|
191
|
+
required
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
var src_default = zodSchema;
|
|
195
|
+
export {
|
|
196
|
+
src_default as default,
|
|
197
|
+
zId,
|
|
198
|
+
zodSchema,
|
|
199
|
+
zodSchemaRaw
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { zm } from './mongoose.types.js';\nimport { Schema, SchemaTypes, Types, isValidObjectId } from 'mongoose';\nimport {\n ZodAny,\n ZodArray,\n ZodBoolean,\n ZodDate,\n ZodDefault,\n ZodEffects,\n ZodEnum,\n ZodNumber,\n ZodObject,\n ZodOptional,\n ZodRawShape,\n ZodString,\n ZodType,\n ZodUnion,\n z,\n} from 'zod';\n\n/**\n * Converts a Zod schema to a Mongoose schema\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { zId, zodSchema } from '@zodyac/mongoose';\n * import { model } from 'mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: zId.describe('ObjectId:Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const schema = zodSchema(zDoc);\n * const userModel = model('User', schema);\n */\nexport function zodSchema<T extends ZodRawShape>(\n schema: ZodObject<T>,\n): Schema<T> {\n const definition = parseObject(schema);\n return new Schema<T>(definition);\n}\n\n/**\n * Converts a Zod schema to a raw Mongoose schema object\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { zId, zodSchemaRaw } from '@zodyac/mongoose';\n * import { model, Schema } from 'mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: zId.describe('ObjectId:Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const rawSchema = zodSchemaRaw(zDoc);\n * const schema = new Schema(rawSchema);\n * const userModel = model('User', schema);\n */\nexport function zodSchemaRaw<T extends ZodRawShape>(\n schema: ZodObject<T>,\n): zm._Schema<T> {\n return parseObject(schema);\n}\n\n/**\n * Zod ObjectId type\n *\n * You can provide a reference to a model to enable population via zod .describe() method.\n * Description must start with 'ObjectId:' followed by the collection name.\n *\n * Can also be used for string validation for ObjectId.\n *\n * @example\n * import { zId } from '@zodyac/mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * companyId: zId.describe('ObjectId:Company'),\n * });\n */\nexport const zId = z\n .instanceof(Types.ObjectId)\n .describe('ObjectId')\n .or(z.string().refine((v) => isValidObjectId(v), { message: 'Invalid Id' }));\n\n// Helpers\nfunction parseObject<T extends ZodRawShape>(obj: ZodObject<T>): zm._Schema<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const object: any = {};\n for (const [key, field] of Object.entries(obj.shape)) {\n if (field instanceof ZodObject) {\n object[key] = parseObject(field);\n } else {\n const f = parseField(field);\n if (f) object[key] = f;\n else\n console.error(\n `Key ${key}: Unsupported field type: ${field.constructor}`,\n );\n }\n }\n return object;\n}\n\nfunction parseField<T>(\n field: ZodType<T>,\n required?: boolean,\n def?: T,\n // validate?: (v: T) => boolean,\n): zm.mField | null {\n if (field instanceof ZodObject) {\n return parseObject(field);\n }\n\n if (field instanceof ZodNumber) {\n return parseNumber(\n field,\n required,\n def as number,\n // validate as (v: number) => boolean,\n );\n }\n\n if (field instanceof ZodString) {\n return parseString(\n field,\n required,\n def as string,\n // validate as (v: string) => boolean,\n );\n }\n\n if (field instanceof ZodEnum) {\n return parseEnum(Object.keys(field.Values), required, def as string);\n }\n\n if (field instanceof ZodBoolean) {\n return parseBoolean(required, def as boolean);\n }\n\n if (field instanceof ZodDate) {\n return parseDate(required, def as Date);\n }\n\n if (field instanceof ZodArray) {\n return [parseField(field.element)];\n }\n\n if (field instanceof ZodDefault) {\n return parseField(\n field._def.innerType,\n required,\n field._def.defaultValue(),\n );\n }\n\n if (field instanceof ZodOptional) {\n return parseField(field._def.innerType, false, undefined);\n }\n\n if (field.description?.startsWith('ObjectId')) {\n const ref = field.description.split(':')[1];\n if (ref) return parseObjectIdRef(required, ref);\n return parseObjectId(required);\n }\n\n if (field instanceof ZodUnion) {\n return parseField(field._def.options[0]);\n }\n\n if (field instanceof ZodAny) {\n return parseMixed(required, def);\n }\n\n if (field instanceof ZodEffects) {\n if (field._def.effect.type === 'refinement') {\n return parseField(\n field._def.schema,\n required,\n def,\n // field._def.effect.refinement as (v: T) => boolean,\n );\n }\n }\n return null;\n}\n\nfunction parseNumber(\n field: ZodNumber,\n required: boolean = true,\n def?: number,\n validate?: (v: number) => boolean,\n): zm.mNumber {\n if (validate) {\n return {\n type: Number,\n default: def,\n min: field.minValue ?? undefined,\n max: field.maxValue ?? undefined,\n validation: {\n validate,\n },\n required,\n };\n }\n\n return {\n type: Number,\n default: def,\n min: field.minValue ?? undefined,\n max: field.maxValue ?? undefined,\n required,\n };\n}\n\nfunction parseString(\n field: ZodString,\n required: boolean = true,\n def?: string,\n validate?: ((v: string) => boolean) | undefined,\n): zm.mString {\n if (validate) {\n return {\n type: String,\n default: def,\n required,\n minLength: field.minLength ?? undefined,\n maxLength: field.maxLength ?? undefined,\n validation: {\n validate,\n },\n };\n }\n\n return {\n type: String,\n default: def,\n // TODO: match: field.regex(),\n required,\n minLength: field.minLength ?? undefined,\n maxLength: field.maxLength ?? undefined,\n };\n}\n\nfunction parseEnum(\n values: string[],\n required: boolean = true,\n def?: string,\n): zm.mString {\n return {\n type: String,\n default: def,\n enum: values,\n required,\n };\n}\n\nfunction parseBoolean(required: boolean = true, def?: boolean): zm.mBoolean {\n return {\n type: Boolean,\n default: def,\n required,\n };\n}\n\nfunction parseDate(required: boolean = true, def?: Date): zm.mDate {\n return {\n type: Date,\n default: def,\n required,\n };\n}\n\nfunction parseObjectId(required: boolean = true): zm.mObjectId {\n return {\n type: SchemaTypes.ObjectId,\n required,\n };\n}\n\nfunction parseObjectIdRef(required: boolean = true, ref: string): zm.mObjectId {\n return {\n type: SchemaTypes.ObjectId,\n ref,\n required,\n };\n}\n\nfunction parseMixed(\n required: boolean = true,\n def?: unknown,\n): zm.mMixed<unknown> {\n return {\n type: SchemaTypes.Mixed,\n default: def,\n required,\n };\n}\n\nexport { zm };\nexport default zodSchema;\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zodyac/zod-mongoose",
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "A library that allows you to generate mongoose schemas from zod objects.",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsup",
|
|
7
|
+
"test": "ts-node --esm ./src/test/test.ts"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"module": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"private": false,
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"zod",
|
|
19
|
+
"mongoose",
|
|
20
|
+
"schema",
|
|
21
|
+
"validation",
|
|
22
|
+
"typescript",
|
|
23
|
+
"type",
|
|
24
|
+
"types",
|
|
25
|
+
"type-safe",
|
|
26
|
+
"validation",
|
|
27
|
+
"mongodb",
|
|
28
|
+
"mongo",
|
|
29
|
+
"database",
|
|
30
|
+
"db",
|
|
31
|
+
"orm",
|
|
32
|
+
"odm",
|
|
33
|
+
"document"
|
|
34
|
+
],
|
|
35
|
+
"author": "bebrasmell",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"homepage": "https://zodyac.dev/toolbox/zod-mongoose",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/git-zodyac/mongoose"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
|
44
|
+
"@typescript-eslint/parser": "^6.15.0",
|
|
45
|
+
"eslint": "^8.56.0",
|
|
46
|
+
"eslint-plugin-prettier": "^5.1.0",
|
|
47
|
+
"prettier": "^3.1.1",
|
|
48
|
+
"tsup": "^8.0.1"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"mongoose": "^8.0.3",
|
|
52
|
+
"zod": "^3.22.4"
|
|
53
|
+
}
|
|
54
|
+
}
|