@classytic/mongokit 3.5.4 → 3.5.6

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.
Files changed (29) hide show
  1. package/README.md +228 -9
  2. package/dist/{PaginationEngine-DCs-zKwZ.mjs → PaginationEngine-CpsQl471.mjs} +5 -3
  3. package/dist/actions/index.d.mts +1 -1
  4. package/dist/ai/index.d.mts +1 -1
  5. package/dist/coercion-B19MD38s.d.mts +106 -0
  6. package/dist/id-resolution-LZ-cCwR5.mjs +81 -0
  7. package/dist/{index-BNpVzw_-.d.mts → index-DmVbUzDL.d.mts} +1 -1
  8. package/dist/index.d.mts +84 -6
  9. package/dist/index.mjs +101 -36
  10. package/dist/indexes-qIBCZ3mY.d.mts +41 -0
  11. package/dist/{mongooseToJsonSchema-DpjhFfaO.mjs → mongooseToJsonSchema-8Cyu3NFJ.mjs} +50 -45
  12. package/dist/{mongooseToJsonSchema-Dsx3YAAx.d.mts → mongooseToJsonSchema-DQMU0Dlv.d.mts} +4 -3
  13. package/dist/pagination/PaginationEngine.d.mts +1 -1
  14. package/dist/pagination/PaginationEngine.mjs +1 -1
  15. package/dist/plugins/index.d.mts +1 -1
  16. package/dist/plugins/index.mjs +1 -1
  17. package/dist/query/primitives/coercion.d.mts +2 -0
  18. package/dist/query/primitives/coercion.mjs +148 -0
  19. package/dist/query/primitives/geo.d.mts +116 -0
  20. package/dist/query/primitives/geo.mjs +211 -0
  21. package/dist/query/primitives/indexes.d.mts +2 -0
  22. package/dist/query/primitives/indexes.mjs +46 -0
  23. package/dist/{types-CkE3mOaW.d.mts → types-BwO4u3JN.d.mts} +25 -0
  24. package/dist/utils/index.d.mts +60 -3
  25. package/dist/utils/index.mjs +4 -3
  26. package/dist/{validation-chain.plugin-BYMZB8dN.d.mts → validation-chain.plugin-BtmT-FFB.d.mts} +1 -1
  27. package/dist/{validation-chain.plugin-KjPV_6_N.mjs → validation-chain.plugin-DCYjnPau.mjs} +81 -20
  28. package/package.json +15 -3
  29. /package/dist/{field-selection-reyDRzXf.mjs → field-selection-C5o7jyyA.mjs} +0 -0
package/dist/index.d.mts CHANGED
@@ -1,8 +1,10 @@
1
- import { $ as ReadPreferenceType, A as InferDocument, At as LookupOptions, B as NonNullableFields, C as EventPayload, Ct as WithPlugins, D as GroupResult, Dt as IRequestContext, E as FieldRules, Et as IControllerResponse, F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, I as Logger, J as Plugin, K as PaginationResult, L as LookupPopulateOptions, M as JsonSchema, N as KeysOfType, O as HookMode, Ot as IResponseFormatter, P as KeysetPaginationOptions, Q as ReadOptions, R as LookupPopulateResult, S as EventHandlers, St as ValidatorDefinition, T as FieldPreset, Tt as IController, U as OffsetPaginationResult, V as ObjectId, W as OperationOptions, X as PluginType, Y as PluginFunction, Z as PopulateSpec, _ as CrudSchemas, _t as UpdateOptions, a as AnyDocument, at as RequiredBy, b as DeleteResult, bt as ValidationChainOptions, c as CacheOperationOptions, ct as SessionOptions, d as CacheableOptions, dt as SoftDeleteRepository, et as RepositoryContext, f as CascadeOptions, ft as SortDirection, g as CreateOptions, gt as UpdateManyResult, h as CreateInput, ht as UpdateInput, i as AllPluginMethods, it as RepositoryOptions, j as InferRawDoc, k as HttpError, kt as LookupBuilder, l as CacheOptions, lt as SoftDeleteFilterMode, m as CollationOptions, mt as Strict, n as AggregatePaginationOptions, nt as RepositoryInstance, o as AnyModel, ot as SchemaBuilderOptions, p as CascadeRelation, pt as SortSpec, q as PartialBy, r as AggregatePaginationResult, rt as RepositoryOperation, s as CacheAdapter, st as SelectSpec, t as AggregateOptions, tt as RepositoryEvent, u as CacheStats, ut as SoftDeleteOptions, v as DecodedCursor, vt as UpdateWithValidationResult, w as EventPhase, wt as WithTransactionOptions, x as DocField, xt as ValidationResult, y as DeepPartial, yt as UserContext, z as MinMaxResult } from "./types-CkE3mOaW.mjs";
2
- import { t as index_d_exports } from "./index-BNpVzw_-.mjs";
1
+ import { $ as ReadPreferenceType, A as InferDocument, At as LookupOptions, B as NonNullableFields, C as EventPayload, Ct as WithPlugins, D as GroupResult, Dt as IRequestContext, E as FieldRules, Et as IControllerResponse, F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, I as Logger, J as Plugin, K as PaginationResult, L as LookupPopulateOptions, M as JsonSchema, N as KeysOfType, O as HookMode, Ot as IResponseFormatter, P as KeysetPaginationOptions, Q as ReadOptions, R as LookupPopulateResult, S as EventHandlers, St as ValidatorDefinition, T as FieldPreset, Tt as IController, U as OffsetPaginationResult, V as ObjectId, W as OperationOptions, X as PluginType, Y as PluginFunction, Z as PopulateSpec, _ as CrudSchemas, _t as UpdateOptions, a as AnyDocument, at as RequiredBy, b as DeleteResult, bt as ValidationChainOptions, c as CacheOperationOptions, ct as SessionOptions, d as CacheableOptions, dt as SoftDeleteRepository, et as RepositoryContext, f as CascadeOptions, ft as SortDirection, g as CreateOptions, gt as UpdateManyResult, h as CreateInput, ht as UpdateInput, i as AllPluginMethods, it as RepositoryOptions, j as InferRawDoc, k as HttpError, kt as LookupBuilder, l as CacheOptions, lt as SoftDeleteFilterMode, m as CollationOptions, mt as Strict, n as AggregatePaginationOptions, nt as RepositoryInstance, o as AnyModel, ot as SchemaBuilderOptions, p as CascadeRelation, pt as SortSpec, q as PartialBy, r as AggregatePaginationResult, rt as RepositoryOperation, s as CacheAdapter, st as SelectSpec, t as AggregateOptions, tt as RepositoryEvent, u as CacheStats, ut as SoftDeleteOptions, v as DecodedCursor, vt as UpdateWithValidationResult, w as EventPhase, wt as WithTransactionOptions, x as DocField, xt as ValidationResult, y as DeepPartial, yt as UserContext, z as MinMaxResult } from "./types-BwO4u3JN.mjs";
2
+ import { t as index_d_exports } from "./index-DmVbUzDL.mjs";
3
3
  import { PaginationEngine } from "./pagination/PaginationEngine.mjs";
