modelence 0.7.0-dev.6 → 0.7.1

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.
@@ -1,7 +1,7 @@
1
1
  import './index-CwdohC5n.js';
2
2
  import { P as Permission, d as Session, e as UserInfo } from './types-Ds1ESQSs.js';
3
3
  import * as mongodb from 'mongodb';
4
- import { WithId, IndexDescription, SearchIndexDescription, MongoClient, Collection, Filter, FindOptions, ObjectId, Document, OptionalUnlessRequiredId, InsertOneResult, InsertManyResult, UpdateFilter, UpdateResult, ClientSession, DeleteResult, AggregateOptions, AggregationCursor, AnyBulkWriteOperation, BulkWriteResult } from 'mongodb';
4
+ import { WithId, IndexDescription, SearchIndexDescription, MongoClient, Collection, FilterOperators, Document, FindOptions, ObjectId, OptionalUnlessRequiredId, InsertOneResult, InsertManyResult, UpdateFilter, UpdateResult, ClientSession, DeleteResult, AggregateOptions, AggregationCursor, AnyBulkWriteOperation, BulkWriteResult } from 'mongodb';
5
5
  import { z, ZodNumber, ZodArray } from 'zod';
6
6
  import { Request, Response, NextFunction } from 'express';
7
7
 
@@ -137,6 +137,72 @@ type SerializedSchema = BaseSerializedSchema | (BaseSerializedSchema & {
137
137
  optional: true;
138
138
  });
139
139
 
140
+ /**
141
+ * Top-level query operators (logical and evaluation) - custom version without Document index signature
142
+ * Based on MongoDB's RootFilterOperators but without the [key: string]: any from Document
143
+ * @internal
144
+ */
145
+ type StrictRootFilterOperators<TSchema> = {
146
+ $and?: TypedFilter<TSchema>[];
147
+ $or?: TypedFilter<TSchema>[];
148
+ $nor?: TypedFilter<TSchema>[];
149
+ $not?: TypedFilter<TSchema>;
150
+ $text?: {
151
+ $search: string;
152
+ $language?: string;
153
+ $caseSensitive?: boolean;
154
+ $diacriticSensitive?: boolean;
155
+ };
156
+ $where?: string | ((this: TSchema) => boolean);
157
+ $comment?: string | Document;
158
+ $expr?: any;
159
+ $jsonSchema?: any;
160
+ };
161
+ /**
162
+ * Type-safe MongoDB filter that ensures only schema fields can be queried
163
+ * while supporting all MongoDB query operators and dot notation for nested fields.
164
+ *
165
+ * This type combines:
166
+ * - MongoDB's native `FilterOperators<T>` for field-level operators (comprehensive operator support)
167
+ * - Custom `StrictRootFilterOperators<T>` for top-level operators without index signature
168
+ * - Custom restriction: only strings containing dots are allowed for nested field queries
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * const dbUsers = new Store('users', {
173
+ * schema: {
174
+ * name: schema.string(),
175
+ * age: schema.number(),
176
+ * tags: schema.array(schema.string()),
177
+ * address: schema.object({
178
+ * street: schema.string(),
179
+ * city: schema.string(),
180
+ * }),
181
+ * },
182
+ * indexes: []
183
+ * });
184
+ *
185
+ * // ✅ Valid - field exists in schema
186
+ * await dbUsers.findOne({ name: 'John' });
187
+ *
188
+ * // ✅ Valid - using MongoDB operators (from FilterOperators)
189
+ * await dbUsers.findOne({ age: { $gt: 18 } });
190
+ * await dbUsers.findOne({ tags: { $in: ['typescript', 'mongodb'] } });
191
+ * await dbUsers.findOne({ $or: [{ name: 'John' }, { name: 'Jane' }] });
192
+ *
193
+ * // ✅ Valid - dot notation for nested fields (must contain a dot)
194
+ * await dbUsers.findOne({ 'address.city': 'New York' });
195
+ * await dbUsers.findOne({ 'emails.0.address': 'test@example.com' });
196
+ *
197
+ * // ❌ TypeScript error - 'id' is not in schema and doesn't contain a dot
198
+ * await dbUsers.findOne({ id: '123' });
199
+ * ```
200
+ */
201
+ type TypedFilter<T> = {
202
+ [K in keyof WithId<T>]?: WithId<T>[K] | FilterOperators<WithId<T>[K]>;
203
+ } & StrictRootFilterOperators<T> & {
204
+ [K: DottedString]: any;
205
+ };
140
206
  /**
141
207
  * Helper type to preserve method types when extending a store.
142
208
  * Maps each method to work with the extended schema while preserving signatures.
@@ -257,8 +323,29 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
257
323
  requireCollection(): Collection<this["_type"]>;
258
324
  /** @internal */
