Skip to content

Field Types

Monch provides a field helper with common field types built on Zod. All field types support the full Zod API.

Basic Types

String

typescript
field.string()                    // Required string
field.string().min(1)             // At least 1 character
field.string().max(100)           // At most 100 characters
field.string().length(10)         // Exactly 10 characters
field.string().trim()             // Trim whitespace
field.string().toLowerCase()      // Convert to lowercase
field.string().optional()         // Optional (can be undefined)
field.string().nullable()         // Can be null
field.string().default('hello')   // Default value

Number

typescript
field.number()                    // Required number
field.number().int()              // Integer only
field.number().positive()         // Greater than 0
field.number().negative()         // Less than 0
field.number().min(0)             // Minimum value
field.number().max(100)           // Maximum value
field.number().multipleOf(5)      // Must be multiple of 5

Boolean

typescript
field.boolean()                   // Required boolean
field.boolean().default(false)    // Default value

Date

typescript
field.date()                      // Required date
field.date().min(new Date())      // Minimum date
field.date().max(new Date())      // Maximum date

field.datetime()                  // Date with default to now

ID Types

ObjectId

typescript
// Auto-generating ObjectId (for _id field)
field.id()

// Required ObjectId reference (for foreign keys)
field.objectId()

Both accept strings and automatically convert them to ObjectId:

typescript
await Users.insertOne({
  _id: '507f1f77bcf86cd799439011',  // Converted to ObjectId
  name: 'Alice',
});

UUID

typescript
field.uuid()  // Auto-generating UUID v4

// Result: '123e4567-e89b-12d3-a456-426614174000'

Validation Types

Email

typescript
field.email()  // Email validation

URL

typescript
field.url()  // URL validation

Enum

typescript
// String enum
field.enum(['pending', 'active', 'suspended'])

// With default
field.enum(['user', 'admin']).default('user')

Complex Types

Array

typescript
// Array of strings
field.array(field.string())

// Array of numbers with constraints
field.array(field.number()).min(1).max(10)

// Array of objects
field.array(field.object({
  name: field.string(),
  value: field.number(),
}))

Object

typescript
// Nested object
field.object({
  street: field.string(),
  city: field.string(),
  zip: field.string(),
  country: field.string().default('US'),
})

// Optional nested object
field.object({
  bio: field.string().optional(),
  website: field.url().optional(),
}).optional()

BSON Types

Long (64-bit Integer)

typescript
field.long()  // MongoDB Long (Int64)

// Usage
await Stats.insertOne({
  viewCount: Long.fromNumber(9007199254740993),  // Beyond JS safe integer
});

Serialization

Long values serialize to number when within JavaScript's safe integer range (±9,007,199,254,740,991). Values outside this range serialize to bigint to preserve precision.

Decimal128 (High-Precision Decimal)

typescript
field.decimal()  // MongoDB Decimal128

// Usage - great for financial calculations
await Accounts.insertOne({
  balance: Decimal128.fromString('99999999999999.99'),
});

Binary

typescript
field.binary()  // MongoDB Binary

// Usage
await Files.insertOne({
  content: new Binary(Buffer.from('hello')),
});

Timestamp

typescript
field.timestamp()  // MongoDB Timestamp

// Usage - internal MongoDB operations
await OpLog.insertOne({
  ts: new Timestamp({ t: 1234567890, i: 1 }),
});

Serialization

Timestamp serializes to { t: number, i: number } where t is the timestamp and i is the increment.

Money Type

Built-in currency support with 30+ currencies, stored as Decimal128 for precision:

typescript
field.money()                           // Default: USD
field.money({ currency: 'EUR' })        // Euro
field.money({ currency: 'JPY' })        // Japanese Yen (no decimals)
field.money({ currency: 'BTC' })        // Bitcoin (8 decimals)

Money Options

typescript
field.money({
  currency: 'USD',        // Default currency code (default: 'USD')
  min: 0,                 // Minimum amount
  max: 10000,             // Maximum amount
  allowNegative: false,   // Allow negative amounts (default: false)
});

MoneyValue Structure

Stored as Decimal128 for financial precision:

typescript
{
  amount: Decimal128,    // High-precision decimal value
  currency: string,      // Currency code (e.g., 'USD')
}

Flexible Input Formats

Money fields accept multiple input formats:

typescript
await Products.insertOne({
  name: 'Widget',
  price: 29.99,                              // Number
  priceEUR: '49.99',                         // String
  priceJPY: { amount: 3500, currency: 'JPY' }, // Object
});

// Stored as Decimal128:
// {
//   price: { amount: Decimal128('29.99'), currency: 'USD' },
//   priceEUR: { amount: Decimal128('49.99'), currency: 'EUR' },
//   priceJPY: { amount: Decimal128('3500'), currency: 'JPY' }
// }

Example Usage

typescript
import { collection, field, Money } from '@codician-team/monch';

const Products = collection({
  name: 'products',
  schema: {
    _id: field.id(),
    name: field.string(),
    price: field.money({ currency: 'USD' }),
  },
});

// Insert with decimal amount
const product = await Products.insertOne({
  name: 'Widget',
  price: 19.99,
});

// Use Money utility class for operations
Money.format(product.price);        // '$19.99'
Money.toCents(product.price);       // 1999 (for Stripe)
Money.toNumber(product.price);      // 19.99

Supported Currencies

USD, EUR, GBP, JPY, CNY, INR, AUD, CAD, CHF, HKD, SGD, SEK, KRW, NOK, NZD, MXN, TWD, ZAR, BRL, DKK, PLN, THB, ILS, IDR, CZK, AED, TRY, HUF, CLP, SAR, PHP, MYR, COP, RUB, RON, BTC, and ETH.

Money Utility Class

The Money class provides all operations for monetary values:

typescript
import { Money } from '@codician-team/monch';

// Formatting
Money.format(price);                    // '$99.99'
Money.format(price, { precision: 0 });  // '$100'

// Conversions
Money.toNumber(price);      // 99.99 (may lose precision)
Money.toString(price);      // '99.99' (exact)
Money.toCents(price);       // 9999 (for payment APIs)
Money.fromCents(9999, 'USD'); // MoneyValue

// Create MoneyValue
Money.from(99.99);                              // From number
Money.from('99.99', 'EUR');                     // From string
Money.from({ amount: 99.99, currency: 'GBP' }); // From object

// Arithmetic
Money.add(price, tax);           // Add two values
Money.subtract(price, discount); // Subtract
Money.multiply(price, 1.1);      // Multiply (10% increase)
Money.divide(total, 4);          // Divide
Money.percentage(price, 15);     // Calculate 15%
Money.round(result);             // Round to currency precision

// Aggregation
Money.sum([price1, price2]);     // Sum array
Money.min(price1, price2);       // Find minimum
Money.max(price1, price2);       // Find maximum

// Splitting
Money.split(total, 3);           // Split equally [$33.34, $33.33, $33.33]
Money.allocate(total, [2,1,1]);  // Split by ratios [$50, $25, $25]

// Comparison
Money.equals(a, b);              // Check equality
Money.compare(a, b);             // -1 | 0 | 1
Money.greaterThan(a, b);         // a > b
Money.lessThan(a, b);            // a < b
Money.isZero(price);             // Check if zero
Money.isPositive(price);         // Check if positive
Money.isNegative(price);         // Check if negative
Money.abs(price);                // Absolute value
Money.negate(price);             // Negate value

// JSON serialization
Money.toJSON(price);
// { amount: '99.99', currency: 'USD', display: '$99.99', cents: 9999 }

Currency Configuration

typescript
import { getCurrencyConfig, CURRENCY_CONFIGS } from '@codician-team/monch';

// Get currency configuration
const config = getCurrencyConfig('USD');
// { code: 'USD', symbol: '$', precision: 2, symbolPosition: 'before' }

// Access all currency configs
CURRENCY_CONFIGS.EUR  // { code: 'EUR', symbol: '€', ... }

Quick Reference

MethodOutput TypeDescription
field.id()ObjectIdAuto-generating ObjectId
field.objectId()ObjectIdRequired ObjectId reference
field.uuid()stringAuto-generating UUID
field.string()stringString
field.number()numberNumber
field.boolean()booleanBoolean
field.date()DateDate
field.datetime()DateDate with default to now
field.email()stringEmail validation
field.url()stringURL validation
field.enum([...])unionEnum type
field.array(type)T[]Array of type
field.object({...})objectNested object
field.long()Long64-bit integer
field.decimal()Decimal128High-precision decimal
field.binary()BinaryBinary data
field.timestamp()TimestampMongoDB timestamp
field.money(opts?)MoneyValueCurrency with formatting

Released under the MIT License.