@classytic/mongokit 3.31.1 → 3.33.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.
Files changed (33) hide show
  1. package/dist/{PaginationEngine-CuONvwCM.mjs → PaginationEngine-GdyX29tE.mjs} +14 -12
  2. package/dist/{Repository-Cx7BwvDA.mjs → Repository-BArvU32x.mjs} +151 -38
  3. package/dist/{Repository-BAzymuOz.d.mts → Repository-BdSkQ8vc.d.mts} +27 -4
  4. package/dist/actions/index.d.mts +1 -1
  5. package/dist/actions/index.mjs +1 -1
  6. package/dist/ai/index.d.mts +1 -1
  7. package/dist/better-auth/index.d.mts +19 -0
  8. package/dist/better-auth/index.mjs +5 -3
  9. package/dist/{create-repository-mEdfH9sz.d.mts → create-repository-BU4x9Kb0.d.mts} +4 -4
  10. package/dist/{create-repository-EWKzpsyM.mjs → create-repository-CPNbktFG.mjs} +2 -2
  11. package/dist/id-chunks-BmAwsqNk.mjs +67 -0
  12. package/dist/{index-Beyr1r4d.d.mts → index-DKEql4cL.d.mts} +1 -1
  13. package/dist/index.d.mts +15 -14
  14. package/dist/index.mjs +96 -56
  15. package/dist/{multi-tenant.plugin-2VtSSm1Y.d.mts → multi-tenant.plugin-BwSvTirB.d.mts} +3 -3
  16. package/dist/{operations-CuzX9m2Z.d.mts → operations-DZodvjC-.d.mts} +22 -3
  17. package/dist/outbox/index.d.mts +1 -1
  18. package/dist/outbox/index.mjs +1 -1
  19. package/dist/pagination/PaginationEngine.mjs +1 -1
  20. package/dist/{plugin-options-BsFH0sTi.d.mts → plugin-options-DXnlKM3B.d.mts} +31 -1
  21. package/dist/plugins/index.d.mts +3 -3
  22. package/dist/plugins/index.mjs +2 -2
  23. package/dist/{repository-Q16ErTu8.d.mts → repository-H_ffGgpE.d.mts} +8 -0
  24. package/dist/testkit/index.d.mts +2 -2
  25. package/dist/testkit/index.mjs +1 -1
  26. package/dist/{timestamp.plugin-CX_kw6TN.mjs → timestamp.plugin-BEc6TANm.mjs} +7 -5
  27. package/dist/{to-plain-BuX1RUZV.d.mts → to-plain-Dyz_qvuo.d.mts} +3 -3
  28. package/dist/{update-w5i-pa_c.mjs → update-jSXp3nu3.mjs} +48 -28
  29. package/dist/utils/index.d.mts +54 -2
  30. package/dist/utils/index.mjs +2 -1
  31. package/dist/{validation-chain.plugin-DbcBOWi3.mjs → validation-chain.plugin-CyK1s9Ze.mjs} +219 -20
  32. package/dist/{validation-chain.plugin-BSshLJTA.d.mts → validation-chain.plugin-yQRob3Av.d.mts} +2 -2
  33. package/package.json +193 -193
package/dist/index.d.mts CHANGED
@@ -1,18 +1,18 @@
1
- import { _ as WithTransactionOptions, c as GroupResult, d as MinMaxResult, f as OperationOptions, g as UpdateOptions, h as UpdateManyResult, i as CreateOptions, l as LookupPopulateOptions, m as SessionOptions, n as CacheOperationOptions, o as DeleteResult, p as ReadOptions, r as CacheableOptions, s as FindOneAndUpdateOptions, t as AggregateOptions, u as LookupPopulateResult, v as LookupBuilder, y as LookupOptions } from "./operations-CuzX9m2Z.mjs";
1
+ import { _ as UpdateOptions, a as CreateOptions, b as LookupOptions, c as FindOneAndUpdateOptions, d as LookupPopulateResult, f as MinMaxResult, g as UpdateManyResult, h as SessionOptions, i as ConvenientTransactionOptions, l as GroupResult, m as ReadOptions, n as CacheOperationOptions, p as OperationOptions, r as CacheableOptions, s as DeleteResult, t as AggregateOptions, u as LookupPopulateOptions, v as WithTransactionOptions, y as LookupBuilder } from "./operations-DZodvjC-.mjs";
2
2
  import { a as PopulateSpec, c as SortDirection, i as ObjectId, l as SortSpec$1, n as AnyModel, o as ReadPreferenceType, s as SelectSpec, t as AnyDocument } from "./core-62oo3N1C.mjs";
3
3
  import { a as DecodedCursor, c as PaginationConfig, i as CursorPayload, l as ValueType, n as BasePaginationOptions, o as KeysetPaginationOptions, r as CollationOptions, s as OffsetPaginationOptions, t as AggregatePaginationOptions } from "./pagination-jSUdrACK.mjs";
4
- import { t as index_d_exports } from "./index-Beyr1r4d.mjs";
4
+ import { t as index_d_exports } from "./index-DKEql4cL.mjs";
5
5
  import { a as InferRawDoc, c as NonNullableFields, d as Strict, f as UpdatePatch, i as InferDocument, l as PartialBy, n as DeepPartial, o as KeysOfType, p as UpdateWithValidationResult, r as DocField, s as MongoOperatorUpdate, t as CreateInput, u as RequiredBy } from "./type-utils-CLzRFtIA.mjs";
6
- import { S as RepositoryPluginName, _ as RepositoryOptions, a as HookMode, b as MONGOKIT_PLUGIN_NAMES, c as MinimalRepoView, d as PluginType, f as PrioritizedHook, g as RepositoryOperation, h as RepositoryInstance, i as EventPhase, l as Plugin, m as RepositoryEvent, n as EventHandlers, o as Middleware, p as RepositoryContext, r as EventPayload, s as MiddlewareContext, t as AllPluginMethods, u as PluginFunction, v as UserContext, x as MongoKitPluginName, y as WithPlugins } from "./repository-Q16ErTu8.mjs";
7
- import { A as ensureAuditTrailReady, C as AuditTrailMethods, D as AuditTrailQueryOptions, E as AuditTrailQuery, O as EnsureAuditTrailReadyOptions, S as AuditQueryResult, T as AuditTrailOptions, _ as RepositoryCachePluginOptions, a as DateSequentialIdOptions, b as AuditOperation, c as SequentialIdOptions, d as getNextSequence, f as prefixedId, g as RepositoryCacheHandle, h as CacheOptions, i as CustomIdOptions, k as auditTrailPlugin, l as customIdPlugin, m as CacheAdapter, n as adminBypass, o as IdGenerator, p as sequentialId, r as multiTenantPlugin, s as PrefixedIdOptions, t as MultiTenantOptions, u as dateSequentialId, v as cachePlugin, w as AuditTrailMode, x as AuditQueryOptions, y as AuditEntry } from "./multi-tenant.plugin-2VtSSm1Y.mjs";
6
+ import { S as RepositoryPluginName, _ as RepositoryOptions, a as HookMode, b as MONGOKIT_PLUGIN_NAMES, c as MinimalRepoView, d as PluginType, f as PrioritizedHook, g as RepositoryOperation, h as RepositoryInstance, i as EventPhase, l as Plugin, m as RepositoryEvent, n as EventHandlers, o as Middleware, p as RepositoryContext, r as EventPayload, s as MiddlewareContext, t as AllPluginMethods, u as PluginFunction, v as UserContext, x as MongoKitPluginName, y as WithPlugins } from "./repository-H_ffGgpE.mjs";
7
+ import { A as ensureAuditTrailReady, C as AuditTrailMethods, D as AuditTrailQueryOptions, E as AuditTrailQuery, O as EnsureAuditTrailReadyOptions, S as AuditQueryResult, T as AuditTrailOptions, _ as RepositoryCachePluginOptions, a as DateSequentialIdOptions, b as AuditOperation, c as SequentialIdOptions, d as getNextSequence, f as prefixedId, g as RepositoryCacheHandle, h as CacheOptions, i as CustomIdOptions, k as auditTrailPlugin, l as customIdPlugin, m as CacheAdapter, n as adminBypass, o as IdGenerator, p as sequentialId, r as multiTenantPlugin, s as PrefixedIdOptions, t as MultiTenantOptions, u as dateSequentialId, v as cachePlugin, w as AuditTrailMode, x as AuditQueryOptions, y as AuditEntry } from "./multi-tenant.plugin-BwSvTirB.mjs";
8
8
  import { t as PaginationEngine } from "./PaginationEngine-CBS1XGzp.mjs";
