update naming and publish info

This commit is contained in:
2024-01-29 10:44:25 -06:00
parent 8135722458
commit 0d22f46118
5 changed files with 114 additions and 25 deletions

View File

@@ -1,8 +1,8 @@
# Mongo Assert
# Mongo Validate
Stronger, more intuitive type checking and assertions for MongoDB.
Mongo Assert extends the functionality of Zod, integrated with the MongoDB Node.js driver, to provide a more intuitive and powerful way to validate and assert MongoDB documents.
Mongo Validate extends the functionality of Zod, integrated with the MongoDB Node.js driver, to provide a more intuitive and powerful way to validate MongoDB documents.
Some of its features include:
@@ -12,20 +12,20 @@ Some of its features include:
## But why?
Mongo Assert is something I put together out of frustration with existing, heavy handed solutions for MongoDB schema management. Mongo Assert is intended to have a minimal footprint, add on to existing validation infrastructure, and plug in seamlessly to build-time integrity checks.
Mongo Validate is something I put together out of frustration with existing, heavy handed solutions for MongoDB schema management. Mongo Validate is intended to have a minimal footprint, add on to existing validation infrastructure, and plug in seamlessly to build-time integrity checks.
## Usage
Mongo Assert is available as an NPM package. To install it, run:
Mongo Validate is available as an NPM package. To install it, run:
```bash
npm install mongo-assert
pnpm install mongo-assert
yarn add mongo-assert
bun install mongo-assert
npm install mongo-validate
pnpm install mongo-validate
yarn add mongo-validate
bun install mongo-validate
```
Mongo Assert supports Zod schemas out of the box, so any schemas you may already have defined can be used
Mongo Validate supports Zod schemas out of the box, so any schemas you may already have defined can be used
with any MongoDB instance.
## Examples
@@ -36,7 +36,7 @@ For all of the examples below, we'll be using the following schema:
```ts
import { z } from 'zod';
import { ObjectId } from "mongo-assert/lib/mongodb"
import { ObjectId } from "mongo-validate/lib/mongodb"
export const userSchema = z.object({
_id: ObjectId,
@@ -49,13 +49,14 @@ export type User = z.infer<typeof userSchema>;
### Unique field validation
Mongo Assert extends Zod schemas to check that your documents match the desired schema. For example:
Mongo Validate extends Zod schemas to check that your documents match the desired schema. For example:
```ts
import MongoAssert, { type AssertUniqueType } from 'mongo-assert';
import mongo-validate, { type AssertUniqueType } from 'mongo-validate';
import { userSchema, type User } from "./schemas";
export const UserEmailsUniqueValidator: AssertUniqueType<User> = MongoAssert.unique.fromSchema(userSchema, ["email"]);
export const UserEmailsUniqueValidator = MongoValidate.assertUnique.fromSchema(userSchema, ["email"]);
// ^? AssertUniqueType<User>
```
The returned object is a Zod schema that can be directly invoked to validate a result from MongoDB. This object
@@ -87,7 +88,7 @@ async function main() {
### Reference validation
Mongo Assert also supports validation of references to other collections.
Mongo Validate also supports validation of references to other collections.
For example, suppose we have a collection of `Store`s that must be associated to an existing `User`. Let's define our schema first:
@@ -107,9 +108,9 @@ export type Store = z.infer<typeof storeSchema>;
Now, we can define a reference validator between these two collections:
```ts
import MongoAssert from 'mongo-assert';
import mongo-validate from 'mongo-validate';
const StoresHaveOwnersValidator = new MongoAssert.relation({
const StoresHaveOwnersValidator = new MongoValidate.assertRelation({
db: "your-db",
mainCollection: "users",
relationCollection: "stores",

View File

@@ -1,5 +1,5 @@
import { z } from 'zod';
import MongoAssert from '..';
import MongoValidator from '..';
import dotenv from 'dotenv';
import path from 'path';
import { createMongoClient, ObjectId } from '../pkg/lib/mongodb';
@@ -52,10 +52,10 @@ async function main() {
type AssertUniqueType<T extends Record<string, unknown>> = z.ZodEffects<z.ZodArray<z.ZodType<T>>, T[], unknown>;
// validate against internal schema
const MusicEntryValidator = MongoAssert.unique.fromSchema(MusicEntry, ["slug"]) satisfies AssertUniqueType<MusicEntryType>;
const MusicCollections = MongoAssert.unique.fromSchema(MusicCollection, ["collectionslug"]);
const MusicEntryValidator = MongoValidator.unique.fromSchema(MusicEntry, ["slug"]) satisfies AssertUniqueType<MusicEntryType>;
const MusicCollections = MongoValidator.unique.fromSchema(MusicCollection, ["collectionslug"]);
const result: Promise<number | undefined> = MongoAssert.relation.check({
const result: Promise<number | undefined> = MongoValidator.relation.check({
db: "mikayladotdev",
mainCollection: "music",
relationCollection: "music-collection",

View File

@@ -1,5 +1,5 @@
{
"name": "mongo-assert",
"name": "mongo-validate",
"version": "0.0.1",
"description": "Lightweight schema validation for MongoDB with Zod",
"author": "Mikayla Dobson",

88
pkg/examples/main.ts Normal file
View File

@@ -0,0 +1,88 @@
import { z } from 'zod';
import MongoAssert from '..';
import dotenv from 'dotenv';
import path from 'path';
import { createMongoClient, ObjectId } from '../lib/mongodb';
dotenv.config();
const MusicEntry = z.object({
_id: ObjectId,
name: z.string(),
shortdescription: z.string(),
longdescription: z.string().optional(),
artist: z.string().optional(),
compositiondate: z.string().optional(),
pathtoentry: z.string(),
collection: z.string(),
slug: z.string(),
})
const MusicCollection = z.object({
_id: ObjectId,
name: z.string(),
description: z.string().optional(),
collectionslug: z.string(),
})
type MusicEntryType = z.infer<typeof MusicEntry>;
type MusicCollectionType = z.infer<typeof MusicCollection>;
async function main() {
try {
const url = process.env.MONGO_URL;
const cert = process.env.MONGO_CERT;
if (!url || !cert) {
throw new Error('Missing environment variables');
}
const client = await createMongoClient(url, {
tlsCertificateKeyFile: path.resolve(__dirname, '..', cert)
});
if (!client) return null;
const mdotdev = client.db('mikayladotdev');
const music = mdotdev.collection('music');
const musicData = await music.find().toArray();
const collectionData = await mdotdev.collection('music-collection').find().toArray();
type AssertUniqueType<T extends Record<string, unknown>> = z.ZodEffects<z.ZodArray<z.ZodType<T>>, T[], unknown>;
// validate against internal schema
const MusicEntryValidator = MongoAssert.assertUnique.fromSchema(MusicEntry, ["slug"]) satisfies AssertUniqueType<MusicEntryType>;
const MusicCollections = MongoAssert.assertUnique.fromSchema(MusicCollection, ["collectionslug"]);
const result: Promise<number | undefined> = MongoAssert.assertRelation.check({
db: "mikayladotdev",
mainCollection: "music",
relationCollection: "music-collection",
mainSchema: MusicEntry,
relationSchema: MusicCollection,
relations: {
"collection": "collectionslug"
}
});
await Promise.allSettled([
MusicEntryValidator.parseAsync(musicData) satisfies Promise<MusicEntryType[]>,
MusicCollections.parseAsync(collectionData) satisfies Promise<MusicCollectionType[]>,
result
]).then((results) => {
results.forEach((result) => {
if (result.status === 'rejected') {
console.log(result.reason);
}
})
})
.catch(console.error)
.finally(() => client.close());
} catch(e) {
console.log(e);
}
}
main().catch(console.error);

View File

@@ -5,8 +5,8 @@ import { AssertConstrained } from './actions/constrained';
export type { AssertUniqueType } from "./actions/unique";
export type { AssertRelationType } from "./actions/relation";
export default class MongoAssert {
static unique = AssertUnique;
static relation = AssertRelation;
static constrained = AssertConstrained;
export default class MongoValidator {
static assertUnique = AssertUnique;
static assertRelation = AssertRelation;
static assertConstrained = AssertConstrained;
}