259
325
  requireClient(): MongoClient;
260
- findOne(query: Filter<this['_type']>, options?: FindOptions): Promise<this["_doc"] | null>;
261
- requireOne(query: Filter<this['_type']>, options?: FindOptions, errorHandler?: () => Error): Promise<this['_doc']>;
326
+ /**
327
+ * Finds a single document matching the query
328
+ *
329
+ * @param query - Type-safe query filter. Only schema fields, MongoDB operators, and dot notation are allowed.
330
+ * @param options - Find options
331
+ * @returns The document, or null if not found
332
+ *
333
+ * @example
334
+ * ```ts
335
+ * // ✅ Valid queries:
336
+ * await store.findOne({ name: 'John' })
337
+ * await store.findOne({ age: { $gt: 18 } })
338
+ * await store.findOne({ _id: new ObjectId('...') })
339
+ * await store.findOne({ tags: { $in: ['typescript', 'mongodb'] } })
340
+ * await store.findOne({ $or: [{ name: 'John' }, { name: 'Jane' }] })
341
+ * await store.findOne({ 'emails.address': 'test@example.com' }) // dot notation
342
+ *
343
+ * // ❌ TypeScript error - 'id' is not in schema:
344
+ * await store.findOne({ id: '123' })
345
+ * ```
346
+ */
347
+ findOne(query: TypedFilter<this['_type']>, options?: FindOptions): Promise<this["_doc"] | null>;
348
+ requireOne(query: TypedFilter<this['_type']>, options?: FindOptions, errorHandler?: () => Error): Promise<this['_doc']>;
262
349
  private find;
263
350
  /**
264
351
  * Fetches a single document by its ID
@@ -281,7 +368,7 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
281
368
  * @param query - The query to filter documents
282
369
  * @returns The number of documents that match the query
283
370
  */
284
- countDocuments(query: Filter<this['_type']>): Promise<number>;
371
+ countDocuments(query: TypedFilter<this['_type']>): Promise<number>;
285
372
  /**
286
373
  * Fetches multiple documents, equivalent to Node.js MongoDB driver's `find` and `toArray` methods combined.
287
374
  *
@@ -289,7 +376,7 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
289
376
  * @param options - Options
290
377
  * @returns The documents
291
378
  */