4
- import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, R as BulkWriteResult, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, z as batchOperationsPlugin } from "./validation-chain.plugin-BYMZB8dN.mjs";
5
- import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, m as parseDuplicateKeyError, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "./mongooseToJsonSchema-Dsx3YAAx.mjs";
4
+ import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, R as BulkWriteResult, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, z as batchOperationsPlugin } from "./validation-chain.plugin-BtmT-FFB.mjs";
5
+ import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-B19MD38s.mjs";
6
+ import { n as SchemaIndexes } from "./indexes-qIBCZ3mY.mjs";
7
+ import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, m as parseDuplicateKeyError, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "./mongooseToJsonSchema-DQMU0Dlv.mjs";
6
8
  import * as _$mongoose from "mongoose";
7
9
  import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
8
10
 
@@ -487,6 +489,22 @@ interface ParsedQuery {
487
489
  }
488
490
  /** Search mode for query parser */
489
491
  type SearchMode = 'text' | 'regex';
492
+ /**
493
+ * Normalized field type used for schema-aware value coercion. Re-exported
494
+ * from `primitives/coercion` so the public QueryParser API stays unchanged
495
+ * while the actual logic lives in a single, unit-tested primitive module.
496
+ */
497
+ type FieldType = FieldType$1;
498
+ /**
499
+ * Minimal structural type for a Mongoose schema. We only read `.paths` and
500
+ * (optionally) `.indexes()`, so the parser stays decoupled from a specific
501
+ * Mongoose major version and is easy to mock in tests. Re-exported from the
502
+ * primitives module — the canonical definition lives there.
503
+ */
504
+ interface SchemaLike extends SchemaPathsLike {
505
+ /** Optional — when present, schema indexes are introspected for geo/text fields */
506
+ indexes?: () => Array<[Record<string, unknown>, Record<string, unknown>?]>;
507
+ }
490
508
  interface QueryParserOptions {
491
509
  /** Maximum allowed regex pattern length (default: 500) */
492
510
  maxRegexLength?: number;
@@ -534,6 +552,25 @@ interface QueryParserOptions {
534
552
  * @example ['eq', 'ne', 'gt', 'gte', 'lt', 'lte', 'in']
535
553
  */
536
554
  allowedOperators?: string[];
555
+ /**
556
+ * Mongoose schema (or schema-like object exposing `.paths`) used for
557
+ * authoritative, schema-aware value coercion. When provided, filter values
558
+ * are coerced to the declared field type instead of guessed from the
559
+ * string shape — `?stock=50` becomes a number against a `Number` field but
560
+ * `?name=12345` stays a string against a `String` field. Nested paths like
561
+ * `address.zip` are looked up via dot-notation, matching Mongoose's
562
+ * `schema.paths` reflection. Unknown fields fall through to the heuristic.
563
+ */
564
+ schema?: SchemaLike;
565
+ /**
566
+ * Plain field-type map used for authoritative coercion when no Mongoose
567
+ * schema is available (raw MongoDB, Prisma, computed fields, upstream
568
+ * models you don't own). Takes precedence over `schema` for paths declared
569
+ * in both — useful for runtime overrides. Use dot-notation for nested
570
+ * paths (`'address.zip': 'string'`).
571
+ * @example { stock: 'number', active: 'boolean', releasedAt: 'date' }
572
+ */
573
+ fieldTypes?: Record<string, FieldType>;
537
574
  }
538
575
  /**
539
576
  * Modern Query Parser
@@ -543,6 +580,21 @@ declare class QueryParser {
543
580
  private readonly options;
544
581
  private readonly operators;
545
582
  private readonly dangerousOperators;
583
+ /**
584
+ * Normalized dot-notation field-type map. Built once at construction from
585
+ * `options.schema` (Mongoose) and `options.fieldTypes` (override map), with
586
+ * `fieldTypes` taking precedence. An empty map means schema-aware coercion
587
+ * is disabled and the heuristic in `_convertValue` runs unchanged — this
588
+ * preserves backwards compatibility for callers that don't opt in.
589
+ */
590
+ private readonly _fieldTypes;
591
+ /**
592
+ * Structured schema-index info (geo / text / other), built once from
593
+ * `options.schema?.indexes()`. Used by the operator router to validate
594
+ * geo operators against actual geo-indexed fields, and exposed publicly
595
+ * via `parser.schemaIndexes` for downstream tools (Arc MCP, query planners).
596
+ */
597
+ private readonly _schemaIndexes;
546
598
  /**
547
599
  * Regex patterns that can cause catastrophic backtracking (ReDoS attacks)
548
600
  * Detects:
@@ -554,6 +606,16 @@ declare class QueryParser {
554
606
  */
555
607
  private readonly dangerousRegexPatterns;
556
608
  constructor(options?: QueryParserOptions);
609
+ /**
610
+ * Structured view of the configured schema's indexes — geo fields, text
611
+ * fields, and other compound indexes. Empty arrays when no schema was
612
+ * provided. Stable across the parser's lifetime; mutating the returned
613
+ * object does not affect parser behavior.
614
+ *
615
+ * Useful for downstream tooling (Arc MCP, query planners, doc generators)
616
+ * that needs to know which fields support which query types.
617
+ */
618
+ get schemaIndexes(): SchemaIndexes;
557
619
  /**
558
620
  * Get the configured allowed filter fields.
559
621
  * Returns `undefined` if no whitelist is set (all fields allowed).
@@ -738,7 +800,6 @@ declare class QueryParser {
738
800
  * // ]
739
801
  */
740
802
  private _buildRegexSearch;
741
- private _convertValue;
742
803
  private _parseOr;
743
804
  private _enhanceWithBetween;
744
805
  private _pluralize;
@@ -774,6 +835,8 @@ declare class Repository<TDoc = unknown> {
774
835
  readonly _pagination: PaginationEngine<TDoc>;
775
836
  private readonly _hookMode;
776
837
  readonly idField: string;
838
+ readonly searchMode: 'text' | 'regex' | 'auto';
839
+ readonly searchFields: string[] | undefined;
777
840
  [key: string]: unknown;
778
841
  private _hasTextIndex;
779
842
  constructor(Model: Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions);
@@ -1048,6 +1111,21 @@ declare class Repository<TDoc = unknown> {
1048
1111
  * 4. DEFAULT (500) — user-registered hooks
1049
1112
  */
1050
1113
  _buildContext(operation: string, options: Record<string, unknown> | object): Promise<RepositoryContext>;
1114
+ /**
1115
+ * Resolve the effective sort for getAll. Handles $near conflict detection
1116
+ * (warns + drops explicit sort when $near is in filters).
1117
+ */
1118
+ private _resolveSort;
1119
+ /**
1120
+ * Detect whether to use keyset (cursor) or offset (page) pagination.
1121
+ */
1122
+ private _detectPaginationMode;
1123
+ /**
1124
+ * Build the MongoDB query filter with search merged in. Handles text
1125
+ * search ($text), regex search ($or of $regex), and the search-resolver
1126
+ * plugin contract (search already cleared by a before:getAll hook).
1127
+ */
1128
+ private _buildSearchQuery;
1051
1129
  /**
1052
1130
  * Parse sort string or object
1053
1131
  */
@@ -1075,4 +1153,4 @@ declare class Repository<TDoc = unknown> {
1075
1153
  */
1076
1154
  declare function createRepository<TDoc>(Model: _$mongoose.Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions): Repository<TDoc>;
1077
1155
  //#endregion
1078
- export { type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, type FilterQuery, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type JsonSchema, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidationResult, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin };
1156
+ export { type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, type FieldType, type FilterQuery, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type JsonSchema, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidationResult, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin };
package/dist/index.mjs CHANGED
@@ -1,11 +1,13 @@
1
1
  import { a as warn, n as parseDuplicateKeyError, r as configureLogger, t as createError } from "./error-Bpbi_NKo.mjs";
2
2
  import { y as LookupBuilder } from "./update-AVfKWNGt.mjs";
3
3
  import { t as actions_exports } from "./actions/index.mjs";
4
- import { t as PaginationEngine } from "./PaginationEngine-DCs-zKwZ.mjs";
5
- import { A as aggregateHelpersPlugin, C as HOOK_PRIORITY, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, T as AggregationBuilder, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, w as Repository, x as cascadePlugin, y as prefixedId } from "./validation-chain.plugin-KjPV_6_N.mjs";
6
- import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-reyDRzXf.mjs";
7
- import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-DpjhFfaO.mjs";
8
- import mongoose from "mongoose";
4
+ import { t as PaginationEngine } from "./PaginationEngine-CpsQl471.mjs";
5
+ import { A as aggregateHelpersPlugin, C as HOOK_PRIORITY, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, T as AggregationBuilder, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, w as Repository, x as cascadePlugin, y as prefixedId } from "./validation-chain.plugin-DCYjnPau.mjs";
6
+ import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
7
+ import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-C5o7jyyA.mjs";
8
+ import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
9
+ import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
10
+ import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-8Cyu3NFJ.mjs";
9
11
  //#region src/query/QueryParser.ts
10
12
  /**
11
13
  * Modern Query Parser
@@ -31,6 +33,21 @@ var QueryParser = class {
31
33
  };
32
34
  dangerousOperators;
33
35
  /**
36
+ * Normalized dot-notation field-type map. Built once at construction from
37
+ * `options.schema` (Mongoose) and `options.fieldTypes` (override map), with
38
+ * `fieldTypes` taking precedence. An empty map means schema-aware coercion
39
+ * is disabled and the heuristic in `_convertValue` runs unchanged — this
40
+ * preserves backwards compatibility for callers that don't opt in.
41
+ */
42
+ _fieldTypes;
43
+ /**
44
+ * Structured schema-index info (geo / text / other), built once from
45
+ * `options.schema?.indexes()`. Used by the operator router to validate
46
+ * geo operators against actual geo-indexed fields, and exposed publicly
47
+ * via `parser.schemaIndexes` for downstream tools (Arc MCP, query planners).
48
+ */
49
+ _schemaIndexes;
50
+ /**
34
51
  * Regex patterns that can cause catastrophic backtracking (ReDoS attacks)
35
52
  * Detects:
36
53
  * - Quantifiers: {n,m}
@@ -67,6 +84,20 @@ var QueryParser = class {
67
84
  "$expr",
68
85
  ...this.options.additionalDangerousOperators
69
86
  ];
87
+ this._fieldTypes = buildFieldTypeMap(options.schema, options.fieldTypes);
88
+ this._schemaIndexes = extractSchemaIndexes(options.schema);
89
+ }
90
+ /**
91
+ * Structured view of the configured schema's indexes — geo fields, text
92
+ * fields, and other compound indexes. Empty arrays when no schema was
93
+ * provided. Stable across the parser's lifetime; mutating the returned
94
+ * object does not affect parser behavior.
95
+ *
96
+ * Useful for downstream tooling (Arc MCP, query planners, doc generators)
97
+ * that needs to know which fields support which query types.
98
+ */
99
+ get schemaIndexes() {
100
+ return this._schemaIndexes;
70
101
  }
71
102
  /**
72
103
  * Get the configured allowed filter fields.
@@ -520,7 +551,7 @@ var QueryParser = class {
520
551
  */
521
552
  _convertPopulateMatch(match) {
522
553
  const converted = {};
523
- for (const [key, value] of Object.entries(match)) converted[key] = this._convertValue(value);
554
+ for (const [key, value] of Object.entries(match)) converted[key] = coerceHeuristic(value);
524
555
  return converted;
525
556
  }
526
557
  /**
@@ -569,7 +600,7 @@ var QueryParser = class {
569
600
  continue;
570
601
  }
571
602
  if (typeof value === "object" && value !== null && !Array.isArray(value)) this._handleBracketSyntax(key, value, parsedFilters, depth + 1);
572
- else parsedFilters[key] = this._convertValue(value);
603
+ else parsedFilters[key] = coerceFieldValue(key, value, this._fieldTypes);
573
604
  }
574
605
  return parsedFilters;
575
606
  }
@@ -597,12 +628,18 @@ var QueryParser = class {
597
628
  }
598
629
  return;
599
630
  }
631
+ if (isGeoOperator(operator)) {
632
+ const geoFilter = parseGeoFilter(operator, value);
633
+ if (geoFilter) filters[field] = geoFilter;
634
+ else warn(`[mongokit] Invalid geo operator value for ${field}[${operator}]; dropping filter`);
635
+ return;
636
+ }
600
637
  const mongoOperator = this._toMongoOperator(operator);
601
638
  if (this.dangerousOperators.includes(mongoOperator)) {
602
639
  warn(`[mongokit] Blocked dangerous operator: ${mongoOperator}`);
603
640
  return;
604
641
  }
605
- if (mongoOperator === "$eq") filters[field] = value;
642
+ if (mongoOperator === "$eq") filters[field] = coerceFieldValue(field, value, this._fieldTypes);
606
643
  else if (mongoOperator === "$regex") {
607
644
  const safeRegex = this._createSafeRegex(value);
608
645
  if (safeRegex) {
@@ -612,17 +649,23 @@ var QueryParser = class {
612
649
  } else {
613
650
  let processedValue;
614
651
  const op = operator.toLowerCase();
615
- if ([
652
+ if (op === "size") {
653
+ processedValue = parseFloat(String(value));
654
+ if (Number.isNaN(processedValue)) return;
655
+ } else if ([
616
656
  "gt",
617
657
  "gte",
618
658
  "lt",
619
- "lte",
620
- "size"
621
- ].includes(op)) {
659
+ "lte"
660
+ ].includes(op)) if (this._fieldTypes.has(field)) {
661
+ processedValue = coerceFieldValue(field, value, this._fieldTypes);
662
+ if (typeof processedValue === "number" && Number.isNaN(processedValue)) return;
663
+ } else {
622
664
  processedValue = parseFloat(String(value));
623
665
  if (Number.isNaN(processedValue)) return;
624
- } else if (op === "in" || op === "nin") processedValue = Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim());
625
- else processedValue = this._convertValue(value);
666
+ }
667
+ else if (op === "in" || op === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, this._fieldTypes));
668
+ else processedValue = coerceFieldValue(field, value, this._fieldTypes);
626
669
  if (typeof filters[field] !== "object" || filters[field] === null || Array.isArray(filters[field])) filters[field] = {};
627
670
  filters[field][mongoOperator] = processedValue;
628
671
  }
@@ -642,6 +685,15 @@ var QueryParser = class {
642
685
  parsedFilters[field].between = value;
643
686
  continue;
644
687
  }
688
+ if (isGeoOperator(operator)) {
689
+ const geoFilter = parseGeoFilter(operator, value);
690
+ if (geoFilter) parsedFilters[field] = geoFilter;
691
+ else {
692
+ warn(`[mongokit] Invalid geo operator value for ${field}[${operator}]; dropping filter`);
693
+ delete parsedFilters[field];
694
+ }
695
+ continue;
696
+ }
645
697
  if (this.options.allowedOperators && !this.options.allowedOperators.includes(operator)) {
646
698
  warn(`[mongokit] Operator not in allowlist: ${operator}`);
647
699
  continue;
@@ -649,21 +701,27 @@ var QueryParser = class {
649
701
  if (this.operators[operator]) {
650
702
  const mongoOperator = this.operators[operator];
651
703
  let processedValue;
652
- if ([
704
+ if (operator === "size") {
705
+ processedValue = parseFloat(String(value));
706
+ if (Number.isNaN(processedValue)) continue;
707
+ } else if ([
653
708
  "gt",
654
709
  "gte",
655
710
  "lt",
656
- "lte",
657
- "size"
658
- ].includes(operator)) {
711
+ "lte"
712
+ ].includes(operator)) if (this._fieldTypes.has(field)) {
713
+ processedValue = coerceFieldValue(field, value, this._fieldTypes);
714
+ if (typeof processedValue === "number" && Number.isNaN(processedValue)) continue;
715
+ } else {
659
716
  processedValue = parseFloat(String(value));
660
717
  if (Number.isNaN(processedValue)) continue;
661
- } else if (operator === "in" || operator === "nin") processedValue = Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim());
718
+ }
719
+ else if (operator === "in" || operator === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, this._fieldTypes));
662
720
  else if (operator === "like" || operator === "contains" || operator === "regex") {
663
721
  const safeRegex = this._createSafeRegex(value);
664
722
  if (!safeRegex) continue;
665
723
  processedValue = safeRegex;
666
- } else processedValue = this._convertValue(value);
724
+ } else processedValue = coerceFieldValue(field, value, this._fieldTypes);
667
725
  parsedFilters[field][mongoOperator] = processedValue;
668
726
  }
669
727
  }
@@ -727,17 +785,31 @@ var QueryParser = class {
727
785
  */
728
786
  _sanitizeMatchConfig(config) {
729
787
  const sanitized = {};
788
+ const logicalArrayOps = new Set([
789
+ "$or",
790
+ "$and",
791
+ "$nor"
792
+ ]);
730
793
  for (const [key, value] of Object.entries(config)) {
731
794
  if (this.dangerousOperators.includes(key)) {
732
795
  warn(`[mongokit] Blocked dangerous operator in aggregation: ${key}`);
733
796
  continue;
734
797
  }
735
798
  if (value && typeof value === "object" && !Array.isArray(value)) sanitized[key] = this._sanitizeMatchConfig(value);
736
- else if (Array.isArray(value)) sanitized[key] = value.map((item) => {
737
- if (item && typeof item === "object" && !Array.isArray(item)) return this._sanitizeMatchConfig(item);
738
- return item;
739
- });
740
- else sanitized[key] = value;
799
+ else if (Array.isArray(value)) {
800
+ const sanitizedArray = value.map((item) => {
801
+ if (item && typeof item === "object" && !Array.isArray(item)) return this._sanitizeMatchConfig(item);
802
+ return item;
803
+ });
804
+ if (logicalArrayOps.has(key)) {
805
+ const filtered = sanitizedArray.filter((item) => !(item && typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0));
806
+ if (filtered.length === 0) {
807
+ warn(`[mongokit] All branches of ${key} were blocked by sanitization; dropping the operator`);
808
+ continue;
809
+ }
810
+ sanitized[key] = filtered;
811
+ } else sanitized[key] = sanitizedArray;
812
+ } else sanitized[key] = value;
741
813
  }
742
814
  return sanitized;
743
815
  }
@@ -822,22 +894,15 @@ var QueryParser = class {
822
894
  for (const field of this.options.searchFields) orConditions.push({ [field]: { $regex: safeRegex } });
823
895
  return orConditions.length > 0 ? orConditions : null;
824
896
  }
825
- _convertValue(value) {
826
- if (value === null || value === void 0) return value;
827
- if (Array.isArray(value)) return value.map((v) => this._convertValue(v));
828
- if (typeof value === "object") return value;
829
- const stringValue = String(value);
830
- if (stringValue === "true") return true;
831
- if (stringValue === "false") return false;
832
- if (mongoose.Types.ObjectId.isValid(stringValue) && stringValue.length === 24) return stringValue;
833
- return stringValue;
834
- }
835
897
  _parseOr(query) {
836
898
  const orArray = [];
837
899
  const raw = query?.or || query?.OR || query?.$or;
838
900
  if (!raw) return void 0;
839
901
  const items = Array.isArray(raw) ? raw : typeof raw === "object" ? Object.values(raw) : [];
840
- for (const item of items) if (typeof item === "object" && item) orArray.push(this._parseFilters(item, 1));
902
+ for (const item of items) if (typeof item === "object" && item) {
903
+ const parsedBranch = this._parseFilters(item, 1);
904
+ if (Object.keys(parsedBranch).length > 0) orArray.push(parsedBranch);
905
+ }
841
906
  return orArray.length ? orArray : void 0;
842
907
  }
843
908
  _enhanceWithBetween(filters) {
@@ -0,0 +1,41 @@
1
+ //#region src/query/primitives/indexes.d.ts
2
+ /**
3
+ * Schema index introspection
4
+ *
5
+ * Pure functions that read a Mongoose-like schema's `.indexes()` output and
6
+ * extract structured information about which fields are indexed how. Used by
7
+ * QueryParser to:
8
+ *
9
+ * - Detect 2dsphere/2d-indexed fields → enable geo operator routing.
10
+ * - Detect text-indexed fields → expose to repositories that need it.
11
+ * - Surface compound index hints → useful for query planners and Arc MCP
12
+ * auto-generation.
13
+ *
14
+ * Stays decoupled from a specific Mongoose major version: only depends on
15
+ * `.indexes()` returning a list of `[indexSpec, options?]` tuples, which has
16
+ * been stable since Mongoose 4.x.
17
+ */
18
+ /** Minimal structural type for a Mongoose-like schema. */
19
+ interface IndexableSchema {
20
+ indexes(): Array<[Record<string, unknown>, Record<string, unknown>?]>;
21
+ }
22
+ /** Structured view of a schema's indexes, indexed by purpose. */
23
+ interface SchemaIndexes {
24
+ /** Field paths with a 2dsphere or 2d index — eligible for geo operators */
25
+ geoFields: string[];
26
+ /** Field paths with a text index — eligible for $text queries */
27
+ textFields: string[];
28
+ /** All other indexes as raw spec/options pairs (for hints, plan analysis) */
29
+ other: Array<{
30
+ spec: Record<string, unknown>;
31
+ options?: Record<string, unknown>;
32
+ }>;
33
+ }
34
+ /**
35
+ * Extract structured index information from a Mongoose schema. Returns an
36
+ * empty `SchemaIndexes` shape (not null) when no schema is provided so callers
37
+ * can read `.geoFields`/`.textFields` unconditionally without null checks.
38
+ */
39
+ declare function extractSchemaIndexes(schema?: IndexableSchema | null): SchemaIndexes;
40
+ //#endregion
41
+ export { SchemaIndexes as n, extractSchemaIndexes as r, IndexableSchema as t };
@@ -1,3 +1,4 @@
1
+ import { n as isObjectIdInstance } from "./id-resolution-LZ-cCwR5.mjs";
1
2
  import "mongoose";
2
3
  //#region src/utils/memory-cache.ts
3
4
  /**
@@ -93,28 +94,56 @@ function buildCrudSchemasFromModel(mongooseModel, options = {}) {
93
94
  return buildCrudSchemasFromMongooseSchema(mongooseModel.schema, options);
94
95
  }
95
96
  /**
96
- * Get fields that are immutable (cannot be updated)
97
+ * Collect fields to omit from a generated schema based on field rules and
98
+ * explicit omit lists. This is the single source of truth for "which fields
99
+ * should NOT appear in the create/update body" — called by both the
100
+ * path-based and tree-based schema builders.
101
+ */
102
+ function collectFieldsToOmit(options, purpose) {
103
+ const result = new Set([
104
+ "createdAt",
105
+ "updatedAt",
106
+ "__v"
107
+ ]);
108
+ const rules = options?.fieldRules || {};
109
+ for (const [field, rule] of Object.entries(rules)) {
110
+ if (rule.systemManaged) result.add(field);
111
+ if (purpose === "update" && (rule.immutable || rule.immutableAfterCreate)) result.add(field);
112
+ }
113
+ const explicit = purpose === "create" ? options?.create?.omitFields : options?.update?.omitFields;
114
+ if (explicit) for (const f of explicit) result.add(f);
115
+ return result;
116
+ }
117
+ /**
118
+ * Apply omissions + optional-overrides to a built JSON schema in-place.
119
+ * Removes properties and adjusts the `required` array.
120
+ */
121
+ function applyFieldRules(schema, fieldsToOmit, options) {
122
+ for (const field of fieldsToOmit) {
123
+ if (schema.properties?.[field]) delete schema.properties[field];
124
+ if (schema.required) schema.required = schema.required.filter((k) => k !== field);
125
+ }
126
+ const rules = options?.fieldRules || {};
127
+ for (const [field, rule] of Object.entries(rules)) if (rule.optional && schema.required) schema.required = schema.required.filter((k) => k !== field);
128
+ }
129
+ /**
130
+ * Get fields that are immutable (cannot be updated).
131
+ * Delegates to `collectFieldsToOmit` internally.
97
132
  */
98
133
  function getImmutableFields(options = {}) {
99
134
  const immutable = [];
100
- const fieldRules = options?.fieldRules || {};
101
- Object.entries(fieldRules).forEach(([field, rules]) => {
102
- if (rules.immutable || rules.immutableAfterCreate) immutable.push(field);
103
- });
104
- (options?.update?.omitFields || []).forEach((f) => {
105
- if (!immutable.includes(f)) immutable.push(f);
106
- });
135
+ const rules = options?.fieldRules || {};
136
+ for (const [field, rule] of Object.entries(rules)) if (rule.immutable || rule.immutableAfterCreate) immutable.push(field);
137
+ for (const f of options?.update?.omitFields || []) if (!immutable.includes(f)) immutable.push(f);
107
138
  return immutable;
108
139
  }
109
140
  /**
110
- * Get fields that are system-managed (cannot be set by users)
141
+ * Get fields that are system-managed (cannot be set by users).
111
142
  */
112
143
  function getSystemManagedFields(options = {}) {
113
144
  const systemManaged = [];
114
- const fieldRules = options?.fieldRules || {};
115
- Object.entries(fieldRules).forEach(([field, rules]) => {
116
- if (rules.systemManaged) systemManaged.push(field);
117
- });
145
+ const rules = options?.fieldRules || {};
146
+ for (const [field, rule] of Object.entries(rules)) if (rule.systemManaged) systemManaged.push(field);
118
147
  return systemManaged;
119
148
  }
120
149
  /**
@@ -161,7 +190,11 @@ function buildJsonSchemaFromPaths(mongooseSchema, options) {
161
190
  };
162
191
  const rootFields = /* @__PURE__ */ new Map();
163
192
  for (const [path, schemaType] of Object.entries(paths)) {
164
- if (path === "_id" || path === "__v") continue;
193
+ if (path === "__v") continue;
194
+ if (path === "_id") {
195
+ const instance = schemaType.instance;
196
+ if (!instance || isObjectIdInstance(instance)) continue;
197
+ }
165
198
  const rootField = path.split(".")[0];
166
199
  if (!rootFields.has(rootField)) rootFields.set(rootField, []);
167
200
  rootFields.get(rootField)?.push({
@@ -183,30 +216,12 @@ function buildJsonSchemaFromPaths(mongooseSchema, options) {
183
216
  properties
184
217
  };
185
218
  if (required.length) schema.required = required;
186
- const fieldsToOmit = new Set([
187
- "createdAt",
188
- "updatedAt",
189
- "__v"
190
- ]);
191
- (options?.create?.omitFields || []).forEach((f) => {
192
- fieldsToOmit.add(f);
193
- });
194
- const fieldRules = options?.fieldRules || {};
195
- Object.entries(fieldRules).forEach(([field, rules]) => {
196
- if (rules.systemManaged) fieldsToOmit.add(field);
197
- });
198
- fieldsToOmit.forEach((field) => {
199
- if (schema.properties?.[field]) delete schema.properties[field];
200
- if (schema.required) schema.required = schema.required.filter((k) => k !== field);
201
- });
219
+ applyFieldRules(schema, collectFieldsToOmit(options, "create"), options);
202
220
  const reqOv = options?.create?.requiredOverrides || {};
203
221
  const optOv = options?.create?.optionalOverrides || {};
204
222
  schema.required = schema.required || [];
205
223
  for (const [k, v] of Object.entries(reqOv)) if (v && !schema.required.includes(k)) schema.required.push(k);
206
224
  for (const [k, v] of Object.entries(optOv)) if (v && schema.required) schema.required = schema.required.filter((x) => x !== k);
207
- Object.entries(fieldRules).forEach(([field, rules]) => {
208
- if (rules.optional && schema.required) schema.required = schema.required.filter((x) => x !== field);
209
- });
210
225
  const schemaOverrides = options?.create?.schemaOverrides || {};
211
226
  for (const [k, override] of Object.entries(schemaOverrides)) if (schema.properties?.[k]) schema.properties[k] = override;
212
227
  if (options?.strictAdditionalProperties === true) schema.additionalProperties = false;
@@ -270,7 +285,7 @@ function schemaTypeToJsonSchema(schemaType) {
270
285
  else if (instance === "Date") {
271
286
  result.type = "string";
272
287
  result.format = "date-time";
273
- } else if (instance === "ObjectId" || instance === "ObjectID") {
288
+ } else if (isObjectIdInstance(instance)) {
274
289
  result.type = "string";
275
290
  result.pattern = "^[0-9a-fA-F]{24}$";
276
291
  } else if (instance === "Array") {
@@ -285,17 +300,7 @@ function schemaTypeToJsonSchema(schemaType) {
285
300
  function buildJsonSchemaForUpdate(createJson, options) {
286
301
  const clone = JSON.parse(JSON.stringify(createJson));
287
302
  delete clone.required;
288
- const fieldsToOmit = /* @__PURE__ */ new Set();
289
- (options?.update?.omitFields || []).forEach((f) => {
290
- fieldsToOmit.add(f);
291
- });
292
- const fieldRules = options?.fieldRules || {};
293
- Object.entries(fieldRules).forEach(([field, rules]) => {
294
- if (rules.immutable || rules.immutableAfterCreate) fieldsToOmit.add(field);
295
- });
296
- fieldsToOmit.forEach((field) => {
297
- if (clone.properties?.[field]) delete clone.properties[field];
298
- });
303
+ applyFieldRules(clone, collectFieldsToOmit(options, "update"), options);
299
304
  if (options?.strictAdditionalProperties === true) clone.additionalProperties = false;
300
305
  if (options?.update?.requireAtLeastOne === true) clone.minProperties = 1;
301
306
  return clone;
@@ -1,4 +1,4 @@
1
- import { T as FieldPreset, _ as CrudSchemas, k as HttpError, ot as SchemaBuilderOptions, s as CacheAdapter, xt as ValidationResult, yt as UserContext } from "./types-CkE3mOaW.mjs";
1
+ import { T as FieldPreset, _ as CrudSchemas, k as HttpError, ot as SchemaBuilderOptions, s as CacheAdapter, xt as ValidationResult, yt as UserContext } from "./types-BwO4u3JN.mjs";
2
2
  import mongoose, { Schema } from "mongoose";
3
3
 
4
4
  //#region src/utils/error.d.ts
@@ -146,11 +146,12 @@ declare function buildCrudSchemasFromMongooseSchema(mongooseSchema: Schema, opti
146
146
  */
147
147
  declare function buildCrudSchemasFromModel(mongooseModel: mongoose.Model<unknown>, options?: SchemaBuilderOptions): CrudSchemas;
148
148
  /**
149
- * Get fields that are immutable (cannot be updated)
149
+ * Get fields that are immutable (cannot be updated).
150
+ * Delegates to `collectFieldsToOmit` internally.
150
151
  */
151
152
  declare function getImmutableFields(options?: SchemaBuilderOptions): string[];
152
153
  /**
153
- * Get fields that are system-managed (cannot be set by users)
154
+ * Get fields that are system-managed (cannot be set by users).
154
155
  */
155
156
  declare function getSystemManagedFields(options?: SchemaBuilderOptions): string[];
156
157
  /**
@@ -1,4 +1,4 @@
1
- import { F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, P as KeysetPaginationOptions, U as OffsetPaginationResult, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-CkE3mOaW.mjs";
1
+ import { F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, P as KeysetPaginationOptions, U as OffsetPaginationResult, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-BwO4u3JN.mjs";
2
2
  import { Model } from "mongoose";
3
3
 
4
4
  //#region src/pagination/PaginationEngine.d.ts
@@ -1,2 +1,2 @@
1
- import { t as PaginationEngine } from "../PaginationEngine-DCs-zKwZ.mjs";
1
+ import { t as PaginationEngine } from "../PaginationEngine-CpsQl471.mjs";
2
2
  export { PaginationEngine };
@@ -1,2 +1,2 @@
1
- import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, y as MethodRegistryRepository, z as batchOperationsPlugin } from "../validation-chain.plugin-BYMZB8dN.mjs";
1
+ import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, y as MethodRegistryRepository, z as batchOperationsPlugin } from "../validation-chain.plugin-BtmT-FFB.mjs";
2
2
  export { type AggregateHelpersMethods, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type CacheMethods, type CustomIdOptions, type DateSequentialIdOptions, type ElasticSearchOptions, type IdGenerator, type MethodRegistryRepository, type MongoOperationsMethods, type MultiTenantOptions, type ObservabilityOptions, type OperationMetric, type PrefixedIdOptions, type SequentialIdOptions, type SoftDeleteMethods, type SubdocumentMethods, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };