@rpcbase/db
v0.68.0
Published
This package provides a small Zod extension that adds `.unique()` and `.sparse()` to `z.string()`, `z.number()`, and `z.date()` (for chaining/compatibility).
Readme
@rpcbase/db
Zod extensions
This package provides a small Zod extension that adds .unique() and .sparse() to z.string(), z.number(), and z.date() (for chaining/compatibility).
import { z } from "@rpcbase/db"
const ZUser = z.object({
email: z.string().email().unique().sparse(),
createdAt: z.date().sparse(),
})LocalizedString / zI18nString()
zI18nString() (alias of zLocalizedString()) describes a localized string as an object keyed by language codes (BCP47):
import { z, zI18nString } from "@rpcbase/db"
const ZPost = z.object({
title: zI18nString(), // { "en": "...", "fr": "...", "fr-FR": "..." }
})Mongoose re-export
import { Schema, model, mongoose } from "@rpcbase/db"Transactions (MongoDB / Mongoose sessions)
@rpcbase/db supports MongoDB transactions via Mongoose sessions.
To make a write atomic across tenant DB + global DB + tenant filesystem DB, use withTransaction(...) and pass { session } to every operation (Mongoose and native driver):
import { models, withTransaction } from "@rpcbase/db"
await withTransaction({ tenantId }, async ({ session, ctx, db }) => {
const Item = await models.get("Item", ctx.tenant)
const item = await Item.create({ uid: "u1", name: "Hello", createdAt: Date.now() }, { session })
const globalNative = db.global.db
if (globalNative) {
await globalNative.collection("rb_audit_log").insertOne({ itemId: item._id.toString() }, { session })
}
const filesystemNative = db.filesystem.db
if (filesystemNative) {
await filesystemNative.collection("rb_fs_meta").insertOne({ itemId: item._id.toString() }, { session })
}
})Notes:
- MongoDB transactions require a replica set (or a sharded cluster). On a standalone MongoDB server,
withTransactionwill fail. - To include deletes in the same transaction, the RTS delete change-log plugin is session-aware (
rtsChangeLogPlugin).
Mongoose localized fallback (optional)
When storing localized strings as plain objects, mongooseLocalizedStringField() adds a getter that returns a proxy with fallback behavior:
import { Schema, mongooseLocalizedStringField } from "@rpcbase/db"
const PostSchema = new Schema({
title: mongooseLocalizedStringField(),
})Search helpers
@rpcbase/db exposes helpers to run MongoDB search:
import { buildSearchTextStage, ensureSearchIndex, searchMetaProjection } from "@rpcbase/db"buildSearchTextStage(...)builds a$searchstage.ensureSearchIndex(...)creates an index if missing (listSearchIndexes+createSearchIndexes) and returns{ created: boolean }.searchMetaProjection()addsscoreandhighlightsprojection fields.
Sample usage (sample-app) in sample-app/src/api/search/items/handler.ts:
await ensureSearchIndex({ db: Item.db.db, collection: Item.collection.name, name: "item_name_text_v1", definition })
const results = await Item.aggregate([
buildSearchTextStage({ index: "item_name_text_v1", query, path: "name", highlightPath: "name" }),
{ $limit: 20 },
{ $project: { name: 1, createdAt: 1, ...searchMetaProjection() } },
]).exec()Dans sample-app, la config se trouve dans sample-app/infrastructure (compose.yml, mongot/config.yml, mongot/mongodb-init.js, ensure-mongot-*).