292
- fetch(query: Filter<this['_type']>, options?: {
379
+ fetch(query: TypedFilter<this['_type']>, options?: {
293
380
  sort?: Document;
294
381
  limit?: number;
295
382
  skip?: number;
@@ -315,7 +402,7 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
315
402
  * @param update - The update to apply to the document
316
403
  * @returns The result of the update operation
317
404
  */
318
- updateOne(selector: Filter<this['_type']> | string | ObjectId, update: UpdateFilter<this['_type']>): Promise<UpdateResult>;
405
+ updateOne(selector: TypedFilter<this['_type']> | string | ObjectId, update: UpdateFilter<this['_type']>): Promise<UpdateResult>;
319
406
  /**
320
407
  * Updates a single document, or inserts it if it doesn't exist
321
408
  *
@@ -323,7 +410,7 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
323
410
  * @param update - The MongoDB modifier to apply to the document
324
411
  * @returns The result of the update operation
325
412
  */
326
- upsertOne(selector: Filter<this['_type']> | string | ObjectId, update: UpdateFilter<this['_type']>): Promise<UpdateResult>;
413
+ upsertOne(selector: TypedFilter<this['_type']> | string | ObjectId, update: UpdateFilter<this['_type']>): Promise<UpdateResult>;
327
414
  /**
328
415
  * Updates multiple documents
329
416
  *
@@ -331,7 +418,7 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
331
418
  * @param update - The MongoDB modifier to apply to the documents
332
419
  * @returns The result of the update operation
333
420
  */
334
- updateMany(selector: Filter<this['_type']>, update: UpdateFilter<this['_type']>, options?: {
421
+ updateMany(selector: TypedFilter<this['_type']>, update: UpdateFilter<this['_type']>, options?: {
335
422
  session?: ClientSession;
336
423
  }): Promise<UpdateResult>;
337
424
  /**
@@ -341,21 +428,21 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
341
428
  * @param update - The MongoDB modifier to apply to the documents
342
429
  * @returns The result of the update operation
343
430
  */
344
- upsertMany(selector: Filter<this['_type']>, update: UpdateFilter<this['_type']>): Promise<UpdateResult>;
431
+ upsertMany(selector: TypedFilter<this['_type']>, update: UpdateFilter<this['_type']>): Promise<UpdateResult>;
345
432
  /**
346
433
  * Deletes a single document
347
434
  *
348
435
  * @param selector - The selector to find the document to delete
349
436
  * @returns The result of the delete operation
350
437
  */
351
- deleteOne(selector: Filter<this['_type']>): Promise<DeleteResult>;
438
+ deleteOne(selector: TypedFilter<this['_type']>): Promise<DeleteResult>;
352
439
  /**
353
440
  * Deletes multiple documents
354
441
  *
355
442
  * @param selector - The selector to find the documents to delete
356
443
  * @returns The result of the delete operation
357
444
  */
358
- deleteMany(selector: Filter<this['_type']>): Promise<DeleteResult>;
445
+ deleteMany(selector: TypedFilter<this['_type']>): Promise<DeleteResult>;
359
446
  /**
360
447
  * Aggregates documents using MongoDB's aggregation framework
361
448
  *
@@ -519,6 +606,7 @@ type RouteParams<T = unknown> = {
519
606
  params: Record<string, string>;
520
607
  headers: Record<string, string>;
521
608
  cookies: Record<string, string>;
609
+ rawBody?: Buffer;
522
610
  req: Request;
523
611
  res: Response;
524
612
  next: NextFunction;
@@ -533,11 +621,25 @@ type RouteHandler<T = unknown> = (params: RouteParams, context: Pick<Context, 's
533
621
  type RouteHandlers = {
534
622
  [key in HttpMethod]?: RouteHandler;
535
623
  };
624
+ type BodyConfig = {
625
+ json?: boolean | {
626
+ limit?: string;
627
+ };
628
+ urlencoded?: boolean | {
629
+ limit?: string;
630
+ extended?: boolean;
631
+ };
632
+ raw?: boolean | {
633
+ limit?: string;
634
+ type?: string | string[];
635
+ };
636
+ };
536
637
  type RouteDefinition = {
537
638
  path: string;
538
639
  handlers: RouteHandlers;
539
640
  errorHandler?: RouteHandler;
641
+ body?: BodyConfig;
540
642
  };
541
643
  type ExpressHandler = (req: Request, res: Response) => Promise<void> | void;
542
644
 
543
- export { type Args as A, type CronJobInputParams as C, type EmailProvider as E, type HttpMethod as H, type InferDocumentType as I, type MethodDefinition as M, type RouteDefinition as R, Store as S, type RateLimitRule as a, type ConnectionInfo as b, type RateLimitType as c, type EmailPayload as d, type RouteHandler as e, type RouteParams as f, type RouteResponse as g, type EmailAttachment as h, type ClientInfo as i, type Context as j, type Handler as k, type MethodType as l, type Method as m, type CronJob as n, type CronJobMetadata as o, type ModelSchema as p, type RouteHandlers as q, type ExpressHandler as r, schema as s };
645
+ export { type Args as A, type BodyConfig as B, type CronJobInputParams as C, type EmailProvider as E, type HttpMethod as H, type InferDocumentType as I, type MethodDefinition as M, type RouteDefinition as R, Store as S, type RateLimitRule as a, type ConnectionInfo as b, type RateLimitType as c, type EmailPayload as d, type RouteHandler as e, type RouteParams as f, type RouteResponse as g, type EmailAttachment as h, type ClientInfo as i, type Context as j, type Handler as k, type MethodType as l, type Method as m, type CronJob as n, type CronJobMetadata as o, type ModelSchema as p, type RouteHandlers as q, type ExpressHandler as r, schema as s };
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { A as AppServer, E as ExpressMiddleware, M as ModelenceConfig } from './index-CwdohC5n.js';
2
- export { A as Args, i as ClientInfo, b as ConnectionInfo, j as Context, n as CronJob, C as CronJobInputParams, o as CronJobMetadata, h as EmailAttachment, d as EmailPayload, E as EmailProvider, r as ExpressHandler, k as Handler, H as HttpMethod, I as InferDocumentType, m as Method, M as MethodDefinition, l as MethodType, p as ModelSchema, a as RateLimitRule, c as RateLimitType, R as RouteDefinition, e as RouteHandler, q as RouteHandlers, f as RouteParams, g as RouteResponse, s as schema } from './types-D6nwUab6.js';
2
+ export { A as Args, B as BodyConfig, i as ClientInfo, b as ConnectionInfo, j as Context, n as CronJob, C as CronJobInputParams, o as CronJobMetadata, h as EmailAttachment, d as EmailPayload, E as EmailProvider, r as ExpressHandler, k as Handler, H as HttpMethod, I as InferDocumentType, m as Method, M as MethodDefinition, l as MethodType, p as ModelSchema, a as RateLimitRule, c as RateLimitType, R as RouteDefinition, e as RouteHandler, q as RouteHandlers, f as RouteParams, g as RouteResponse, s as schema } from './types-WgRbQ-tj.js';
3
3
  export { A as AppConfig, b as ConfigKey, C as ConfigSchema, g as ConfigType, h as Configs, D as DefaultRoles, P as Permission, f as Role, R as RoleDefinition, d as Session, U as User, e as UserInfo, a as WebsocketClientProvider, W as WebsocketServerProvider } from './types-Ds1ESQSs.js';
4
4
  import 'express';
5
5
  import 'mongodb';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "modelence",
4
- "version": "0.7.0-dev.6",
4
+ "version": "0.7.1",
5
5
  "description": "The Node.js Framework for Real-Time MongoDB Apps",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/global.d.ts",
@@ -1,3 +0,0 @@
1
- var s="module",i="modelence",o="0.7.0-dev.6",r="The Node.js Framework for Real-Time MongoDB Apps",n="dist/index.js",p="dist/global.d.ts",c={".":"./dist/index.js","./client":"./dist/client.js","./server":"./dist/server.js","./telemetry":"./dist/telemetry.js","./mongodb":"./dist/mongo.js","./types":{types:"./dist/types.d.ts",default:"./dist/types.js"}},d=["dist","dist/bin"],l={modelence:"./dist/bin/modelence.js"},m={build:"tsup",dev:"tsup --watch",format:'prettier --write "src/**/*.{ts,tsx,js,jsx,json,css,md}"',"format:check":'prettier --check "src/**/*.{ts,tsx,js,jsx,json,css,md}"',lint:"eslint src --ext .ts,.tsx --fix","lint:check":"eslint src --ext .ts,.tsx",prepublishOnly:"npm run build",test:"NODE_OPTIONS=--experimental-vm-modules jest","test:watch":"NODE_OPTIONS=--experimental-vm-modules jest --watch","test:coverage":"NODE_OPTIONS=--experimental-vm-modules jest --coverage",postversion:"git push && git push --tags"},a={type:"git",url:"git+https://github.com/modelence/modelence.git"},y="Modelence",u="SEE LICENSE IN LICENSE",j={url:"https://github.com/modelence/modelence/issues"},g="https://modelence.com",h={"@types/archiver":"^6.0.3","@types/bcrypt":"^5.0.2","@types/cookie-parser":"^1.4.9","@types/express":"^5.0.0","@types/fs-extra":"^11.0.4","@types/jest":"^30.0.0","@types/node":"^22.5.1","@types/react":"^19.0.0","@types/react-dom":"^19.0.1","@types/socket.io":"^3.0.1","@typescript-eslint/eslint-plugin":"^8.17.0","@typescript-eslint/parser":"^8.17.0",eslint:"^9.37.0",jest:"^30.2.0",prettier:"^3.6.2",react:"^19.0.0","react-dom":"^19.0.0","ts-jest":"^29.4.5","ts-node":"^10.9.2"},x={"@socket.io/mongo-adapter":"^0.4.0","@vitejs/plugin-react":"^4.3.4",archiver:"^7.0.1",bcrypt:"^5.1.1",commander:"^12.0.0","cookie-parser":"^1.4.7",dotenv:"^16.4.5","elastic-apm-node":"^4.8.0",express:"^4.21.0","fs-extra":"^11.2.0",jiti:"^2.4.2",mongodb:"^6.8.1",open:"^10.1.0","socket.io":"^4.8.1","socket.io-client":"^4.8.1",tsup:"^8.3.6",tsx:"^4.19.3",typescript:"^5.7.2",vite:"^6.0.3","vite-plugin-eslint":"^1.8.1",winston:"^3.15.0","winston-elasticsearch":"^0.19.0",zod:"^3.23.8",zustand:"^5.0.2"},v={react:">=18.0.0","react-dom":">=18.0.0"},b={type:s,name:i,version:o,description:r,main:n,types:p,exports:c,files:d,bin:l,scripts:m,repository:a,author:y,license:u,bugs:j,homepage:g,devDependencies:h,dependencies:x,peerDependencies:v};
2
- export{s as a,i as b,o as c,r as d,n as e,p as f,c as g,d as h,l as i,m as j,a as k,y as l,u as m,j as n,g as o,h as p,x as q,v as r,b as s};//# sourceMappingURL=chunk-33DVBH5R.js.map
3
- //# sourceMappingURL=chunk-33DVBH5R.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../package.json"],"names":["type","name","version","description","main","types","exports","files","bin","scripts","repository","author","license","bugs","homepage","devDependencies","dependencies","peerDependencies","package_default"],"mappings":"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","file":"chunk-33DVBH5R.js","sourcesContent":["{\n \"type\": \"module\",\n \"name\": \"modelence\",\n \"version\": \"0.7.0-dev.6\",\n \"description\": \"The Node.js Framework for Real-Time MongoDB Apps\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/global.d.ts\",\n \"exports\": {\n \".\": \"./dist/index.js\",\n \"./client\": \"./dist/client.js\",\n \"./server\": \"./dist/server.js\",\n \"./telemetry\": \"./dist/telemetry.js\",\n \"./mongodb\": \"./dist/mongo.js\",\n \"./types\": {\n \"types\": \"./dist/types.d.ts\",\n \"default\": \"./dist/types.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"dist/bin\"\n ],\n \"bin\": {\n \"modelence\": \"./dist/bin/modelence.js\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"format\": \"prettier --write \\\"src/**/*.{ts,tsx,js,jsx,json,css,md}\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.{ts,tsx,js,jsx,json,css,md}\\\"\",\n \"lint\": \"eslint src --ext .ts,.tsx --fix\",\n \"lint:check\": \"eslint src --ext .ts,.tsx\",\n \"prepublishOnly\": \"npm run build\",\n \"test\": \"NODE_OPTIONS=--experimental-vm-modules jest\",\n \"test:watch\": \"NODE_OPTIONS=--experimental-vm-modules jest --watch\",\n \"test:coverage\": \"NODE_OPTIONS=--experimental-vm-modules jest --coverage\",\n \"postversion\": \"git push && git push --tags\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/modelence/modelence.git\"\n },\n \"author\": \"Modelence\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"bugs\": {\n \"url\": \"https://github.com/modelence/modelence/issues\"\n },\n \"homepage\": \"https://modelence.com\",\n \"devDependencies\": {\n \"@types/archiver\": \"^6.0.3\",\n \"@types/bcrypt\": \"^5.0.2\",\n \"@types/cookie-parser\": \"^1.4.9\",\n \"@types/express\": \"^5.0.0\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/jest\": \"^30.0.0\",\n \"@types/node\": \"^22.5.1\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.1\",\n \"@types/socket.io\": \"^3.0.1\",\n \"@typescript-eslint/eslint-plugin\": \"^8.17.0\",\n \"@typescript-eslint/parser\": \"^8.17.0\",\n \"eslint\": \"^9.37.0\",\n \"jest\": \"^30.2.0\",\n \"prettier\": \"^3.6.2\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"ts-jest\": \"^29.4.5\",\n \"ts-node\": \"^10.9.2\"\n },\n \"dependencies\": {\n \"@socket.io/mongo-adapter\": \"^0.4.0\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"archiver\": \"^7.0.1\",\n \"bcrypt\": \"^5.1.1\",\n \"commander\": \"^12.0.0\",\n \"cookie-parser\": \"^1.4.7\",\n \"dotenv\": \"^16.4.5\",\n \"elastic-apm-node\": \"^4.8.0\",\n \"express\": \"^4.21.0\",\n \"fs-extra\": \"^11.2.0\",\n \"jiti\": \"^2.4.2\",\n \"mongodb\": \"^6.8.1\",\n \"open\": \"^10.1.0\",\n \"socket.io\": \"^4.8.1\",\n \"socket.io-client\": \"^4.8.1\",\n \"tsup\": \"^8.3.6\",\n \"tsx\": \"^4.19.3\",\n \"typescript\": \"^5.7.2\",\n \"vite\": \"^6.0.3\",\n \"vite-plugin-eslint\": \"^1.8.1\",\n \"winston\": \"^3.15.0\",\n \"winston-elasticsearch\": \"^0.19.0\",\n \"zod\": \"^3.23.8\",\n \"zustand\": \"^5.0.2\"\n },\n \"peerDependencies\": {\n \"react\": \">=18.0.0\",\n \"react-dom\": \">=18.0.0\"\n }\n}\n"]}