Skip to content

Commit

Permalink
feat: add zod to mongodb schema
Browse files Browse the repository at this point in the history
  • Loading branch information
moroine committed Nov 13, 2023
1 parent 3fc63c0 commit 4de2798
Show file tree
Hide file tree
Showing 5 changed files with 1,103 additions and 60 deletions.
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@
"build": "tsup-node --env.NODE_ENV production",
"typecheck": "tsc --noEmit"
},
"peerDependencies": {
"mongodb": "^6.2.0",
"zod": "^3.22.4"
},
"dependencies": {
"json-schema": "^0.4.0",
"zod-to-json-schema": "^3.21.4"
},
"devDependencies": {
"@commitlint/cli": "^18.4.0",
"@commitlint/config-conventional": "^18.4.0",
Expand All @@ -42,12 +50,14 @@
"eslint-plugin-zod": "^1.4.0",
"husky": "^8.0.3",
"lint-staged": "^15.0.2",
"mongodb": "^6.2.0",
"prettier": "^3.0.3",
"semantic-release": "^22.0.7",
"semantic-release-slack-bot": "^4.0.2",
"tsup": "^7.2.0",
"typescript": "^5.2.2",
"vitest": "^0.34.6"
"vitest": "^0.34.6",
"zod": "^3.22.4"
},
"lint-staged": {
"*.{js,ts}": [
Expand Down
64 changes: 64 additions & 0 deletions src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`zodToMongoSchema > should convert zod object properly 1`] = `
{
"additionalProperties": false,
"bsonType": "object",
"properties": {
"_id": {
"bsonType": "objectId",
},
"enum": {
"bsonType": "string",
"enum": [
"a",
"b",
],
},
"nullishNumber": {
"bsonType": [
"number",
"null",
],
},
"number": {
"bsonType": "number",
},
"optionalString": {
"bsonType": "string",
},
"string": {
"bsonType": "string",
},
},
"required": [
"_id",
"string",
"number",
"enum",
],
}
`;

exports[`zodToMongoSchema > should resolves zod ref properly 1`] = `
{
"additionalProperties": false,
"bsonType": "object",
"properties": {
"_id": {
"bsonType": "objectId",
},
"a": {
"bsonType": "string",
},
"b": {
"bsonType": "string",
},
},
"required": [
"_id",
"a",
"b",
],
}
`;
200 changes: 196 additions & 4 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,200 @@
import { JSONSchema7 } from "json-schema";
import { describe, expect, it } from "vitest";
import { helloWorld } from "./index.ts";

describe("helloWorld", () => {
it("should display hello world", () => {
expect(helloWorld("Antoine")).toBe("Hello Antoine");
import {
jsonSchemaToMongoSchema,
zodToMongoSchema,
zObjectId,
} from "./index.ts";
import { z } from "zod";

describe("jsonSchemaToMongoSchema", () => {
it("should convert complex schema", () => {
const input: JSONSchema7 = {
type: "object",
properties: {
_id: {
$ref: "#/definitions/objectId",
},
type_document: {
type: "string",
description: "Le type de document (exemple: DECA, etc..)",
},
ext_fichier: {
type: "string",
description: "Le type de fichier extension",
enum: ["xlsx", "xls", "csv"], // 10mb
},
nom_fichier: {
type: "string",
description: "Le nom de fichier",
},
chemin_fichier: {
type: "string",
description: "Chemin du fichier binaire",
},
taille_fichier: {
type: "integer",
description: "Taille du fichier en bytes",
},
hash_secret: {
type: "string",
description: "Hash fichier",
},
hash_fichier: {
type: "string",
description: "Checksum fichier",
},
import_progress: {
type: "number",
description: "Progress percentage (-1 not started)",
},
lines_count: {
type: "integer",
description: "Number of lines",
},
added_by: {
type: "string",
description: "Qui a ajouté le fichier",
},
updated_at: {
type: "string",
format: "date-time",
description: "Date de mise à jour en base de données",
},
created_at: {
type: "string",
format: "date-time",
description: "Date d'ajout en base de données",
},
_meta: {
type: "object",
additionalProperties: {},
},
},
required: [
"_id",
"type_document",
"ext_fichier",
"nom_fichier",
"chemin_fichier",
"taille_fichier",
"hash_secret",
"hash_fichier",
"added_by",
"created_at",
],
additionalProperties: false,
};

expect(jsonSchemaToMongoSchema(input, input)).toEqual({
bsonType: "object",
properties: {
_id: {
bsonType: "objectId",
},
type_document: {
bsonType: "string",
description: "Le type de document (exemple: DECA, etc..)",
},
ext_fichier: {
bsonType: "string",
description: "Le type de fichier extension",
enum: ["xlsx", "xls", "csv"], // 10mb
},
nom_fichier: {
bsonType: "string",
description: "Le nom de fichier",
},
chemin_fichier: {
bsonType: "string",
description: "Chemin du fichier binaire",
},
taille_fichier: {
bsonType: "int",
description: "Taille du fichier en bytes",
},
hash_secret: {
bsonType: "string",
description: "Hash fichier",
},
hash_fichier: {
bsonType: "string",
description: "Checksum fichier",
},
import_progress: {
bsonType: "number",
description: "Progress percentage (-1 not started)",
},
lines_count: {
bsonType: "int",
description: "Number of lines",
},
added_by: {
bsonType: "string",
description: "Qui a ajouté le fichier",
},
updated_at: {
bsonType: "date",
description: "Date de mise à jour en base de données",
},
created_at: {
bsonType: "date",
description: "Date d'ajout en base de données",
},
_meta: {
bsonType: "object",
additionalProperties: true,
},
},
required: [
"_id",
"type_document",
"ext_fichier",
"nom_fichier",
"chemin_fichier",
"taille_fichier",
"hash_secret",
"hash_fichier",
"added_by",
"created_at",
],
additionalProperties: false,
});
});
});

describe("zodToMongoSchema", () => {
it("should convert zod object properly", () => {
expect(
zodToMongoSchema(
z
.object({
_id: zObjectId,
string: z.string(),
number: z.number(),
enum: z.enum(["a", "b"]),
optionalString: z.string().optional(),
nullishNumber: z.number().nullish(),
})
.strict(),
),
).toMatchSnapshot();
});

it("should resolves zod ref properly", () => {
const zEmail = z.string().email();

expect(
zodToMongoSchema(
z
.object({
_id: zObjectId,
a: zEmail,
b: zEmail,
})
.strict(),
),
).toMatchSnapshot();
});
});
Loading

0 comments on commit 4de2798

Please sign in to comment.