9
- import { a as AggregationPlan, c as SortOrder, i as AggregationBuilder, l as SortSpec, n as Repository, o as GroupSpec, r as TransitionMachine, s as ProjectionSpec, t as HOOK_PRIORITY, u as VectorSearchOptions } from "./Repository-BAzymuOz.mjs";
10
- import { a as SoftDeleteFilterMode, c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, n as CascadeRelation, o as SoftDeleteOptions, r as FieldPreset, s as SoftDeleteRepository, t as CascadeOptions } from "./plugin-options-BsFH0sTi.mjs";
11
- import { n as CreateRepositoryConfig, r as createRepository, t as AuditConfig } from "./create-repository-mEdfH9sz.mjs";
12
- import { A as IdempotencyStoreMethods, B as auditLogPlugin, C as LeaseMethods, D as ImmutableStatesPluginOptions, E as ImmutableClaimView, F as elasticSearchPlugin, H as appendOnlyPlugin, I as cascadePlugin, L as BatchOperationsMethods, M as idempotencyStorePlugin, N as fieldFilterPlugin, O as immutableStatesPlugin, P as ElasticSearchOptions, R as BulkWriteResult, S as methodRegistryPlugin, T as leasePlugin, U as AggregateHelpersMethods, V as AppendOnlyPluginOptions, W as aggregateHelpersPlugin, _ as OperationMetric, a as requireField, b as mongoOperationsPlugin, c as timestampPlugin, d as createTenantContext, f as SubdocumentMethods, g as ObservabilityOptions, h as softDeletePlugin, i as immutableField, j as IdempotencyStorePluginOptions, k as IdempotencyClaim, l as TenantContext, m as SoftDeleteMethods, n as autoInject, o as uniqueField, p as subdocumentPlugin, r as blockIf, s as validationChainPlugin, t as OperationType, u as TenantStore, v as observabilityPlugin, w as LeasePluginOptions, y as MongoOperationsMethods, z as batchOperationsPlugin } from "./validation-chain.plugin-BSshLJTA.mjs";
9
+ import { a as AggregationPlan, c as SortOrder, i as AggregationBuilder, l as SortSpec, n as Repository, o as GroupSpec, r as TransitionMachine, s as ProjectionSpec, t as HOOK_PRIORITY, u as VectorSearchOptions } from "./Repository-BdSkQ8vc.mjs";
10
+ import { a as SoftDeleteFilterMode, c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, n as CascadeRelation, o as SoftDeleteOptions, r as FieldPreset, s as SoftDeleteRepository, t as CascadeOptions } from "./plugin-options-DXnlKM3B.mjs";
11
+ import { n as CreateRepositoryConfig, r as createRepository, t as AuditConfig } from "./create-repository-BU4x9Kb0.mjs";
12
+ import { A as IdempotencyStoreMethods, B as auditLogPlugin, C as LeaseMethods, D as ImmutableStatesPluginOptions, E as ImmutableClaimView, F as elasticSearchPlugin, H as appendOnlyPlugin, I as cascadePlugin, L as BatchOperationsMethods, M as idempotencyStorePlugin, N as fieldFilterPlugin, O as immutableStatesPlugin, P as ElasticSearchOptions, R as BulkWriteResult, S as methodRegistryPlugin, T as leasePlugin, U as AggregateHelpersMethods, V as AppendOnlyPluginOptions, W as aggregateHelpersPlugin, _ as OperationMetric, a as requireField, b as mongoOperationsPlugin, c as timestampPlugin, d as createTenantContext, f as SubdocumentMethods, g as ObservabilityOptions, h as softDeletePlugin, i as immutableField, j as IdempotencyStorePluginOptions, k as IdempotencyClaim, l as TenantContext, m as SoftDeleteMethods, n as autoInject, o as uniqueField, p as subdocumentPlugin, r as blockIf, s as validationChainPlugin, t as OperationType, u as TenantStore, v as observabilityPlugin, w as LeasePluginOptions, y as MongoOperationsMethods, z as batchOperationsPlugin } from "./validation-chain.plugin-yQRob3Av.mjs";
13
13
  import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-BjdPX3YF.mjs";
14
14
  import { n as SchemaIndexes } from "./indexes-DIjMpYES.mjs";
15
- import { S as parseDuplicateKeyError, _ as getMongooseProjection, a as createMemoryCache, b as createError, g as getFieldsForUser, h as filterResponseData, i as buildCrudSchemasFromMongooseSchema, m as createFieldPreset, n as CrudSchemasFramework, o as LoggerConfig, r as buildCrudSchemasFromModel, s as configureLogger, t as toPlain, u as idVariants, v as CreateErrorOptions, x as isDuplicateKeyError, y as ParseDuplicateKeyOptions } from "./to-plain-BuX1RUZV.mjs";
15
+ import { S as parseDuplicateKeyError, _ as getMongooseProjection, a as createMemoryCache, b as createError, g as getFieldsForUser, h as filterResponseData, i as buildCrudSchemasFromMongooseSchema, m as createFieldPreset, n as CrudSchemasFramework, o as LoggerConfig, r as buildCrudSchemasFromModel, s as configureLogger, t as toPlain, u as idVariants, v as CreateErrorOptions, x as isDuplicateKeyError, y as ParseDuplicateKeyOptions } from "./to-plain-Dyz_qvuo.mjs";
16
16
  import { RepoCapabilities } from "@classytic/repo-core/repository";
17
17
  import { ClientSession, Connection, Model, PipelineStage, Schema } from "mongoose";
18
18
  //#region src/actions/cascade-references.d.ts
@@ -144,10 +144,11 @@ declare function transactionResolutionOf(caps: RepoCapabilities): CapabilityReso
144
144
  /**
145
145
  * What MongoDB supports through mongokit's surface, DECLARED (not observed).
146
146
  *
147
- * Deployment-dependent flags (`transactions`, `nestedTransactions`,
148
- * `changeStreams` — all three need a replica set or mongos) are `true` here
149
- * because they describe the product, not the server you happen to be pointed
150
- * at. **Do not read this constant to decide whether a live connection can run
147
+ * Deployment-dependent flags (`transactions`, `changeStreams` — both need a
148
+ * replica set or mongos) are `true` here because they describe the product,
149
+ * not the server you happen to be pointed at. `nestedTransactions` is NOT one
150
+ * of them: it is `false` unconditionally, because the refusal comes from
151
+ * mongokit's own tx-bound proxy rather than from the deployment. **Do not read this constant to decide whether a live connection can run
151
152
  * a transaction** — that is {@link resolveMongoCapabilities}, which is what
152
153
  * `Repository#capabilities` returns. This one is for the cross-kit conformance
153
154
  * harness (which overrides environment-specific limits where it is
@@ -971,4 +972,4 @@ declare function createOptionsExtractor<TCtx extends Record<string, unknown>>(fi
971
972
  */
972
973
  declare function systemContext(extra?: SessionOptions): SessionOptions;
973
974
  //#endregion
974
- export { ALL_OPERATIONS, type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, AggregationBuilder, type AggregationPlan, type SortOrder as AggregationSortOrder, type SortSpec as AggregationSortSpec, type AllPluginMethods, type AnyDocument, type AnyModel, type AppendOnlyPluginOptions, type AuditConfig, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailMode, type AuditTrailOptions, AuditTrailQuery, type AuditTrailQueryOptions, type BasePaginationOptions, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheOperationOptions, type CacheOptions, type CacheableOptions, type CapabilityConnectionLike, type CapabilityProbeOptions, type CapabilityResolution, type CascadeOptions, type CascadePurgeReferencesOptions, type CascadeRelation, type CollationOptions, type CollectionRWLike, type CreateErrorOptions, type CreateInput, type CreateOptions, type CreateRepositoryConfig, type CrudSchemasFramework, type CursorPayload, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DefineModelOptions, type DeleteResult, type DocField, type ElasticSearchOptions, type EnsureAuditTrailReadyOptions, type EventHandlers, type EventPayload, type EventPhase, type ExistingModelPolicy, type FieldPreset, type FieldType, type FilterQuery, type FindOneAndUpdateOptions, type GroupResult, type GroupSpec, HOOK_PRIORITY, type HookMode, type IdGenerator, type IdempotencyClaim, type IdempotencyStoreMethods, type IdempotencyStorePluginOptions, type ImmutableClaimView, type ImmutableStatesPluginOptions, type InferDocument, type InferRawDoc, type KeysOfType, type KeysetPaginationOptions, type LeaseMethods, type LeasePluginOptions, type Logger, type LoggerConfig, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, MONGOKIT_CAPABILITIES, MONGOKIT_PLUGIN_NAMES, MUTATING_OPERATIONS, type Middleware, type MiddlewareContext, type MinMaxResult, type MinimalRepoView, type ModelBlueprint, ModelCollisionError, type ModelSpec, type MongoKitPluginName, type MongoOperationsMethods, type MongoOperatorUpdate, type MongoRepoCapabilities, type MultiTenantOptions, type NonNullableFields, OP_REGISTRY, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OperationDescriptor, type OperationMetric, type OperationOptions, type OperationType, type PaginationConfig, PaginationEngine, type ParseDuplicateKeyOptions, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PolicyKey, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, type PrioritizedHook, type ProjectionSpec, type PurgeMode, type PurgeableRepoLike, QueryParser, type QueryParserOptions, type QuerySchema, READ_OPERATIONS, type ReadOptions, type ReadPreferenceType, type ReferencePurgeResult, type ReferenceRelation, Repository, Repository as default, type RepositoryCacheHandle, type RepositoryCachePluginOptions, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RepositoryPluginName, type RequiredBy, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SessionStarter, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec$1 as SortSpec, type Strict, type SubdocumentMethods, type TenantContext, type TenantStore, type TransactionSupport, type TransitionMachine, type UpdateManyResult, type UpdateOptions, type UpdatePatch, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidatorDefinition, type ValueType, type VectorSearchOptions, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, adminBypass, aggregateHelpersPlugin, appendOnlyPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, batchTransaction, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, capabilitiesForSupport, cascadePlugin, cascadePurgeReferences, classifyHelloReply, compileFilterToMongo, configureLogger, createError, createFieldPreset, createMemoryCache, createOptionsExtractor, createRepository, createTenantContext, customIdPlugin, dateSequentialId, defineModel, defineModels, elasticSearchPlugin, ensureAuditTrailReady, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, getNextSequence, idVariants, idempotencyStorePlugin, immutableField, immutableStatesPlugin, isDuplicateKeyError, isModelRegistered, isTransactionUnsupported, leasePlugin, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, probeMongoCapabilities, repoOptionsFromCtx, requireField, resetCapabilityProbeCache, resolveMongoCapabilities, resolveTransactionSupport, sequentialId, softDeletePlugin, subdocumentPlugin, supportsTransactions, systemContext, timestampPlugin, toPlain, transactionResolutionOf, uniqueField, validationChainPlugin, withTransaction };
975
+ export { ALL_OPERATIONS, type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, AggregationBuilder, type AggregationPlan, type SortOrder as AggregationSortOrder, type SortSpec as AggregationSortSpec, type AllPluginMethods, type AnyDocument, type AnyModel, type AppendOnlyPluginOptions, type AuditConfig, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailMode, type AuditTrailOptions, AuditTrailQuery, type AuditTrailQueryOptions, type BasePaginationOptions, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheOperationOptions, type CacheOptions, type CacheableOptions, type CapabilityConnectionLike, type CapabilityProbeOptions, type CapabilityResolution, type CascadeOptions, type CascadePurgeReferencesOptions, type CascadeRelation, type CollationOptions, type CollectionRWLike, type ConvenientTransactionOptions, type CreateErrorOptions, type CreateInput, type CreateOptions, type CreateRepositoryConfig, type CrudSchemasFramework, type CursorPayload, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DefineModelOptions, type DeleteResult, type DocField, type ElasticSearchOptions, type EnsureAuditTrailReadyOptions, type EventHandlers, type EventPayload, type EventPhase, type ExistingModelPolicy, type FieldPreset, type FieldType, type FilterQuery, type FindOneAndUpdateOptions, type GroupResult, type GroupSpec, HOOK_PRIORITY, type HookMode, type IdGenerator, type IdempotencyClaim, type IdempotencyStoreMethods, type IdempotencyStorePluginOptions, type ImmutableClaimView, type ImmutableStatesPluginOptions, type InferDocument, type InferRawDoc, type KeysOfType, type KeysetPaginationOptions, type LeaseMethods, type LeasePluginOptions, type Logger, type LoggerConfig, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, MONGOKIT_CAPABILITIES, MONGOKIT_PLUGIN_NAMES, MUTATING_OPERATIONS, type Middleware, type MiddlewareContext, type MinMaxResult, type MinimalRepoView, type ModelBlueprint, ModelCollisionError, type ModelSpec, type MongoKitPluginName, type MongoOperationsMethods, type MongoOperatorUpdate, type MongoRepoCapabilities, type MultiTenantOptions, type NonNullableFields, OP_REGISTRY, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OperationDescriptor, type OperationMetric, type OperationOptions, type OperationType, type PaginationConfig, PaginationEngine, type ParseDuplicateKeyOptions, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PolicyKey, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, type PrioritizedHook, type ProjectionSpec, type PurgeMode, type PurgeableRepoLike, QueryParser, type QueryParserOptions, type QuerySchema, READ_OPERATIONS, type ReadOptions, type ReadPreferenceType, type ReferencePurgeResult, type ReferenceRelation, Repository, Repository as default, type RepositoryCacheHandle, type RepositoryCachePluginOptions, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RepositoryPluginName, type RequiredBy, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SessionStarter, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec$1 as SortSpec, type Strict, type SubdocumentMethods, type TenantContext, type TenantStore, type TransactionSupport, type TransitionMachine, type UpdateManyResult, type UpdateOptions, type UpdatePatch, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidatorDefinition, type ValueType, type VectorSearchOptions, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, adminBypass, aggregateHelpersPlugin, appendOnlyPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, batchTransaction, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, capabilitiesForSupport, cascadePlugin, cascadePurgeReferences, classifyHelloReply, compileFilterToMongo, configureLogger, createError, createFieldPreset, createMemoryCache, createOptionsExtractor, createRepository, createTenantContext, customIdPlugin, dateSequentialId, defineModel, defineModels, elasticSearchPlugin, ensureAuditTrailReady, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, getNextSequence, idVariants, idempotencyStorePlugin, immutableField, immutableStatesPlugin, isDuplicateKeyError, isModelRegistered, isTransactionUnsupported, leasePlugin, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, probeMongoCapabilities, repoOptionsFromCtx, requireField, resetCapabilityProbeCache, resolveMongoCapabilities, resolveTransactionSupport, sequentialId, softDeletePlugin, subdocumentPlugin, supportsTransactions, systemContext, timestampPlugin, toPlain, transactionResolutionOf, uniqueField, validationChainPlugin, withTransaction };
package/dist/index.mjs CHANGED
@@ -1,16 +1,16 @@
1
1
  import { n as idVariants } from "./id-resolution-BqDrk0S2.mjs";
2
- import { _ as resetCapabilityProbeCache, a as supportsTransactions, b as transactionResolutionOf, c as ALL_OPERATIONS, d as READ_OPERATIONS, f as operationsByPolicyKey, g as probeMongoCapabilities, h as classifyHelloReply, i as isTransactionUnsupported, l as MUTATING_OPERATIONS, m as capabilitiesForSupport, n as Repository, o as withTransaction, p as MONGOKIT_CAPABILITIES, r as batchTransaction, s as AggregationBuilder, t as HOOK_PRIORITY, u as OP_REGISTRY, v as resolveMongoCapabilities, x as createMongoPurgePort, y as resolveTransactionSupport } from "./Repository-Cx7BwvDA.mjs";
3
- import { b as LookupBuilder, x as compileFilterToMongo } from "./update-w5i-pa_c.mjs";
2
+ import { _ as resetCapabilityProbeCache, a as supportsTransactions, b as transactionResolutionOf, c as ALL_OPERATIONS, d as READ_OPERATIONS, f as operationsByPolicyKey, g as probeMongoCapabilities, h as classifyHelloReply, i as isTransactionUnsupported, l as MUTATING_OPERATIONS, m as capabilitiesForSupport, n as Repository, o as withTransaction, p as MONGOKIT_CAPABILITIES, r as batchTransaction, s as AggregationBuilder, t as HOOK_PRIORITY, u as OP_REGISTRY, v as resolveMongoCapabilities, x as createMongoPurgePort, y as resolveTransactionSupport } from "./Repository-BArvU32x.mjs";
3
+ import { b as LookupBuilder, x as compileFilterToMongo } from "./update-jSXp3nu3.mjs";
4
4
  import { n as warn, t as configureLogger } from "./logger-K7dPmu2U.mjs";
5
5
  import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-BuByZwKU.mjs";
6
6
  import { t as actions_exports } from "./actions/index.mjs";
7
- import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, r as adminBypass, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-CX_kw6TN.mjs";
7
+ import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, r as adminBypass, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-BEc6TANm.mjs";
8
8
  import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-DblM7V6j.mjs";
9
- import { t as PaginationEngine } from "./PaginationEngine-CuONvwCM.mjs";
9
+ import { t as PaginationEngine } from "./PaginationEngine-GdyX29tE.mjs";
10
10
  import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
11
- import { t as createRepository } from "./create-repository-EWKzpsyM.mjs";
11
+ import { t as createRepository } from "./create-repository-CPNbktFG.mjs";
12
12
  import { n as defineModel, r as isModelRegistered, t as ModelCollisionError } from "./model-registry-ClKtWiHa.mjs";
13
- import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "./validation-chain.plugin-DbcBOWi3.mjs";
13
+ import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "./validation-chain.plugin-CyK1s9Ze.mjs";
14
14
  import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-FSQFLpsU.mjs";
15
15
  import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
16
16
  import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
@@ -536,11 +536,13 @@ function handleOperatorSyntax(rt, filters, regexFields, operatorMatch, value) {
536
536
  }
537
537
  if (operator.toLowerCase() === "options" && regexFields[field]) {
538
538
  const fieldValue = filters[field];
539
- if (typeof fieldValue === "object" && fieldValue !== null && "$regex" in fieldValue) if (typeof value === "string" && /^[imsx]+$/.test(value)) fieldValue.$options = value;
540
- else rt.reject(`Blocked invalid regex $options value: ${String(value)}. Allowed flags: i, m, s, x`, {
541
- field,
542
- value: String(value)
543
- });
539
+ if (typeof fieldValue === "object" && fieldValue !== null && "$regex" in fieldValue) {
540
+ if (typeof value === "string" && /^[imsx]+$/.test(value)) fieldValue.$options = value;
541
+ else rt.reject(`Blocked invalid regex $options value: ${String(value)}. Allowed flags: i, m, s, x`, {
542
+ field,
543
+ value: String(value)
544
+ });
545
+ }
544
546
  return;
545
547
  }
546
548
  if (operator.toLowerCase() === "between") {
@@ -594,26 +596,27 @@ function handleOperatorSyntax(rt, filters, regexFields, operatorMatch, value) {
594
596
  "gte",
595
597
  "lt",
596
598
  "lte"
597
- ].includes(op)) if (rt.fieldTypes.has(field)) {
598
- processedValue = coerceFieldValue(field, value, rt.fieldTypes);
599
- if (typeof processedValue === "number" && Number.isNaN(processedValue)) {
600
- rt.reject(`Invalid value for ${field}[${op}]: ${String(value)}`, {
601
- field,
602
- op
603
- });
604
- return;
605
- }
606
- } else {
607
- processedValue = parseFloat(String(value));
608
- if (Number.isNaN(processedValue)) {
609
- rt.reject(`Non-numeric value for ${field}[${op}]: ${String(value)}`, {
610
- field,
611
- op
612
- });
613
- return;
599
+ ].includes(op)) {
600
+ if (rt.fieldTypes.has(field)) {
601
+ processedValue = coerceFieldValue(field, value, rt.fieldTypes);
602
+ if (typeof processedValue === "number" && Number.isNaN(processedValue)) {
603
+ rt.reject(`Invalid value for ${field}[${op}]: ${String(value)}`, {
604
+ field,
605
+ op
606
+ });
607
+ return;
608
+ }
609
+ } else {
610
+ processedValue = parseFloat(String(value));
611
+ if (Number.isNaN(processedValue)) {
612
+ rt.reject(`Non-numeric value for ${field}[${op}]: ${String(value)}`, {
613
+ field,
614
+ op
615
+ });
616
+ return;
617
+ }
614
618
  }
615
- }
616
- else if (op === "in" || op === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, rt.fieldTypes));
619
+ } else if (op === "in" || op === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, rt.fieldTypes));
617
620
  else processedValue = coerceFieldValue(field, value, rt.fieldTypes);
618
621
  if (typeof filters[field] !== "object" || filters[field] === null || Array.isArray(filters[field])) filters[field] = {};
619
622
  filters[field][mongoOperator] = processedValue;
@@ -672,26 +675,27 @@ function handleBracketSyntax(rt, field, operators, parsedFilters, depth = 0) {
672
675
  "gte",
673
676
  "lt",
674
677
  "lte"
675
- ].includes(operator)) if (rt.fieldTypes.has(field)) {
676
- processedValue = coerceFieldValue(field, value, rt.fieldTypes);
677
- if (typeof processedValue === "number" && Number.isNaN(processedValue)) {
678
- rt.reject(`Invalid value for ${field}[${operator}]: ${String(value)}`, {
679
- field,
680
- operator
681
- });
682
- continue;
683
- }
684
- } else {
685
- processedValue = parseFloat(String(value));
686
- if (Number.isNaN(processedValue)) {
687
- rt.reject(`Non-numeric value for ${field}[${operator}]: ${String(value)}`, {
688
- field,
689
- operator
690
- });
691
- continue;
678
+ ].includes(operator)) {
679
+ if (rt.fieldTypes.has(field)) {
680
+ processedValue = coerceFieldValue(field, value, rt.fieldTypes);
681
+ if (typeof processedValue === "number" && Number.isNaN(processedValue)) {
682
+ rt.reject(`Invalid value for ${field}[${operator}]: ${String(value)}`, {
683
+ field,
684
+ operator
685
+ });
686
+ continue;
687
+ }
688
+ } else {
689
+ processedValue = parseFloat(String(value));
690
+ if (Number.isNaN(processedValue)) {
691
+ rt.reject(`Non-numeric value for ${field}[${operator}]: ${String(value)}`, {
692
+ field,
693
+ operator
694
+ });
695
+ continue;
696
+ }
692
697
  }
693
- }
694
- else if (operator === "in" || operator === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, rt.fieldTypes));
698
+ } else if (operator === "in" || operator === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, rt.fieldTypes));
695
699
  else if (operator === "like" || operator === "contains" || operator === "regex") {
696
700
  const safeRegex = createSafeRegex(rt, value, "i", operator === "regex" ? "reject" : "escape");
697
701
  if (!safeRegex) continue;
@@ -837,6 +841,23 @@ function parsePositiveInt(rt, raw, label) {
837
841
  }
838
842
  //#endregion
839
843
  //#region src/query/parser/sort-select.ts
844
+ /**
845
+ * The sort applied when a request names none. Mongo/mongokit convention.
846
+ *
847
+ * Exported so `parse()` can ask whether it is PERMITTED before applying it,
848
+ * rather than substituting it and then validating it like caller input.
849
+ */
850
+ const DEFAULT_PARSER_SORT = "-createdAt";
851
+ /**
852
+ * Is every field of `sort` inside `allowedSortFields`? True when no allowlist
853
+ * is configured. Pure predicate — never rejects, never warns, so it is safe to
854
+ * ask about a default the caller did not send.
855
+ */
856
+ function isSortFieldAllowed(rt, sort) {
857
+ const allowed = rt.options.allowedSortFields;
858
+ if (!allowed || allowed.length === 0) return true;
859
+ return sort.split(",").map((s) => s.trim()).filter(Boolean).every((field) => allowed.includes(field.startsWith("-") ? field.substring(1) : field));
860
+ }
840
861
  /** Parse a sort spec (string or object form), honoring `allowedSortFields`. */
841
862
  function parseSort(rt, sort) {
842
863
  if (!sort) return void 0;
@@ -1390,18 +1411,35 @@ var QueryParser = class {
1390
1411
  */
1391
1412
  parse(query) {
1392
1413
  const rt = this.rt;
1393
- const { page, limit = 20, sort = "-createdAt", populate, search, after, cursor, select, lookup, aggregate, ...filters } = query || {};
1414
+ const { page, limit = 20, sort, populate, search, after, cursor, select, lookup, aggregate, ...filters } = query || {};
1394
1415
  let parsedLimit = parsePositiveInt(rt, limit, "limit") ?? 20;
1395
1416
  if (parsedLimit > rt.options.maxLimit) {
1396
1417
  warn(`[mongokit] Limit ${parsedLimit} exceeds maximum ${rt.options.maxLimit}, capping to max`);
1397
1418
  parsedLimit = rt.options.maxLimit;
1398
1419
  }
1420
+ /**
1421
+ * The DEFAULT sort applies only when the allowlist permits it.
1422
+ *
1423
+ * `sort = '-createdAt'` was a DESTRUCTURING default, so an absent `?sort=`
1424
+ * became `-createdAt` and was then validated exactly like caller input. With
1425
+ * `allowedSortFields` set and `createdAt` not among them, the parser
1426
+ * REJECTED ITS OWN DEFAULT — and since 3.25 rejection throws, so `parse({})`
1427
+ * threw on an empty query. Every list call on such a resource answered 400
1428
+ * (`Blocked sort field not in allowlist: createdAt`), REST and MCP alike,
1429
+ * and no request the caller could make would avoid it.
1430
+ *
1431
+ * A default the resource forbade must simply not be applied: it is not a
1432
+ * caller error, and there is nobody to report it to. A sort the caller DID
1433
+ * send still rejects — that is the fail-closed behaviour 3.25 added, and it
1434
+ * is deliberately unchanged.
1435
+ */
1436
+ const effectiveSort = sort === void 0 && isSortFieldAllowed(rt, "-createdAt") ? DEFAULT_PARSER_SORT : sort;
1399
1437
  const sanitizedSearch = sanitizeSearch(rt, search);
1400
1438
  const { simplePopulate, populateOptions } = parsePopulate(rt, populate);
1401
1439
  const parsed = {
1402
1440
  filters: parseFilters(rt, filters),
1403
1441
  limit: parsedLimit,
1404
- sort: parseSort(rt, sort),
1442
+ sort: parseSort(rt, effectiveSort),
1405
1443
  populate: simplePopulate,
1406
1444
  populateOptions,
1407
1445
  search: sanitizedSearch
@@ -1426,11 +1464,13 @@ var QueryParser = class {
1426
1464
  const parsedPage = parsePositiveInt(rt, page, "page");
1427
1465
  if (parsedPage !== void 0) parsed.page = parsedPage;
1428
1466
  const orGroup = parseOr(rt, query);
1429
- if (orGroup) if (parsed.filters.$or) {
1430
- const existingOr = parsed.filters.$or;
1431
- delete parsed.filters.$or;
1432
- parsed.filters.$and = [{ $or: existingOr }, { $or: orGroup }];
1433
- } else parsed.filters.$or = orGroup;
1467
+ if (orGroup) {
1468
+ if (parsed.filters.$or) {
1469
+ const existingOr = parsed.filters.$or;
1470
+ delete parsed.filters.$or;
1471
+ parsed.filters.$and = [{ $or: existingOr }, { $or: orGroup }];
1472
+ } else parsed.filters.$or = orGroup;
1473
+ }
1434
1474
  parsed.filters = enhanceWithBetween(rt, parsed.filters);
1435
1475
  return parsed;
1436
1476
  }
@@ -1,7 +1,7 @@
1
1
  import { i as ObjectId } from "./core-62oo3N1C.mjs";
2
- import { l as Plugin, p as RepositoryContext } from "./repository-Q16ErTu8.mjs";
2
+ import { l as Plugin, p as RepositoryContext } from "./repository-H_ffGgpE.mjs";
3
3
  import mongoose, { Connection } from "mongoose";
4
- import { CacheAdapter as CacheAdapter$1, CacheOptions, RepositoryCacheHandle, RepositoryCachePluginOptions, cachePlugin } from "@classytic/repo-core/cache";
4
+ import { CacheAdapter as CacheAdapter$1, CacheOptions, RepositoryCacheHandle as RepositoryCacheHandle$1, RepositoryCachePluginOptions, cachePlugin } from "@classytic/repo-core/cache";
5
5
  import { TenantConfig } from "@classytic/repo-core/tenant";
6
6
  //#region src/plugins/audit-trail.plugin.d.ts
7
7
  /**
@@ -582,4 +582,4 @@ declare function adminBypass(options: {
582
582
  adminRoles: readonly string[];
583
583
  }): (context: RepositoryContext, operation: string) => boolean;
584
584
  //#endregion
585
- export { ensureAuditTrailReady as A, AuditTrailMethods as C, AuditTrailQueryOptions as D, AuditTrailQuery as E, EnsureAuditTrailReadyOptions as O, AuditQueryResult as S, AuditTrailOptions as T, RepositoryCachePluginOptions as _, DateSequentialIdOptions as a, AuditOperation as b, SequentialIdOptions as c, getNextSequence as d, prefixedId as f, RepositoryCacheHandle as g, CacheOptions as h, CustomIdOptions as i, auditTrailPlugin as k, customIdPlugin as l, CacheAdapter$1 as m, adminBypass as n, IdGenerator as o, sequentialId as p, multiTenantPlugin as r, PrefixedIdOptions as s, MultiTenantOptions as t, dateSequentialId as u, cachePlugin as v, AuditTrailMode as w, AuditQueryOptions as x, AuditEntry as y };
585
+ export { ensureAuditTrailReady as A, AuditTrailMethods as C, AuditTrailQueryOptions as D, AuditTrailQuery as E, EnsureAuditTrailReadyOptions as O, AuditQueryResult as S, AuditTrailOptions as T, RepositoryCachePluginOptions as _, DateSequentialIdOptions as a, AuditOperation as b, SequentialIdOptions as c, getNextSequence as d, prefixedId as f, RepositoryCacheHandle$1 as g, CacheOptions as h, CustomIdOptions as i, auditTrailPlugin as k, customIdPlugin as l, CacheAdapter$1 as m, adminBypass as n, IdGenerator as o, sequentialId as p, multiTenantPlugin as r, PrefixedIdOptions as s, MultiTenantOptions as t, dateSequentialId as u, cachePlugin as v, AuditTrailMode as w, AuditQueryOptions as x, AuditEntry as y };
@@ -361,14 +361,25 @@ interface CacheOperationOptions {
361
361
  /** Per-call cache override forwarded to the unified cache plugin. */
362
362
  cache?: import('@classytic/repo-core/cache').CacheOptions;
363
363
  }
364
+ /**
365
+ * `session.withTransaction()`'s own options param — `TransactionOptions` (readConcern,
366
+ * writeConcern, readPreference, maxCommitTimeMS) PLUS the driver's `timeoutMS`, which is
367
+ * NOT a field on `TransactionOptions` itself (verified against the installed mongodb
368
+ * driver's `ClientSession.withTransaction` overload, mongodb.d.ts). `timeoutMS` bounds the
369
+ * WHOLE `withTransaction` call, including its built-in retry loop (default 120s) — distinct
370
+ * from `maxCommitTimeMS`, which only bounds a single `commitTransaction` server call.
371
+ */
372
+ type ConvenientTransactionOptions = import('mongoose').mongo.TransactionOptions & {
373
+ timeoutMS?: number;
374
+ };
364
375
  /** withTransaction options */
365
376
  interface WithTransactionOptions {
366
377
  /** Allow non-transactional fallback when transactions are unsupported */
367
378
  allowFallback?: boolean;
368
379
  /** Optional hook to observe fallback triggers */
369
380
  onFallback?: (error: Error) => void;
370
- /** MongoDB transaction options (readConcern, writeConcern, readPreference, maxCommitTimeMS) */
371
- transactionOptions?: import('mongoose').mongo.TransactionOptions;
381
+ /** MongoDB transaction options (readConcern, writeConcern, readPreference, maxCommitTimeMS, timeoutMS) */
382
+ transactionOptions?: ConvenientTransactionOptions;
372
383
  }
373
384
  /** Create operation options */
374
385
  interface CreateOptions extends SessionOptions {
@@ -381,6 +392,14 @@ interface CreateOptions extends SessionOptions {
381
392
  interface UpdateOptions extends OperationOptions {
382
393
  /** Enable update pipeline syntax */
383
394
  updatePipeline?: boolean;
395
+ /**
396
+ * Optimistic-concurrency CAS (repo-core `WriteOptions.ifVersion`): apply
397
+ * only if the stored version field equals this value; the write also
398
+ * `$inc`s the version. Stale version → `VersionConflictError` (never
399
+ * `null` — null stays "not found"). Version field: `RepositoryOptions.versionField`,
400
+ * default `'__v'`.
401
+ */
402
+ ifVersion?: number;
384
403
  /** Array filters for positional operator $[<identifier>] updates */
385
404
  arrayFilters?: Record<string, unknown>[];
386
405
  }
@@ -499,4 +518,4 @@ interface MinMaxResult {
499
518
  max: unknown;
500
519
  }
501
520
  //#endregion
502
- export { WithTransactionOptions as _, DeleteManyResult as a, GroupResult as c, MinMaxResult as d, OperationOptions as f, UpdateOptions as g, UpdateManyResult as h, CreateOptions as i, LookupPopulateOptions as l, SessionOptions as m, CacheOperationOptions as n, DeleteResult as o, ReadOptions as p, CacheableOptions as r, FindOneAndUpdateOptions as s, AggregateOptions as t, LookupPopulateResult as u, LookupBuilder as v, LookupOptions as y };
521
+ export { UpdateOptions as _, CreateOptions as a, LookupOptions as b, FindOneAndUpdateOptions as c, LookupPopulateResult as d, MinMaxResult as f, UpdateManyResult as g, SessionOptions as h, ConvenientTransactionOptions as i, GroupResult as l, ReadOptions as m, CacheOperationOptions as n, DeleteManyResult as o, OperationOptions as p, CacheableOptions as r, DeleteResult as s, AggregateOptions as t, LookupPopulateOptions as u, WithTransactionOptions as v, LookupBuilder as y };
@@ -1,4 +1,4 @@
1
- import { n as Repository } from "../Repository-BAzymuOz.mjs";
1
+ import { n as Repository } from "../Repository-BdSkQ8vc.mjs";
2
2
  import { Connection, Model } from "mongoose";
3
3
  //#region src/outbox/index.d.ts
4
4
  /** Delivery states. `dead_letter` is terminal and operator-visible. */
@@ -1,4 +1,4 @@
1
- import { n as Repository } from "../Repository-Cx7BwvDA.mjs";
1
+ import { n as Repository } from "../Repository-BArvU32x.mjs";
2
2
  import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-DblM7V6j.mjs";
3
3
  import { Schema } from "mongoose";
4
4
  //#region src/outbox/index.ts
@@ -1,2 +1,2 @@
1
- import { t as PaginationEngine } from "../PaginationEngine-CuONvwCM.mjs";
1
+ import { t as PaginationEngine } from "../PaginationEngine-GdyX29tE.mjs";
2
2
  export { PaginationEngine };
@@ -1,5 +1,5 @@
1
1
  import { a as PopulateSpec, i as ObjectId, l as SortSpec, s as SelectSpec } from "./core-62oo3N1C.mjs";
2
- import { h as RepositoryInstance, p as RepositoryContext } from "./repository-Q16ErTu8.mjs";
2
+ import { h as RepositoryInstance, p as RepositoryContext } from "./repository-H_ffGgpE.mjs";
3
3
  import { OffsetPaginationResult } from "@classytic/repo-core/pagination";
4
4
  //#region src/types/plugin-options.d.ts
5
5
  /** Field preset configuration (field-filter plugin) */
@@ -111,6 +111,27 @@ interface CascadeRelation {
111
111
  foreignKey: string;
112
112
  /** Whether to use soft delete if available (default: follows parent behavior) */
113
113
  softDelete?: boolean;
114
+ /**
115
+ * What happens to the referencing documents when the parent is deleted.
116
+ *
117
+ * MongoDB has no foreign keys, so this is the application-level equivalent of an
118
+ * RDBMS `ON DELETE` clause. Odoo — which hard-deletes almost everything — relies on
119
+ * Postgres `ondelete='restrict'` in 31 places in its accounting module alone; that
120
+ * enforcement is what lets it skip soft delete entirely. Without an equivalent here, a
121
+ * hard delete leaves dangling references that surface later as reports with missing
122
+ * names, and the usual workaround is to soft-delete the parent forever — which hides
123
+ * the row rather than refusing the operation.
124
+ *
125
+ * - `cascade` (DEFAULT, and the pre-existing behaviour) — delete the children too.
126
+ * - `restrict` — REFUSE the parent delete while any reference remains. Runs
127
+ * `before:delete`, because refusing after the parent is gone is not a refusal.
128
+ * - `detach` — clear the reference (`$unset`) and keep the child. The RDBMS
129
+ * `SET NULL`; only valid where the field is optional.
130
+ *
131
+ * `restrict` and `detach` issue a query per relation on delete, so `foreignKey`
132
+ * SHOULD be indexed — Mongo gives no index for free the way a FK constraint does.
133
+ */
134
+ onDelete?: 'cascade' | 'restrict' | 'detach';
114
135
  }
115
136
  /** Cascade delete plugin options */
116
137
  interface CascadeOptions {
@@ -118,6 +139,15 @@ interface CascadeOptions {
118
139
  relations: CascadeRelation[];
119
140
  /** Run cascade deletes in parallel (default: true) */
120
141
  parallel?: boolean;
142
+ /**
143
+ * Upper bound on every `$in` the bulk (`deleteMany`) path issues — restrict counts,
144
+ * detach `$unset`s and cascade deletes are all sliced to at most this many parent ids
145
+ * per query. Bounds the query-document size (Mongo rejects documents past 16 MB, which
146
+ * an unsliced `$in` reaches around a million ObjectIds) and the per-call working set.
147
+ * Default 10_000 (`DEFAULT_ID_CHUNK`); see `utils/id-chunks.ts` for why this is larger
148
+ * than `runChunkedPurge`'s 1000.
149
+ */
150
+ batchSize?: number;
121
151
  /** Logger for cascade operations */
122
152
  logger?: Logger;
123
153
  }
@@ -1,6 +1,6 @@
1
- import { S as RepositoryPluginName, b as MONGOKIT_PLUGIN_NAMES, l as Plugin, x as MongoKitPluginName } from "../repository-Q16ErTu8.mjs";
2
- import { A as ensureAuditTrailReady, C as AuditTrailMethods, D as AuditTrailQueryOptions, E as AuditTrailQuery, O as EnsureAuditTrailReadyOptions, S as AuditQueryResult, T as AuditTrailOptions, _ as RepositoryCachePluginOptions, a as DateSequentialIdOptions, b as AuditOperation, c as SequentialIdOptions, d as getNextSequence, f as prefixedId, g as RepositoryCacheHandle, h as CacheOptions, i as CustomIdOptions, k as auditTrailPlugin, l as customIdPlugin, m as CacheAdapter, o as IdGenerator, p as sequentialId, r as multiTenantPlugin, s as PrefixedIdOptions, t as MultiTenantOptions, u as dateSequentialId, v as cachePlugin, w as AuditTrailMode, x as AuditQueryOptions, y as AuditEntry } from "../multi-tenant.plugin-2VtSSm1Y.mjs";
3
- import { A as IdempotencyStoreMethods, B as auditLogPlugin, C as LeaseMethods, D as ImmutableStatesPluginOptions, E as ImmutableClaimView, F as elasticSearchPlugin, H as appendOnlyPlugin, I as cascadePlugin, L as BatchOperationsMethods, M as idempotencyStorePlugin, N as fieldFilterPlugin, O as immutableStatesPlugin, P as ElasticSearchOptions, S as methodRegistryPlugin, T as leasePlugin, U as AggregateHelpersMethods, V as AppendOnlyPluginOptions, W as aggregateHelpersPlugin, _ as OperationMetric, a as requireField, b as mongoOperationsPlugin, c as timestampPlugin, d as createTenantContext, f as SubdocumentMethods, g as ObservabilityOptions, h as softDeletePlugin, i as immutableField, j as IdempotencyStorePluginOptions, k as IdempotencyClaim, l as TenantContext, m as SoftDeleteMethods, n as autoInject, o as uniqueField, p as subdocumentPlugin, r as blockIf, s as validationChainPlugin, t as OperationType, u as TenantStore, v as observabilityPlugin, w as LeasePluginOptions, x as MethodRegistryRepository, y as MongoOperationsMethods, z as batchOperationsPlugin } from "../validation-chain.plugin-BSshLJTA.mjs";
1
+ import { S as RepositoryPluginName, b as MONGOKIT_PLUGIN_NAMES, l as Plugin, x as MongoKitPluginName } from "../repository-H_ffGgpE.mjs";
2
+ import { A as ensureAuditTrailReady, C as AuditTrailMethods, D as AuditTrailQueryOptions, E as AuditTrailQuery, O as EnsureAuditTrailReadyOptions, S as AuditQueryResult, T as AuditTrailOptions, _ as RepositoryCachePluginOptions, a as DateSequentialIdOptions, b as AuditOperation, c as SequentialIdOptions, d as getNextSequence, f as prefixedId, g as RepositoryCacheHandle, h as CacheOptions, i as CustomIdOptions, k as auditTrailPlugin, l as customIdPlugin, m as CacheAdapter, o as IdGenerator, p as sequentialId, r as multiTenantPlugin, s as PrefixedIdOptions, t as MultiTenantOptions, u as dateSequentialId, v as cachePlugin, w as AuditTrailMode, x as AuditQueryOptions, y as AuditEntry } from "../multi-tenant.plugin-BwSvTirB.mjs";
3
+ import { A as IdempotencyStoreMethods, B as auditLogPlugin, C as LeaseMethods, D as ImmutableStatesPluginOptions, E as ImmutableClaimView, F as elasticSearchPlugin, H as appendOnlyPlugin, I as cascadePlugin, L as BatchOperationsMethods, M as idempotencyStorePlugin, N as fieldFilterPlugin, O as immutableStatesPlugin, P as ElasticSearchOptions, S as methodRegistryPlugin, T as leasePlugin, U as AggregateHelpersMethods, V as AppendOnlyPluginOptions, W as aggregateHelpersPlugin, _ as OperationMetric, a as requireField, b as mongoOperationsPlugin, c as timestampPlugin, d as createTenantContext, f as SubdocumentMethods, g as ObservabilityOptions, h as softDeletePlugin, i as immutableField, j as IdempotencyStorePluginOptions, k as IdempotencyClaim, l as TenantContext, m as SoftDeleteMethods, n as autoInject, o as uniqueField, p as subdocumentPlugin, r as blockIf, s as validationChainPlugin, t as OperationType, u as TenantStore, v as observabilityPlugin, w as LeasePluginOptions, x as MethodRegistryRepository, y as MongoOperationsMethods, z as batchOperationsPlugin } from "../validation-chain.plugin-yQRob3Av.mjs";
4
4
  import { ChangeLogStore } from "@classytic/repo-core/sync";
5
5
  //#region src/plugins/change-log.plugin.d.ts
6
6
  interface ChangeLogPluginOptions {
@@ -1,6 +1,6 @@
1
- import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "../timestamp.plugin-CX_kw6TN.mjs";
1
+ import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "../timestamp.plugin-BEc6TANm.mjs";
2
2
  import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-DblM7V6j.mjs";
3
- import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "../validation-chain.plugin-DbcBOWi3.mjs";
3
+ import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "../validation-chain.plugin-CyK1s9Ze.mjs";
4
4
  //#region src/plugins/change-log.plugin.ts
5
5
  const PLUGIN_NAME = "changeLog";
6
6
  function isSkipped(context) {
@@ -109,6 +109,14 @@ interface RepositoryOptions {
109
109
  /** Custom ID field used by getById/update/delete (default: '_id').
110
110
  * Set to 'slug', 'code', 'chatId', etc. for non-ObjectId lookups. */
111
111
  idField?: string;
112
+ /**
113
+ * Field carrying the optimistic-concurrency version for `ifVersion` CAS
114
+ * writes. Default `'__v'` — the versionKey every mongoose schema already
115
+ * carries, so CAS works with zero schema changes. Note mongoose only
116
+ * auto-increments `__v` on array-mutating `save()`; mongokit's CAS path
117
+ * `$inc`s it explicitly on every versioned write, which is the contract.
118
+ */
119
+ versionField?: string;
112
120
  /**
113
121
  * How Repository.getAll handles the `search` parameter.
114
122
  * - 'text' (default): uses MongoDB $text; requires a text index.
@@ -1,5 +1,5 @@
1
- import { n as Repository } from "../Repository-BAzymuOz.mjs";
2
- import { n as CreateRepositoryConfig } from "../create-repository-mEdfH9sz.mjs";
1
+ import { n as Repository } from "../Repository-BdSkQ8vc.mjs";
2
+ import { n as CreateRepositoryConfig } from "../create-repository-BU4x9Kb0.mjs";
3
3
  import { Connection, Model, Schema } from "mongoose";
4
4
  import { MongoMemoryReplSet, MongoMemoryServer } from "mongodb-memory-server";
5
5
  //#region src/testkit/index.d.ts
@@ -1,4 +1,4 @@
1
- import { t as createRepository } from "../create-repository-EWKzpsyM.mjs";
1
+ import { t as createRepository } from "../create-repository-CPNbktFG.mjs";
2
2
  import { createConnection } from "mongoose";
3
3
  //#region src/testkit/index.ts
4
4
  function idempotentStop(server) {
@@ -1,4 +1,4 @@
1
- import { c as ALL_OPERATIONS, t as HOOK_PRIORITY, u as OP_REGISTRY } from "./Repository-Cx7BwvDA.mjs";
1
+ import { c as ALL_OPERATIONS, t as HOOK_PRIORITY, u as OP_REGISTRY } from "./Repository-BArvU32x.mjs";
2
2
  import { n as warn } from "./logger-K7dPmu2U.mjs";
3
3
  import { throwIfAborted, withRetry } from "@classytic/repo-core/repository";
4
4
  import mongoose from "mongoose";
@@ -1355,10 +1355,12 @@ function softDeletePlugin(options = {}) {
1355
1355
  const limit = params.limit || 20;
1356
1356
  const skip = (page - 1) * limit;
1357
1357
  let sortSpec = { [deletedField]: -1 };
1358
- if (params.sort) if (typeof params.sort === "string") {
1359
- const sortOrder = params.sort.startsWith("-") ? -1 : 1;
1360
- sortSpec = { [params.sort.startsWith("-") ? params.sort.substring(1) : params.sort]: sortOrder };
1361
- } else sortSpec = params.sort;
1358
+ if (params.sort) {
1359
+ if (typeof params.sort === "string") {
1360
+ const sortOrder = params.sort.startsWith("-") ? -1 : 1;
1361
+ sortSpec = { [params.sort.startsWith("-") ? params.sort.substring(1) : params.sort]: sortOrder };
1362
+ } else sortSpec = params.sort;
1363
+ }
1362
1364
  let query = this.Model.find(combinedFilters).sort(sortSpec).skip(skip).limit(limit);
1363
1365
  if (getDeletedOptions.session) query = query.session(getDeletedOptions.session);
1364
1366
  if (getDeletedOptions.select) {
@@ -1,9 +1,9 @@
1
- import { v as UserContext } from "./repository-Q16ErTu8.mjs";
2
- import { r as FieldPreset } from "./plugin-options-BsFH0sTi.mjs";
1
+ import { v as UserContext } from "./repository-H_ffGgpE.mjs";
2
+ import { r as FieldPreset } from "./plugin-options-DXnlKM3B.mjs";
3
3
  import mongoose, { Schema } from "mongoose";
4
4
  import { CacheAdapter } from "@classytic/repo-core/cache";
5
- import { CrudSchemas, SchemaBuilderOptions } from "@classytic/repo-core/schema";
6
5
  import { HttpError } from "@classytic/repo-core/errors";
6
+ import { CrudSchemas, SchemaBuilderOptions } from "@classytic/repo-core/schema";
7
7
  //#region src/utils/error.d.ts
8
8
  /** Optional structured fields for createError. */
9
9
  interface CreateErrorOptions {