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. 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: Some of its features include:
@@ -12,20 +12,20 @@ Some of its features include:
## But why? ## 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 ## 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 ```bash
npm install mongo-assert npm install mongo-validate
pnpm install mongo-assert pnpm install mongo-validate
yarn add mongo-assert yarn add mongo-validate
bun install mongo-assert 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. with any MongoDB instance.
## Examples ## Examples
@@ -36,7 +36,7 @@ For all of the examples below, we'll be using the following schema:
```ts ```ts
import { z } from 'zod'; import { z } from 'zod';
import { ObjectId } from "mongo-assert/lib/mongodb" import { ObjectId } from "mongo-validate/lib/mongodb"
export const userSchema = z.object({ export const userSchema = z.object({
_id: ObjectId, _id: ObjectId,
@@ -49,13 +49,14 @@ export type User = z.infer<typeof userSchema>;
### Unique field validation ### 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 ```ts
import MongoAssert, { type AssertUniqueType } from 'mongo-assert'; import mongo-validate, { type AssertUniqueType } from 'mongo-validate';
import { userSchema, type User } from "./schemas"; 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 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 ### 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: 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: Now, we can define a reference validator between these two collections:
```ts ```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", db: "your-db",
mainCollection: "users", mainCollection: "users",
relationCollection: "stores", relationCollection: "stores",

View File

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

View File

@@ -1,5 +1,5 @@
{ {
"name": "mongo-assert", "name": "mongo-validate",
"version": "0.0.1", "version": "0.0.1",
"description": "Lightweight schema validation for MongoDB with Zod", "description": "Lightweight schema validation for MongoDB with Zod",
"author": "Mikayla Dobson", "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 { AssertUniqueType } from "./actions/unique";
export type { AssertRelationType } from "./actions/relation"; export type { AssertRelationType } from "./actions/relation";
export default class MongoAssert { export default class MongoValidator {
static unique = AssertUnique; static assertUnique = AssertUnique;
static relation = AssertRelation; static assertRelation = AssertRelation;
static constrained = AssertConstrained; static assertConstrained = AssertConstrained;
} }