mondel 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,888 @@
1
+ import * as mongodb from 'mongodb';
2
+ import { AggregateOptions, Document, FindOptions as FindOptions$1, Sort, InsertOneOptions, BulkWriteOptions, UpdateOptions as UpdateOptions$1, DeleteOptions as DeleteOptions$1, CountDocumentsOptions, ObjectId, Filter, MongoClientOptions, Db, ClientSessionOptions, ClientSession, WithId, OptionalUnlessRequiredId, InsertOneResult, InsertManyResult, UpdateResult, DeleteResult, Collection } from 'mongodb';
3
+ export { ClientSession, ObjectId } from 'mongodb';
4
+ import { z, ZodTypeAny } from 'zod';
5
+
6
+ type FieldType = "string" | "number" | "boolean" | "date" | "objectId" | "array" | "object" | "json" | "literal";
7
+ interface IndexOptions {
8
+ type?: 1 | -1 | "text" | "2dsphere" | "2d";
9
+ name?: string;
10
+ unique?: boolean;
11
+ sparse?: boolean;
12
+ expireAfterSeconds?: number;
13
+ partialFilterExpression?: Document;
14
+ }
15
+ interface CompoundIndexDefinition {
16
+ fields: Record<string, 1 | -1 | "text" | "2dsphere" | "2d">;
17
+ options?: {
18
+ name?: string;
19
+ unique?: boolean;
20
+ sparse?: boolean;
21
+ partialFilterExpression?: Document;
22
+ weights?: Record<string, number>;
23
+ };
24
+ }
25
+ interface FieldDefinition<T = unknown> {
26
+ type: FieldType;
27
+ required: boolean;
28
+ unique: boolean;
29
+ default?: T | "auto";
30
+ index?: IndexOptions;
31
+ enum?: readonly string[];
32
+ min?: number;
33
+ max?: number;
34
+ minLength?: number;
35
+ maxLength?: number;
36
+ pattern?: RegExp;
37
+ email?: boolean;
38
+ url?: boolean;
39
+ items?: FieldDefinition;
40
+ properties?: Record<string, FieldDefinition>;
41
+ literal?: string | number | boolean;
42
+ }
43
+ interface TimestampConfig {
44
+ createdAt?: string;
45
+ updatedAt?: string;
46
+ }
47
+ interface ValidationConfig {
48
+ enabled?: boolean;
49
+ mode?: "strict" | "loose" | "off";
50
+ }
51
+ interface SchemaDefinition<TFields extends Record<string, FieldDefinition> = Record<string, FieldDefinition>> {
52
+ collection?: string;
53
+ timestamps?: boolean | TimestampConfig;
54
+ validation?: ValidationConfig;
55
+ connection?: string;
56
+ fields: TFields;
57
+ indexes?: CompoundIndexDefinition[];
58
+ }
59
+ interface Schema<TName extends string = string, TFields extends Record<string, FieldDefinition> = Record<string, FieldDefinition>> {
60
+ name: TName;
61
+ collection: string;
62
+ timestamps: TimestampConfig | false;
63
+ validation: ValidationConfig;
64
+ connection?: string;
65
+ fields: TFields;
66
+ indexes: CompoundIndexDefinition[];
67
+ }
68
+ type ValidationMode = "strict" | "loose" | "off";
69
+ type InferFieldType<T extends FieldDefinition> = T extends {
70
+ type: "string";
71
+ } ? T extends {
72
+ enum: readonly (infer E)[];
73
+ } ? E : string : T extends {
74
+ type: "number";
75
+ } ? number : T extends {
76
+ type: "boolean";
77
+ } ? boolean : T extends {
78
+ type: "date";
79
+ } ? Date : T extends {
80
+ type: "objectId";
81
+ } ? ObjectId : T extends {
82
+ type: "array";
83
+ items: infer I extends FieldDefinition;
84
+ } ? InferFieldType<I>[] : T extends {
85
+ type: "object";
86
+ properties: infer P extends Record<string, FieldDefinition>;
87
+ } ? {
88
+ [K in keyof P]: InferFieldType<P[K]>;
89
+ } : T extends {
90
+ type: "json";
91
+ } ? unknown : T extends {
92
+ type: "literal";
93
+ literal: infer L;
94
+ } ? L : unknown;
95
+ type InferBuilderValue<T> = T extends {
96
+ build(): FieldDefinition<infer V>;
97
+ } ? V : unknown;
98
+ type TimestampFields<T extends Schema> = T["timestamps"] extends false ? never : T["timestamps"] extends {
99
+ createdAt?: infer C;
100
+ updatedAt?: infer U;
101
+ } ? (C extends string ? C : "createdAt") | (U extends string ? U : "updatedAt") : "createdAt" | "updatedAt";
102
+ type TimestampFieldsType<T extends Schema> = T["timestamps"] extends false ? object : T["timestamps"] extends {
103
+ createdAt?: infer C;
104
+ updatedAt?: infer U;
105
+ } ? {
106
+ [K in C extends string ? C : "createdAt"]?: Date;
107
+ } & {
108
+ [K in U extends string ? U : "updatedAt"]?: Date;
109
+ } : {
110
+ createdAt?: Date;
111
+ updatedAt?: Date;
112
+ };
113
+ type InferSchemaType<T extends Schema> = {
114
+ _id: ObjectId;
115
+ } & (T extends {
116
+ __fields: infer TFields;
117
+ } ? {
118
+ [K in keyof TFields]?: InferBuilderValue<TFields[K]>;
119
+ } : {
120
+ [K in keyof T["fields"]]?: InferFieldType<T["fields"][K]>;
121
+ }) & TimestampFieldsType<T>;
122
+ type CreateInput<T extends Schema> = Omit<InferSchemaType<T>, "_id" | TimestampFields<T>>;
123
+ type UpdateInput<T extends Schema> = Partial<Omit<InferSchemaType<T>, "_id" | TimestampFields<T>>>;
124
+ type WhereInput<T extends Schema> = Filter<InferSchemaType<T>>;
125
+ type SelectInput<T extends Schema> = {
126
+ _id?: boolean | 0 | 1;
127
+ } & {
128
+ [K in keyof T["fields"]]?: boolean | 0 | 1;
129
+ } & (T["timestamps"] extends false ? object : T["timestamps"] extends {
130
+ createdAt?: infer C;
131
+ updatedAt?: infer U;
132
+ } ? {
133
+ [K in C extends string ? C : "createdAt"]?: boolean | 0 | 1;
134
+ } & {
135
+ [K in U extends string ? U : "updatedAt"]?: boolean | 0 | 1;
136
+ } : {
137
+ createdAt?: boolean | 0 | 1;
138
+ updatedAt?: boolean | 0 | 1;
139
+ });
140
+ type SortInput<T extends Schema> = Sort;
141
+ interface FindOptions<T extends Schema> extends Omit<FindOptions$1, "projection" | "sort"> {
142
+ select?: SelectInput<T>;
143
+ sort?: SortInput<T>;
144
+ skip?: number;
145
+ limit?: number;
146
+ }
147
+ interface CreateOptions extends InsertOneOptions {
148
+ timestamps?: boolean;
149
+ }
150
+ interface CreateManyOptions extends BulkWriteOptions {
151
+ timestamps?: boolean;
152
+ }
153
+ interface UpdateOptions extends UpdateOptions$1 {
154
+ timestamps?: boolean;
155
+ }
156
+ interface DeleteOptions extends DeleteOptions$1 {
157
+ soft?: boolean;
158
+ }
159
+ interface CountOptions extends CountDocumentsOptions {
160
+ }
161
+ interface AggregateOpts extends AggregateOptions {
162
+ }
163
+
164
+ type SchemaToCollectionProxy<TSchema extends Schema<string, Record<string, FieldDefinition>>> = {
165
+ findOne(where?: Filter<InferSchemaType<TSchema>>, options?: FindOptions<TSchema>): Promise<InferSchemaType<TSchema> | null>;
166
+ findMany(where?: Filter<InferSchemaType<TSchema>>, options?: FindOptions<TSchema>): Promise<InferSchemaType<TSchema>[]>;
167
+ findById(id: ObjectId | string, options?: FindOptions<TSchema>): Promise<InferSchemaType<TSchema> | null>;
168
+ create(data: CreateInput<TSchema>, options?: CreateOptions): Promise<{
169
+ insertedId: ObjectId;
170
+ } & InferSchemaType<TSchema>>;
171
+ createMany(data: CreateInput<TSchema>[], options?: CreateManyOptions): Promise<{
172
+ insertedIds: Record<number, ObjectId>;
173
+ }>;
174
+ updateOne(where: Filter<InferSchemaType<TSchema>>, data: UpdateInput<TSchema> | Document, options?: UpdateOptions): Promise<{
175
+ matchedCount: number;
176
+ modifiedCount: number;
177
+ upsertedId?: ObjectId;
178
+ }>;
179
+ updateMany(where: Filter<InferSchemaType<TSchema>>, data: UpdateInput<TSchema> | Document, options?: UpdateOptions): Promise<{
180
+ matchedCount: number;
181
+ modifiedCount: number;
182
+ upsertedId?: ObjectId;
183
+ }>;
184
+ updateById(id: ObjectId | string, data: UpdateInput<TSchema> | Document, options?: UpdateOptions): Promise<{
185
+ matchedCount: number;
186
+ modifiedCount: number;
187
+ }>;
188
+ deleteOne(where: Filter<InferSchemaType<TSchema>>, options?: DeleteOptions): Promise<{
189
+ deletedCount: number;
190
+ }>;
191
+ deleteMany(where: Filter<InferSchemaType<TSchema>>, options?: DeleteOptions): Promise<{
192
+ deletedCount: number;
193
+ }>;
194
+ deleteById(id: ObjectId | string, options?: DeleteOptions): Promise<{
195
+ deletedCount: number;
196
+ }>;
197
+ count(where?: Filter<InferSchemaType<TSchema>>, options?: CountOptions): Promise<number>;
198
+ exists(where: Filter<InferSchemaType<TSchema>>, options?: CountOptions): Promise<boolean>;
199
+ aggregate<T = InferSchemaType<TSchema>>(pipeline: Document[], options?: AggregateOpts): Promise<T[]>;
200
+ getCollection(): mongodb.Collection;
201
+ };
202
+
203
+ declare const __type: unique symbol;
204
+ declare const __required: unique symbol;
205
+ declare class FieldBuilder<T = unknown, TRequired extends boolean = false> {
206
+ private definition;
207
+ readonly [__type]: T;
208
+ readonly [__required]: TRequired;
209
+ constructor(type: FieldDefinition["type"]);
210
+ required(): FieldBuilder<T, true>;
211
+ unique(): this;
212
+ default(value: T | "auto"): this;
213
+ index(options?: IndexOptions): this;
214
+ build(): FieldDefinition<T>;
215
+ }
216
+ declare class StringFieldBuilder extends FieldBuilder<string> {
217
+ constructor();
218
+ min(length: number): this;
219
+ max(length: number): this;
220
+ pattern(regex: RegExp): this;
221
+ email(): this;
222
+ url(): this;
223
+ text(): this;
224
+ enum<const E extends readonly string[]>(values: E): EnumFieldBuilder<E[number]>;
225
+ }
226
+ declare class EnumFieldBuilder<T extends string> extends FieldBuilder<T> {
227
+ constructor(values: readonly T[]);
228
+ }
229
+ declare class NumberFieldBuilder extends FieldBuilder<number> {
230
+ constructor();
231
+ min(value: number): this;
232
+ max(value: number): this;
233
+ }
234
+ declare class BooleanFieldBuilder extends FieldBuilder<boolean> {
235
+ constructor();
236
+ }
237
+ declare class DateFieldBuilder extends FieldBuilder<Date> {
238
+ constructor();
239
+ }
240
+ declare class ObjectIdFieldBuilder extends FieldBuilder<unknown> {
241
+ constructor();
242
+ }
243
+ declare class ArrayFieldBuilder<T> extends FieldBuilder<T[]> {
244
+ constructor(items: FieldDefinition);
245
+ }
246
+ declare class ObjectFieldBuilder<T extends Record<string, unknown>> extends FieldBuilder<T> {
247
+ constructor(properties: Record<string, FieldDefinition>);
248
+ }
249
+ declare class JsonFieldBuilder extends FieldBuilder<unknown> {
250
+ constructor();
251
+ }
252
+ declare class LiteralFieldBuilder<T extends string | number | boolean> extends FieldBuilder<T> {
253
+ constructor(value: T);
254
+ }
255
+
256
+ type FieldBuilderResult = {
257
+ build(): FieldDefinition;
258
+ required(): FieldBuilderResult;
259
+ unique(): FieldBuilderResult;
260
+ default(value: unknown): FieldBuilderResult;
261
+ index(options?: IndexOptions): FieldBuilderResult;
262
+ };
263
+ type SchemaFieldsInput = Record<string, FieldBuilderResult>;
264
+ declare const s: {
265
+ string(): StringFieldBuilder;
266
+ number(): NumberFieldBuilder;
267
+ boolean(): BooleanFieldBuilder;
268
+ date(): DateFieldBuilder;
269
+ objectId(): ObjectIdFieldBuilder;
270
+ array<T>(items: {
271
+ build(): FieldDefinition;
272
+ }): ArrayFieldBuilder<T>;
273
+ object<T extends Record<string, unknown>>(properties: Record<string, {
274
+ build(): FieldDefinition;
275
+ }>): ObjectFieldBuilder<T>;
276
+ json(): JsonFieldBuilder;
277
+ literal<T extends string | number | boolean>(value: T): LiteralFieldBuilder<T>;
278
+ enum<const E extends readonly string[]>(values: E): EnumFieldBuilder<E[number]>;
279
+ };
280
+
281
+ interface SchemaInput<TFields extends SchemaFieldsInput, TTimestamps extends boolean | TimestampConfig = boolean | TimestampConfig> {
282
+ collection?: string;
283
+ timestamps?: TTimestamps;
284
+ validation?: {
285
+ enabled?: boolean;
286
+ mode?: "strict" | "loose" | "off";
287
+ };
288
+ connection?: string;
289
+ fields: TFields;
290
+ indexes?: CompoundIndexDefinition[];
291
+ }
292
+ type InferSchemaFields<TFields extends SchemaFieldsInput> = {
293
+ [K in keyof TFields]: TFields[K] extends {
294
+ build(): infer FD;
295
+ } ? FD extends FieldDefinition<infer T> ? FieldDefinition<T> & {
296
+ required: TFields[K] extends {
297
+ _required: true;
298
+ } ? true : false;
299
+ unique: TFields[K] extends {
300
+ _unique: true;
301
+ } ? true : false;
302
+ } : FieldDefinition : FieldDefinition;
303
+ };
304
+ type ResolvedTimestamps<T> = T extends true ? {
305
+ createdAt: "createdAt";
306
+ updatedAt: "updatedAt";
307
+ } : T extends TimestampConfig ? T : false;
308
+ type InferredSchema<TName extends string, TFields extends SchemaFieldsInput, TTimestamps extends boolean | TimestampConfig = true> = Omit<Schema<TName, InferSchemaFields<TFields>>, "timestamps"> & {
309
+ readonly timestamps: ResolvedTimestamps<TTimestamps>;
310
+ readonly __fields: TFields;
311
+ };
312
+ declare function schema<const TName extends string, const TFields extends SchemaFieldsInput, const TTimestamps extends boolean | TimestampConfig = false>(name: TName, definition: SchemaInput<TFields, TTimestamps>): InferredSchema<TName, TFields, TTimestamps>;
313
+ declare const defineSchema: typeof schema;
314
+
315
+ type AnySchema = Schema<string, Record<string, FieldDefinition>>;
316
+ /**
317
+ * Configuration for serverless environments (Cloudflare Workers, Vercel Edge, etc.)
318
+ * Returns a factory function that creates connections on-demand.
319
+ *
320
+ * @template TSchemas - Tuple of schema types for type inference
321
+ *
322
+ * @example
323
+ * ```typescript
324
+ * const connectDb = createClient({
325
+ * serverless: true,
326
+ * schemas: [userSchema, postSchema] as const,
327
+ * syncIndexes: false, // Recommended for serverless
328
+ * validation: "strict"
329
+ * });
330
+ *
331
+ * // Later, in request handler:
332
+ * const db = await connectDb(env.MONGODB_URI);
333
+ * ```
334
+ */
335
+ interface ServerlessClientConfig<TSchemas extends readonly AnySchema[]> {
336
+ /** Must be true for serverless mode */
337
+ serverless: true;
338
+ /** Array of schemas to register (use `as const` for type inference) */
339
+ schemas: TSchemas;
340
+ /** Whether to sync indexes on connect (default: false for serverless) */
341
+ syncIndexes?: boolean;
342
+ /** Validation mode: "strict" | "loose" | "off" (default: "strict") */
343
+ validation?: ValidationMode;
344
+ }
345
+ /**
346
+ * Configuration for traditional Node.js environments.
347
+ * Connects immediately and returns a ready-to-use client.
348
+ *
349
+ * @template TSchemas - Tuple of schema types for type inference
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * const db = await createClient({
354
+ * uri: process.env.MONGODB_URI,
355
+ * schemas: [userSchema, postSchema] as const,
356
+ * syncIndexes: true,
357
+ * validation: "strict"
358
+ * });
359
+ * ```
360
+ */
361
+ interface NodeClientConfig<TSchemas extends readonly AnySchema[]> {
362
+ /** Set to false or omit for Node.js mode */
363
+ serverless?: false;
364
+ /** MongoDB connection URI (e.g., mongodb://localhost:27017/mydb) */
365
+ uri: string;
366
+ /** Array of schemas to register (use `as const` for type inference) */
367
+ schemas: TSchemas;
368
+ /** Whether to sync indexes on connect (default: true) */
369
+ syncIndexes?: boolean;
370
+ /** Validation mode: "strict" | "loose" | "off" (default: "strict") */
371
+ validation?: ValidationMode;
372
+ /** MongoDB driver options (maxPoolSize, etc.) */
373
+ options?: MongoClientOptions;
374
+ }
375
+ /**
376
+ * Union type of all client configurations.
377
+ */
378
+ type ClientConfig<TSchemas extends readonly AnySchema[]> = ServerlessClientConfig<TSchemas> | NodeClientConfig<TSchemas>;
379
+ type ClientMethods = {
380
+ readonly close: () => Promise<void>;
381
+ readonly getDb: () => Db;
382
+ readonly startSession: (options?: ClientSessionOptions) => ClientSession;
383
+ };
384
+ type SchemaNames<TSchemas extends readonly AnySchema[]> = TSchemas[number]["name"];
385
+ type ValidClientKeys<TSchemas extends readonly AnySchema[]> = SchemaNames<TSchemas> | keyof ClientMethods;
386
+ type SchemasToClient<TSchemas extends readonly AnySchema[]> = {
387
+ readonly [K in ValidClientKeys<TSchemas>]: K extends SchemaNames<TSchemas> ? SchemaToCollectionProxy<Extract<TSchemas[number], {
388
+ name: K;
389
+ }>> : K extends keyof ClientMethods ? ClientMethods[K] : never;
390
+ };
391
+ /**
392
+ * Create a type-safe MongoDB client with schema-based collection access.
393
+ *
394
+ * **Serverless Mode** (recommended for Cloudflare Workers, Vercel Edge):
395
+ * Returns a factory function that creates connections on-demand.
396
+ *
397
+ * @param config - Client configuration with `serverless: true`
398
+ * @returns Factory function: `(uri: string, options?) => Promise<Client>`
399
+ *
400
+ * @example
401
+ * ```typescript
402
+ * import { createClient, type SchemasToClient } from "mondel";
403
+ * import { userSchema, postSchema } from "./schemas";
404
+ *
405
+ * const schemas = [userSchema, postSchema] as const;
406
+ * export type DbClient = SchemasToClient<typeof schemas>;
407
+ *
408
+ * // Create factory (no connection yet)
409
+ * const connectDb = createClient({
410
+ * serverless: true,
411
+ * schemas,
412
+ * syncIndexes: false,
413
+ * validation: "strict"
414
+ * });
415
+ *
416
+ * // In request handler
417
+ * export async function handleRequest(env: Env) {
418
+ * const db = await connectDb(env.MONGODB_URI);
419
+ * const users = await db.users.findMany({ isActive: true });
420
+ * await db.close();
421
+ * return users;
422
+ * }
423
+ * ```
424
+ */
425
+ declare function createClient<const TSchemas extends readonly AnySchema[]>(config: ServerlessClientConfig<TSchemas>): (uri: string, options?: MongoClientOptions) => Promise<SchemasToClient<TSchemas>>;
426
+ /**
427
+ * Create a type-safe MongoDB client with schema-based collection access.
428
+ *
429
+ * **Node.js Mode** (for traditional servers, scripts, tests):
430
+ * Connects immediately and returns a ready-to-use client.
431
+ *
432
+ * @param config - Client configuration with `serverless: false` or omitted
433
+ * @returns Promise resolving to connected client
434
+ *
435
+ * @example
436
+ * ```typescript
437
+ * import { createClient } from "mondel";
438
+ * import { userSchema, postSchema } from "./schemas";
439
+ *
440
+ * async function main() {
441
+ * const db = await createClient({
442
+ * uri: process.env.MONGODB_URI!,
443
+ * schemas: [userSchema, postSchema] as const,
444
+ * syncIndexes: true,
445
+ * validation: "strict"
446
+ * });
447
+ *
448
+ * // Type-safe access to collections
449
+ * const users = await db.users.findMany({ role: "ADMIN" });
450
+ *
451
+ * // Close when done
452
+ * await db.close();
453
+ * }
454
+ * ```
455
+ */
456
+ declare function createClient<const TSchemas extends readonly AnySchema[]>(config: NodeClientConfig<TSchemas>): Promise<SchemasToClient<TSchemas>>;
457
+
458
+ /**
459
+ * Creates a complete Zod schema from a Mondel schema definition.
460
+ * Includes all fields and timestamp fields if configured.
461
+ *
462
+ * @param schema - Mondel schema definition
463
+ * @returns Zod object schema for full document validation
464
+ *
465
+ * @example
466
+ * ```typescript
467
+ * const zod = zodSchema(userSchema);
468
+ * const result = zod.safeParse(document);
469
+ * ```
470
+ */
471
+ declare function zodSchema<TSchema extends Schema>(schema: TSchema): z.ZodObject<Record<string, ZodTypeAny>>;
472
+ /**
473
+ * Creates a Zod schema for insert operations.
474
+ * Excludes _id and timestamp fields (auto-generated).
475
+ * Used internally by `create()` and `createMany()` methods.
476
+ *
477
+ * @param schema - Mondel schema definition
478
+ * @returns Zod schema for create validation
479
+ */
480
+ declare function zodCreateSchema<TSchema extends Schema>(schema: TSchema): z.ZodObject<Record<string, ZodTypeAny>>;
481
+ /**
482
+ * Creates a Zod schema for update operations.
483
+ * All fields become optional (partial update support).
484
+ * Used internally by `updateOne()`, `updateMany()`, `updateById()` methods.
485
+ *
486
+ * @param schema - Mondel schema definition
487
+ * @returns Zod schema with all fields optional
488
+ */
489
+ declare function zodUpdateSchema<TSchema extends Schema>(schema: TSchema): z.ZodObject<Record<string, ZodTypeAny>>;
490
+ /**
491
+ * Validates data against a Zod schema.
492
+ *
493
+ * @param schema - Zod schema to validate against
494
+ * @param data - Data to validate
495
+ * @returns Result object with success status and data or errors
496
+ *
497
+ * @example
498
+ * ```typescript
499
+ * const result = validate(zodCreateSchema(userSchema), userData);
500
+ * if (result.success) {
501
+ * console.log(result.data);
502
+ * } else {
503
+ * console.error(result.errors);
504
+ * }
505
+ * ```
506
+ */
507
+ declare function validate<T>(schema: z.ZodType<T>, data: unknown): {
508
+ success: true;
509
+ data: T;
510
+ } | {
511
+ success: false;
512
+ errors: z.ZodError;
513
+ };
514
+
515
+ /**
516
+ * Type-safe collection proxy for MongoDB operations.
517
+ * Provides CRUD methods with full TypeScript support and Zod validation.
518
+ *
519
+ * @template TSchema - The schema type for this collection
520
+ *
521
+ * @example
522
+ * ```typescript
523
+ * // Access via client
524
+ * const db = await getMondelClient(env);
525
+ * const users = await db.users.findMany({ isActive: true });
526
+ * ```
527
+ */
528
+ declare class CollectionProxy<TSchema extends Schema> {
529
+ private collection;
530
+ private schema;
531
+ private validationMode;
532
+ constructor(db: Db, schema: TSchema, validationMode?: ValidationMode);
533
+ private validateCreate;
534
+ private validateUpdate;
535
+ /**
536
+ * Find a single document matching the filter.
537
+ *
538
+ * @param where - MongoDB filter query
539
+ * @param options - Find options (select, sort, skip, limit, session)
540
+ * @returns The matching document or null
541
+ *
542
+ * @example
543
+ * ```typescript
544
+ * // Find by email
545
+ * const user = await db.users.findOne({ email: "john@example.com" });
546
+ *
547
+ * // With field selection
548
+ * const user = await db.users.findOne(
549
+ * { email: "john@example.com" },
550
+ * { select: { _id: true, email: true, name: true } }
551
+ * );
552
+ *
553
+ * // With session (for transactions)
554
+ * const user = await db.users.findOne(
555
+ * { email: "john@example.com" },
556
+ * { session }
557
+ * );
558
+ * ```
559
+ */
560
+ findOne(where: Filter<Document>, options?: FindOptions<TSchema>): Promise<WithId<Document> | null>;
561
+ /**
562
+ * Find multiple documents matching the filter.
563
+ *
564
+ * @param where - MongoDB filter query (optional, defaults to {})
565
+ * @param options - Find options (select, sort, skip, limit, session)
566
+ * @returns Array of matching documents
567
+ *
568
+ * @example
569
+ * ```typescript
570
+ * // Find all active users
571
+ * const users = await db.users.findMany({ isActive: true });
572
+ *
573
+ * // With pagination and sorting
574
+ * const users = await db.users.findMany(
575
+ * { role: "ADMIN" },
576
+ * {
577
+ * select: { _id: true, email: true, name: true },
578
+ * sort: { createdAt: -1 },
579
+ * skip: 0,
580
+ * limit: 10
581
+ * }
582
+ * );
583
+ *
584
+ * // Using MongoDB operators
585
+ * const users = await db.users.findMany({
586
+ * age: { $gte: 18, $lte: 65 },
587
+ * role: { $in: ["ADMIN", "MODERATOR"] }
588
+ * });
589
+ * ```
590
+ */
591
+ findMany(where?: Filter<Document>, options?: FindOptions<TSchema>): Promise<WithId<Document>[]>;
592
+ /**
593
+ * Find a document by its _id.
594
+ *
595
+ * @param id - ObjectId or string representation
596
+ * @param options - Find options (select, session)
597
+ * @returns The matching document or null
598
+ *
599
+ * @example
600
+ * ```typescript
601
+ * // Find by string ID
602
+ * const user = await db.users.findById("507f1f77bcf86cd799439011");
603
+ *
604
+ * // Find by ObjectId
605
+ * const user = await db.users.findById(new ObjectId("507f1f77bcf86cd799439011"));
606
+ *
607
+ * // With field selection
608
+ * const user = await db.users.findById(userId, {
609
+ * select: { email: true, name: true }
610
+ * });
611
+ * ```
612
+ */
613
+ findById(id: ObjectId | string, options?: FindOptions<TSchema>): Promise<WithId<Document> | null>;
614
+ /**
615
+ * Create a new document.
616
+ * Automatically adds timestamps if enabled in schema.
617
+ *
618
+ * @param data - Document data (validated against schema)
619
+ * @param options - Create options (timestamps, session)
620
+ * @returns Insert result with insertedId
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * // Create a user
625
+ * const result = await db.users.create({
626
+ * email: "john@example.com",
627
+ * name: "John Doe",
628
+ * role: "USER"
629
+ * });
630
+ * console.log(result.insertedId); // ObjectId
631
+ *
632
+ * // Disable automatic timestamps
633
+ * await db.users.create(userData, { timestamps: false });
634
+ *
635
+ * // With session (for transactions)
636
+ * await db.users.create(userData, { session });
637
+ * ```
638
+ */
639
+ create(data: OptionalUnlessRequiredId<Document>, options?: CreateOptions): Promise<InsertOneResult>;
640
+ /**
641
+ * Create multiple documents in a single operation.
642
+ * Automatically adds timestamps if enabled in schema.
643
+ *
644
+ * @param data - Array of document data
645
+ * @param options - Create options (timestamps, ordered, session)
646
+ * @returns Insert result with insertedIds
647
+ *
648
+ * @example
649
+ * ```typescript
650
+ * // Create multiple users
651
+ * const result = await db.users.createMany([
652
+ * { email: "user1@example.com", name: "User 1" },
653
+ * { email: "user2@example.com", name: "User 2" },
654
+ * { email: "user3@example.com", name: "User 3" }
655
+ * ]);
656
+ * console.log(result.insertedIds); // { 0: ObjectId, 1: ObjectId, 2: ObjectId }
657
+ *
658
+ * // With session (for transactions)
659
+ * await db.users.createMany(usersData, { session });
660
+ * ```
661
+ */
662
+ createMany(data: OptionalUnlessRequiredId<Document>[], options?: CreateManyOptions): Promise<InsertManyResult>;
663
+ /**
664
+ * Update a single document matching the filter.
665
+ * Supports both simple updates and MongoDB update operators.
666
+ *
667
+ * @param where - MongoDB filter query
668
+ * @param data - Update data or MongoDB update operators ($set, $inc, etc.)
669
+ * @param options - Update options (upsert, timestamps, session)
670
+ * @returns Update result with matchedCount, modifiedCount, upsertedId
671
+ *
672
+ * @example
673
+ * ```typescript
674
+ * // Simple update (automatically wrapped in $set)
675
+ * await db.users.updateOne(
676
+ * { email: "john@example.com" },
677
+ * { name: "John Smith" }
678
+ * );
679
+ *
680
+ * // Using MongoDB operators
681
+ * await db.users.updateOne(
682
+ * { _id: userId },
683
+ * { $set: { name: "John" }, $inc: { loginCount: 1 } }
684
+ * );
685
+ *
686
+ * // Upsert - create if not exists
687
+ * await db.users.updateOne(
688
+ * { email: "john@example.com" },
689
+ * { $set: { name: "John", isActive: true } },
690
+ * { upsert: true }
691
+ * );
692
+ *
693
+ * // With session (for transactions)
694
+ * await db.users.updateOne(filter, update, { session });
695
+ * ```
696
+ */
697
+ updateOne(where: Filter<Document>, data: Document, options?: UpdateOptions): Promise<UpdateResult>;
698
+ /**
699
+ * Update multiple documents matching the filter.
700
+ * Supports both simple updates and MongoDB update operators.
701
+ *
702
+ * @param where - MongoDB filter query
703
+ * @param data - Update data or MongoDB update operators
704
+ * @param options - Update options (upsert, timestamps, session)
705
+ * @returns Update result with matchedCount, modifiedCount
706
+ *
707
+ * @example
708
+ * ```typescript
709
+ * // Deactivate all users with expired subscriptions
710
+ * await db.users.updateMany(
711
+ * { subscriptionExpiry: { $lt: new Date() } },
712
+ * { $set: { isActive: false } }
713
+ * );
714
+ *
715
+ * // Increment login count for all admins
716
+ * await db.users.updateMany(
717
+ * { role: "ADMIN" },
718
+ * { $inc: { loginCount: 1 } }
719
+ * );
720
+ * ```
721
+ */
722
+ updateMany(where: Filter<Document>, data: Document, options?: UpdateOptions): Promise<UpdateResult>;
723
+ /**
724
+ * Update a document by its _id.
725
+ * Convenience method that wraps updateOne with _id filter.
726
+ *
727
+ * @param id - ObjectId or string representation
728
+ * @param data - Update data or MongoDB update operators
729
+ * @param options - Update options (upsert, timestamps, session)
730
+ * @returns Update result with matchedCount, modifiedCount
731
+ *
732
+ * @example
733
+ * ```typescript
734
+ * // Update by ID
735
+ * await db.users.updateById(userId, { name: "New Name" });
736
+ *
737
+ * // Using operators
738
+ * await db.users.updateById(userId, {
739
+ * $set: { name: "New Name" },
740
+ * $push: { tags: "premium" }
741
+ * });
742
+ * ```
743
+ */
744
+ updateById(id: ObjectId | string, data: Document, options?: UpdateOptions): Promise<UpdateResult>;
745
+ /**
746
+ * Delete a single document matching the filter.
747
+ *
748
+ * @param where - MongoDB filter query
749
+ * @param options - Delete options (session)
750
+ * @returns Delete result with deletedCount
751
+ *
752
+ * @example
753
+ * ```typescript
754
+ * // Delete by email
755
+ * await db.users.deleteOne({ email: "john@example.com" });
756
+ *
757
+ * // With session (for transactions)
758
+ * await db.users.deleteOne({ _id: userId }, { session });
759
+ * ```
760
+ */
761
+ deleteOne(where: Filter<Document>, options?: DeleteOptions): Promise<DeleteResult>;
762
+ /**
763
+ * Delete multiple documents matching the filter.
764
+ *
765
+ * @param where - MongoDB filter query
766
+ * @param options - Delete options (session)
767
+ * @returns Delete result with deletedCount
768
+ *
769
+ * @example
770
+ * ```typescript
771
+ * // Delete all inactive users
772
+ * const result = await db.users.deleteMany({ isActive: false });
773
+ * console.log(`Deleted ${result.deletedCount} users`);
774
+ *
775
+ * // Delete users created before a date
776
+ * await db.users.deleteMany({
777
+ * createdAt: { $lt: new Date("2023-01-01") }
778
+ * });
779
+ * ```
780
+ */
781
+ deleteMany(where: Filter<Document>, options?: DeleteOptions): Promise<DeleteResult>;
782
+ /**
783
+ * Delete a document by its _id.
784
+ *
785
+ * @param id - ObjectId or string representation
786
+ * @param options - Delete options (session)
787
+ * @returns Delete result with deletedCount
788
+ *
789
+ * @example
790
+ * ```typescript
791
+ * await db.users.deleteById("507f1f77bcf86cd799439011");
792
+ * await db.users.deleteById(userId, { session });
793
+ * ```
794
+ */
795
+ deleteById(id: ObjectId | string, options?: DeleteOptions): Promise<DeleteResult>;
796
+ /**
797
+ * Count documents matching the filter.
798
+ *
799
+ * @param where - MongoDB filter query (optional)
800
+ * @param options - Count options (limit, skip, session)
801
+ * @returns Number of matching documents
802
+ *
803
+ * @example
804
+ * ```typescript
805
+ * // Count all users
806
+ * const total = await db.users.count();
807
+ *
808
+ * // Count active users
809
+ * const activeCount = await db.users.count({ isActive: true });
810
+ *
811
+ * // Count with limit (for existence check optimization)
812
+ * const hasAdmins = await db.users.count({ role: "ADMIN" }, { limit: 1 }) > 0;
813
+ * ```
814
+ */
815
+ count(where?: Filter<Document>, options?: CountDocumentsOptions): Promise<number>;
816
+ /**
817
+ * Check if any document matches the filter.
818
+ * Optimized to stop after finding first match.
819
+ *
820
+ * @param where - MongoDB filter query
821
+ * @param options - Count options (session)
822
+ * @returns true if at least one document matches
823
+ *
824
+ * @example
825
+ * ```typescript
826
+ * // Check if email is taken
827
+ * const emailTaken = await db.users.exists({ email: "john@example.com" });
828
+ *
829
+ * // Check if user has admin role
830
+ * const isAdmin = await db.users.exists({ _id: userId, role: "ADMIN" });
831
+ * ```
832
+ */
833
+ exists(where: Filter<Document>, options?: CountDocumentsOptions): Promise<boolean>;
834
+ /**
835
+ * Run an aggregation pipeline.
836
+ * Provides full access to MongoDB aggregation framework.
837
+ *
838
+ * @param pipeline - Array of aggregation stages
839
+ * @param options - Aggregation options (allowDiskUse, session)
840
+ * @returns Array of aggregation results
841
+ *
842
+ * @example
843
+ * ```typescript
844
+ * // Group users by role and count
845
+ * const stats = await db.users.aggregate([
846
+ * { $match: { isActive: true } },
847
+ * { $group: { _id: "$role", count: { $sum: 1 } } },
848
+ * { $sort: { count: -1 } }
849
+ * ]);
850
+ *
851
+ * // Lookup related documents
852
+ * const usersWithPosts = await db.users.aggregate([
853
+ * { $lookup: {
854
+ * from: "posts",
855
+ * localField: "_id",
856
+ * foreignField: "authorId",
857
+ * as: "posts"
858
+ * }}
859
+ * ]);
860
+ *
861
+ * // With options
862
+ * const bigResult = await db.users.aggregate(pipeline, {
863
+ * allowDiskUse: true
864
+ * });
865
+ * ```
866
+ */
867
+ aggregate(pipeline: Document[], options?: AggregateOptions): Promise<Document[]>;
868
+ /**
869
+ * Get the underlying MongoDB Collection instance.
870
+ * Use for advanced operations not covered by the proxy.
871
+ *
872
+ * @returns MongoDB Collection instance
873
+ *
874
+ * @example
875
+ * ```typescript
876
+ * const collection = db.users.getCollection();
877
+ *
878
+ * // Use for watch, bulkWrite, or other advanced operations
879
+ * const changeStream = collection.watch();
880
+ * ```
881
+ */
882
+ getCollection(): Collection<Document>;
883
+ private applyTimestamps;
884
+ private parseObjectId;
885
+ private applyUpdateTimestamps;
886
+ }
887
+
888
+ export { type AggregateOpts, type ClientConfig, CollectionProxy, type CompoundIndexDefinition, type CountOptions, type CreateInput, type CreateManyOptions, type CreateOptions, type DeleteOptions, type FieldDefinition, type FindOptions, type IndexOptions, type InferSchemaType, type NodeClientConfig, type Schema, type SchemaDefinition, type SchemasToClient, type SelectInput, type ServerlessClientConfig, type SortInput, type TimestampConfig, type UpdateInput, type UpdateOptions, type ValidationConfig, type WhereInput, createClient, defineSchema, s, schema, validate, zodCreateSchema, zodSchema, zodUpdateSchema };