@classytic/mongokit 3.29.0 → 3.30.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 (35) hide show
  1. package/README.md +43 -0
  2. package/dist/{create-repository-D4ZU94b3.d.mts → Repository-BXHkUtLk.d.mts} +30 -57
  3. package/dist/{Repository-DThvFCaV.mjs → Repository-X7U2d0kU.mjs} +296 -42
  4. package/dist/actions/index.mjs +1 -1
  5. package/dist/adapter/index.mjs +1 -1
  6. package/dist/{adapter-CLvUHiTW.mjs → adapter-BitHg-CN.mjs} +1 -1
  7. package/dist/ai/index.d.mts +1 -1
  8. package/dist/better-auth/index.d.mts +13 -0
  9. package/dist/better-auth/index.mjs +76 -6
  10. package/dist/create-repository-CvD4wzuN.d.mts +54 -0
  11. package/dist/{create-repository-uhKt_oUT.mjs → create-repository-DYe5YEie.mjs} +3 -2
  12. package/dist/index.d.mts +275 -41
  13. package/dist/index.mjs +80 -7
  14. package/dist/kernel-conformance/index.d.mts +217 -0
  15. package/dist/kernel-conformance/index.mjs +603 -0
  16. package/dist/method-registry.plugin-DblM7V6j.mjs +112 -0
  17. package/dist/model-registry-ClKtWiHa.mjs +67 -0
  18. package/dist/{mongooseToJsonSchema-CByt1VhQ.mjs → mongooseToJsonSchema-DKbnKduN.mjs} +14 -3
  19. package/dist/{multi-tenant.plugin-DVyVGREb.d.mts → multi-tenant.plugin-2VtSSm1Y.d.mts} +1 -1
  20. package/dist/outbox/index.d.mts +63 -0
  21. package/dist/outbox/index.mjs +239 -0
  22. package/dist/{plugin-options-vFufQZMZ.d.mts → plugin-options-BsFH0sTi.d.mts} +1 -1
  23. package/dist/plugins/index.d.mts +4 -4
  24. package/dist/plugins/index.mjs +3 -2
  25. package/dist/{repository-DCHRWRXw.d.mts → repository-Q16ErTu8.d.mts} +19 -1
  26. package/dist/testkit/index.d.mts +8 -1
  27. package/dist/testkit/index.mjs +1 -1
  28. package/dist/{timestamp.plugin-CFL6LlYZ.mjs → timestamp.plugin-ChFRcLRJ.mjs} +32 -143
  29. package/dist/{to-plain-DkF5px0R.d.mts → to-plain-BuX1RUZV.d.mts} +12 -4
  30. package/dist/{update-CI2NdAW6.mjs → update-DHdXdOk_.mjs} +21 -2
  31. package/dist/utils/index.d.mts +2 -2
  32. package/dist/utils/index.mjs +1 -1
  33. package/dist/{validation-chain.plugin-BLecaKa0.d.mts → validation-chain.plugin-BSshLJTA.d.mts} +3 -3
  34. package/dist/{validation-chain.plugin-CwOcUJC1.mjs → validation-chain.plugin-BxTl_dYR.mjs} +4 -3
  35. package/package.json +191 -185
@@ -0,0 +1,54 @@
1
+ import { c as PaginationConfig } from "./pagination-jSUdrACK.mjs";
2
+ import { _ as RepositoryOptions, d as PluginType } from "./repository-Q16ErTu8.mjs";
3
+ import { T as AuditTrailOptions, _ as RepositoryCachePluginOptions, i as CustomIdOptions, t as MultiTenantOptions } from "./multi-tenant.plugin-2VtSSm1Y.mjs";
4
+ import { n as Repository } from "./Repository-BXHkUtLk.mjs";
5
+ import { i as Logger, o as SoftDeleteOptions } from "./plugin-options-BsFH0sTi.mjs";
6
+ import { Model } from "mongoose";
7
+ //#region src/create-repository.d.ts
8
+ /**
9
+ * Audit config — either a `Logger` (routes to `auditLogPlugin`, which
10
+ * writes structured log lines through your logger) or an
11
+ * `AuditTrailOptions` object (routes to `auditTrailPlugin`, which
12
+ * persists a queryable compliance ledger in its own collection).
13
+ *
14
+ * Discrimination: a value carrying any of the `Logger` function members
15
+ * (`info` / `warn` / `error` / `debug`) is treated as a logger; anything
16
+ * else is treated as `AuditTrailOptions` (all of whose members are
17
+ * data-shaped except `metadata` / `onError`, which don't overlap with
18
+ * the logger member names).
19
+ */
20
+ type AuditConfig = Logger | AuditTrailOptions;
21
+ /**
22
+ * Declarative repository config. Every key is optional; a feature's
23
+ * plugin is installed only when its key is present. The remaining
24
+ * `RepositoryOptions` keys (`idField`, `hooks`, `schema`, `updateSchema`,
25
+ * `events`, `requirePlugins`, ...) pass through to the `Repository`
26
+ * constructor unchanged.
27
+ */
28
+ interface CreateRepositoryConfig extends RepositoryOptions {
29
+ /** Multi-tenant scoping — forwarded to `multiTenantPlugin`. */
30
+ tenant?: MultiTenantOptions;
31
+ /** Soft-delete — `true` for defaults, or `SoftDeleteOptions`. */
32
+ softDelete?: boolean | SoftDeleteOptions;
33
+ /** createdAt/updatedAt stamping — `timestampPlugin` takes no options. */
34
+ timestamps?: boolean;
35
+ /** Batch ops (`updateMany`/`deleteMany`/`bulkWrite`) via `batchOperationsPlugin`. */
36
+ batch?: boolean;
37
+ /** Read-through cache — forwarded to `cachePlugin`. */
38
+ cache?: RepositoryCachePluginOptions;
39
+ /** Audit — `Logger` → `auditLogPlugin`; `AuditTrailOptions` → `auditTrailPlugin`. */
40
+ audit?: AuditConfig;
41
+ /** Custom ID generation — forwarded to `customIdPlugin`. */
42
+ customId?: CustomIdOptions;
43
+ /** Extra plugins appended AFTER the canonical stack. */
44
+ plugins?: PluginType[];
45
+ /** Pagination engine config (defaultLimit, maxLimit, ...). */
46
+ pagination?: PaginationConfig;
47
+ }
48
+ /**
49
+ * Build a `Repository` from a declarative config. See module JSDoc for
50
+ * ordering guarantees and an example.
51
+ */
52
+ declare function createRepository<TDoc>(model: Model<TDoc, any, any, any>, config?: CreateRepositoryConfig): Repository<TDoc>;
53
+ //#endregion
54
+ export { CreateRepositoryConfig as n, createRepository as r, AuditConfig as t };
@@ -1,5 +1,6 @@
1
- import { n as Repository } from "./Repository-DThvFCaV.mjs";
2
- import { a as methodRegistryPlugin, d as cachePlugin, f as batchOperationsPlugin, g as auditLogPlugin, i as multiTenantPlugin, m as auditTrailPlugin, n as softDeletePlugin, o as customIdPlugin, t as timestampPlugin } from "./timestamp.plugin-CFL6LlYZ.mjs";
1
+ import { n as Repository } from "./Repository-X7U2d0kU.mjs";
2
+ import { a as customIdPlugin, f as auditTrailPlugin, i as multiTenantPlugin, m as auditLogPlugin, n as softDeletePlugin, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-ChFRcLRJ.mjs";
3
+ import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-DblM7V6j.mjs";
3
4
  //#region src/create-repository.ts
4
5
  function isLoggerAudit(value) {
5
6
  const v = value;
package/dist/index.d.mts CHANGED
@@ -1,19 +1,20 @@
1
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-C8IcCHF9.mjs";
2
- import { a as PopulateSpec, c as SortDirection, i as ObjectId, l as SortSpec, n as AnyModel, o as ReadPreferenceType, s as SelectSpec, t as AnyDocument } from "./core-62oo3N1C.mjs";
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
4
  import { t as index_d_exports } from "./index-DceInCTX.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-DCHRWRXw.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-DVyVGREb.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";
8
8
  import { t as PaginationEngine } from "./PaginationEngine-CBS1XGzp.mjs";
9
- import { a as Repository, i as HOOK_PRIORITY, n as CreateRepositoryConfig, o as TransitionMachine, r as createRepository, s as AggregationBuilder, t as AuditConfig } from "./create-repository-D4ZU94b3.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-vFufQZMZ.mjs";
11
- import { A as IdempotencyStorePluginOptions, B as AppendOnlyPluginOptions, C as LeasePluginOptions, D as immutableStatesPlugin, E as ImmutableStatesPluginOptions, F as cascadePlugin, H as AggregateHelpersMethods, I as BatchOperationsMethods, L as BulkWriteResult, M as fieldFilterPlugin, N as ElasticSearchOptions, O as IdempotencyClaim, P as elasticSearchPlugin, R as batchOperationsPlugin, S as LeaseMethods, T as ImmutableClaimView, U as aggregateHelpersPlugin, V as appendOnlyPlugin, _ as observabilityPlugin, a as uniqueField, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as idempotencyStorePlugin, k as IdempotencyStoreMethods, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MongoOperationsMethods, w as leasePlugin, x as methodRegistryPlugin, y as mongoOperationsPlugin, z as auditLogPlugin } from "./validation-chain.plugin-BLecaKa0.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-BXHkUtLk.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-CvD4wzuN.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";
12
13
  import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-BjdPX3YF.mjs";
13
14
  import { n as SchemaIndexes } from "./indexes-DIjMpYES.mjs";
14
- import { _ as isDuplicateKeyError, a as configureLogger, c as idVariants, f as createFieldPreset, g as createError, h as getMongooseProjection, i as createMemoryCache, m as getFieldsForUser, n as buildCrudSchemasFromModel, p as filterResponseData, r as buildCrudSchemasFromMongooseSchema, t as toPlain, v as parseDuplicateKeyError } from "./to-plain-DkF5px0R.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
16
  import { RepoCapabilities } from "@classytic/repo-core/repository";
16
- import { ClientSession, PipelineStage } from "mongoose";
17
+ import { ClientSession, Connection, Model, PipelineStage, Schema } from "mongoose";
17
18
  //#region src/actions/cascade-references.d.ts
18
19
  type PurgeMode = 'hard' | 'soft' | 'anonymize';
19
20
  /** Raw collection surface — a native MongoDB `Collection` or a Mongoose `Model`. */
@@ -93,30 +94,255 @@ interface ReferencePurgeResult {
93
94
  declare function cascadePurgeReferences(options: CascadePurgeReferencesOptions): Promise<ReferencePurgeResult[]>;
94
95
  //#endregion
95
96
  //#region src/capabilities.d.ts
96
- declare const MONGOKIT_CAPABILITIES: RepoCapabilities;
97
+ /** Three-valued transaction answer. `'unknown'` is NOT `'no'` and NOT `'yes'`. */
98
+ type TransactionSupport = 'yes' | 'no' | 'unknown';
99
+ /**
100
+ * How a capability descriptor's `transactions` flag was arrived at.
101
+ *
102
+ * - `'declared'` — a static kit descriptor (sqlitekit, prismakit, or
103
+ * {@link MONGOKIT_CAPABILITIES} itself). Absent field ⇒ `'declared'`, so
104
+ * every existing kit stays valid without change.
105
+ * - `'observed'` — read off THIS connection's live deployment topology.
106
+ * - `'unknown'` — could not be determined; `transactions` is reported
107
+ * `false` (fail closed), which is a different fact from an observed `false`.
108
+ */
109
+ type CapabilityResolution = 'declared' | 'observed' | 'unknown';
110
+ /**
111
+ * Mongokit's capability descriptor: `RepoCapabilities` plus the provenance of
112
+ * the `transactions` flag.
113
+ *
114
+ * Structural extension rather than a repo-core change on purpose — the extra
115
+ * key is optional to every other consumer, and {@link transactionResolutionOf}
116
+ * reads it defensively so a kernel can accept ANY `RepoCapabilities` (including
117
+ * a non-mongo kit's) without a cast.
118
+ */
119
+ interface MongoRepoCapabilities extends RepoCapabilities {
120
+ readonly transactionsResolution: CapabilityResolution;
121
+ }
122
+ /**
123
+ * Read the provenance of a capability descriptor's `transactions` flag.
124
+ * A descriptor without the field is a static declaration (`'declared'`) —
125
+ * which is exactly right for sqlitekit / prismakit / any kit whose answer
126
+ * genuinely does not depend on a live deployment.
127
+ */
128
+ declare function transactionResolutionOf(caps: RepoCapabilities): CapabilityResolution;
129
+ /**
130
+ * What MongoDB supports through mongokit's surface, DECLARED (not observed).
131
+ *
132
+ * Deployment-dependent flags (`transactions`, `nestedTransactions`,
133
+ * `changeStreams` — all three need a replica set or mongos) are `true` here
134
+ * because they describe the product, not the server you happen to be pointed
135
+ * at. **Do not read this constant to decide whether a live connection can run
136
+ * a transaction** — that is {@link resolveMongoCapabilities}, which is what
137
+ * `Repository#capabilities` returns. This one is for the cross-kit conformance
138
+ * harness (which overrides environment-specific limits where it is
139
+ * constructed) and as the base every observed descriptor is derived from.
140
+ */
141
+ declare const MONGOKIT_CAPABILITIES: MongoRepoCapabilities;
142
+ interface ServerDescriptionLike {
143
+ readonly type?: string | undefined;
144
+ }
145
+ interface TopologyDescriptionLike {
146
+ readonly type?: string | undefined;
147
+ readonly servers?: ReadonlyMap<string, ServerDescriptionLike> | Record<string, ServerDescriptionLike> | undefined;
148
+ }
149
+ interface ClientLike {
150
+ readonly topology?: {
151
+ readonly description?: TopologyDescriptionLike | undefined;
152
+ } | undefined;
153
+ }
154
+ /**
155
+ * The slice of a Mongoose `Connection` this module touches. Structural on
156
+ * purpose — mongokit's topology helpers stay usable with a raw `MongoClient`,
157
+ * a `Connection`, or a test double, and never import mongoose types.
158
+ */
159
+ interface CapabilityConnectionLike {
160
+ readyState?: number | undefined;
161
+ getClient?: (() => ClientLike | undefined) | undefined;
162
+ client?: ClientLike | undefined;
163
+ asPromise?: (() => Promise<unknown>) | undefined;
164
+ db?: {
165
+ admin?: (() => {
166
+ command: (cmd: Record<string, unknown>) => Promise<Record<string, unknown>>;
167
+ }) | undefined;
168
+ } | undefined;
169
+ }
170
+ /**
171
+ * Read whether a connection's LIVE deployment supports multi-document
172
+ * transactions, synchronously, from the driver's SDAM topology description.
173
+ *
174
+ * Free (a few property reads against an object the driver keeps current), so
175
+ * it is deliberately NOT memoized — a connection that opens after the repo was
176
+ * constructed upgrades its own answer with no invalidation step. What IS
177
+ * memoized is the async {@link probeMongoCapabilities} result, which this
178
+ * function consults first so an exotic deployment that answered `hello` but
179
+ * exposes no topology still reports definitively.
180
+ *
181
+ * @returns `'yes'` / `'no'` when the topology is conclusive, `'unknown'`
182
+ * otherwise — never optimistic. See the module docblock on rule 3.
183
+ */
184
+ declare function resolveTransactionSupport(connection: unknown): TransactionSupport;
185
+ /**
186
+ * The capability descriptor for a LIVE connection — what
187
+ * `Repository#capabilities` returns.
188
+ *
189
+ * Every deployment-dependent flag reflects the observed topology; everything
190
+ * else comes from {@link MONGOKIT_CAPABILITIES}. Cheap enough to call per
191
+ * access (topology read + one frozen-object lookup).
192
+ */
193
+ declare function resolveMongoCapabilities(connection: unknown): MongoRepoCapabilities;
194
+ /** The three derived descriptors, for tests and for gates that want to compare identity. */
195
+ declare function capabilitiesForSupport(support: TransactionSupport): MongoRepoCapabilities;
196
+ /** Test seam — drop memoized probe answers (a reused connection object across suites). */
197
+ declare function resetCapabilityProbeCache(connection?: unknown): void;
198
+ /** Options for {@link probeMongoCapabilities}. */
199
+ interface CapabilityProbeOptions {
200
+ /**
201
+ * Hard ceiling on the whole probe (waiting for the connection to open PLUS
202
+ * the `hello` round-trip). Exceeding it yields `'unknown'` — a bounded
203
+ * wrong-but-loud answer, never a hang at boot. Default 2000ms.
204
+ */
205
+ timeoutMs?: number;
206
+ }
207
+ /**
208
+ * Classify a `hello` (or legacy `isMaster`) reply.
209
+ *
210
+ * - `msg: 'isdbgrid'` ⇒ mongos ⇒ transactions (Mongo 4.2+ sharded).
211
+ * - `setName` ⇒ a replica-set member ⇒ transactions.
212
+ * - a reply that IS a hello (`isWritablePrimary` / `ismaster` present) with
213
+ * neither marker ⇒ standalone ⇒ **no**. Verified: a memory-server standalone
214
+ * returns `{ isWritablePrimary: true }` and nothing else.
215
+ * - anything unrecognised ⇒ `'unknown'`. A reply we cannot parse is not a yes.
216
+ */
217
+ declare function classifyHelloReply(reply: Record<string, unknown> | undefined): TransactionSupport;
218
+ /**
219
+ * Resolve a connection's real capabilities, waiting for (and if necessary
220
+ * asking) the deployment. Memoized per connection: N repositories and N
221
+ * kernels on one connection issue at most ONE `hello`.
222
+ *
223
+ * Hosts do not have to call this — `Repository#capabilities` reads the live
224
+ * topology synchronously, which is already conclusive once
225
+ * `await mongoose.connect()` has returned (the Kernel Construction Standard's
226
+ * Describe → **Bind** ordering guarantees that). It exists for the cases the
227
+ * sync read cannot cover: binding while a connection is still opening, or a
228
+ * deployment whose driver surfaces no topology description. Calling it makes
229
+ * the SUBSEQUENT synchronous reads definitive, so nothing else needs rewiring:
230
+ *
231
+ * ```ts
232
+ * await probeMongoCapabilities(connection); // once, before bind
233
+ * const engine = defineWallet().bind(connection); // gate now sees the truth
234
+ * ```
235
+ *
236
+ * Only definitive answers are cached — an `'unknown'` may be re-probed later
237
+ * (the deployment may simply not have been up yet).
238
+ */
239
+ declare function probeMongoCapabilities(connection: unknown, options?: CapabilityProbeOptions): Promise<MongoRepoCapabilities>;
97
240
  //#endregion
98
241
  //#region src/filter/compile.d.ts
242
+ declare function compileFilterToMongo(input: unknown,
99
243
  /**
100
- * Filter IR → MongoDB query compiler.
101
- *
102
- * Mirrors sqlitekit's `compileFilterToDrizzle`: takes a repo-core
103
- * `Filter` tree and emits a MongoDB query object. Used by `groupBy` /
104
- * `groupByPaginate` to translate the portable AggRequest's `filter`
105
- * + `having` into `$match` stages.
106
- *
107
- * Scope: the same operator set sqlitekit supports (`eq`, `ne`, `gt`,
108
- * `gte`, `lt`, `lte`, `in`, `nin`, `exists`, `like`, `regex`, `and`,
109
- * `or`, `not`, `raw`). Anything else throws so we fail loud instead
110
- * of silently dropping predicates.
111
- *
112
- * Why only this op set here and not everywhere in mongokit? Historic
113
- * reason: mongokit pre-dates repo-core's Filter IR, so its existing
114
- * policy plugins (multi-tenant, soft-delete) speak MongoDB query
115
- * language directly. Converting mongokit's entire filter pipeline
116
- * to Filter IR is out-of-scope for this change — we introduce the
117
- * compiler only where the new portable `groupBy` IR needs it.
244
+ * Mongoose schema for the collection being filtered. Supply it wherever it is available:
245
+ * without it the date coercion guesses from the value's SHAPE alone and silently breaks
246
+ * range filters on ISO-shaped string columns. See `CoerceFilterDatesOptions.isDateField`.
118
247
  */
119
- declare function compileFilterToMongo(input: unknown): Record<string, unknown>;
248
+ schema?: Schema): Record<string, unknown>;
249
+ //#endregion
250
+ //#region src/model-blueprint.d.ts
251
+ /**
252
+ * What a bind does when a model name is ALREADY registered on the connection.
253
+ *
254
+ * There is no default — the kernel chooses per model, because the three are not
255
+ * interchangeable and a silent choice is how schema/index contributions get dropped.
256
+ */
257
+ type ExistingModelPolicy =
258
+ /**
259
+ * The caller is contributing schema (fields, indexes) Mongoose cannot apply to a locked
260
+ * schema — reusing would silently drop it, so fail loud. The production default.
261
+ */
262
+ {
263
+ readonly mode: 'throw';
264
+ readonly hint?: string;
265
+ } |
266
+ /** Idempotent registration — the caller adds nothing new, so an existing model is correct. */
267
+ {
268
+ readonly mode: 'reuse';
269
+ } |
270
+ /**
271
+ * Clobber an existing model, then register fresh. An explicit test/development escape hatch
272
+ * (hot-reload, fixtures) — replacing a live model in production is a footgun and THROWS.
273
+ * `environment` documents intent; a bind still refuses when `NODE_ENV === 'production'`.
274
+ */
275
+ {
276
+ readonly mode: 'replace';
277
+ readonly environment: 'test' | 'development';
278
+ };
279
+ interface ModelSpec<TDocument = unknown> {
280
+ readonly name: string;
281
+ /** Explicit collection name. Omit for Mongoose's default pluralization. */
282
+ readonly collection?: string;
283
+ /** Schema FACTORY — built at most once, only when this model is actually registered. */
284
+ readonly schema: () => Schema<TDocument>;
285
+ /** What to do if `name` is already registered on the bind connection. */
286
+ readonly existing: ExistingModelPolicy;
287
+ }
288
+ interface ModelBlueprint<TModels> {
289
+ /** Every model name this blueprint will register — known WITHOUT a connection. */
290
+ readonly modelNames: readonly string[];
291
+ /**
292
+ * Compile + register every model on `connection`, then assemble the typed model bag.
293
+ *
294
+ * Registration is connection-local (uses `connection.models`, never the global registry).
295
+ * On a partial failure, models THIS bind created are removed from the connection's registry
296
+ * (a registry rollback — it never touches database collections) and the original error is
297
+ * re-thrown with the names that had already bound.
298
+ */
299
+ bind(connection: Connection): TModels;
300
+ }
301
+ /**
302
+ * Describe a set of models as a connection-free blueprint. Duplicate spec names are rejected
303
+ * here, at describe time, before any connection is involved.
304
+ */
305
+ declare function defineModels<TModels>(spec: {
306
+ readonly models: readonly ModelSpec<any>[];
307
+ /** Turn the bound `name -> Model` map into the kernel's typed model bag. */
308
+ readonly assemble: (models: ReadonlyMap<string, Model<unknown>>) => TModels;
309
+ }): ModelBlueprint<TModels>;
310
+ //#endregion
311
+ //#region src/model-registry.d.ts
312
+ /**
313
+ * A model name was already registered when a `throw` policy required it to be free.
314
+ *
315
+ * Typed (not a bare `Error`) so consumers — kernels wrapping their own domain collision error,
316
+ * tests asserting the failure — can `instanceof`-check it instead of matching a message string.
317
+ */
318
+ declare class ModelCollisionError extends Error {
319
+ readonly modelName: string;
320
+ constructor(modelName: string, detail?: string);
321
+ }
322
+ interface DefineModelOptions {
323
+ /** What to do when the name is already registered. Required — see the note above. */
324
+ onExisting: 'reuse' | 'throw';
325
+ /** Register on a specific connection instead of the default mongoose instance. */
326
+ connection?: Connection;
327
+ /** Extra context appended to the `throw` message (which call site, what would be lost). */
328
+ throwHint?: string;
329
+ /**
330
+ * Explicit collection name — Mongoose's third `model()` argument. Omit for Mongoose's
331
+ * default pluralization. Passed through only on a FRESH registration (a `reuse` hit
332
+ * returns the existing model, whose collection is already fixed).
333
+ */
334
+ collection?: string;
335
+ }
336
+ /** Is this model name already registered? Prefer {@link defineModel} over asking. */
337
+ declare function isModelRegistered(name: string, connection?: Connection): boolean;
338
+ /**
339
+ * Register a model, or return the existing one, according to `onExisting`.
340
+ *
341
+ * `schema` is a FACTORY so it is never built when an existing model wins — building a
342
+ * schema has side effects (plugin application, index declaration) that should not run for
343
+ * a registration that is about to be discarded.
344
+ */
345
+ declare function defineModel<TDoc>(name: string, schema: () => Schema<TDoc>, options: DefineModelOptions): Model<TDoc>;
120
346
  //#endregion
121
347
  //#region src/operations.d.ts
122
348
  /**
@@ -155,7 +381,7 @@ declare const READ_OPERATIONS: readonly RepositoryOperation[];
155
381
  declare function operationsByPolicyKey(key: PolicyKey): RepositoryOperation[];
156
382
  //#endregion
157
383
  //#region src/query/parser/types.d.ts
158
- type SortSpec$1 = Record<string, 1 | -1>;
384
+ type SortSpec$2 = Record<string, 1 | -1>;
159
385
  type FilterQuery = Record<string, unknown>;
160
386
  /**
161
387
  * Mongoose-compatible populate option
@@ -177,7 +403,7 @@ interface PopulateOption {
177
403
  /** Query options (limit, sort, skip) */
178
404
  options?: {
179
405
  limit?: number;
180
- sort?: SortSpec$1;
406
+ sort?: SortSpec$2;
181
407
  skip?: number;
182
408
  };
183
409
  /** Nested populate configuration */
@@ -188,7 +414,7 @@ interface ParsedQuery {
188
414
  /** MongoDB filter query */
189
415
  filters: FilterQuery;
190
416
  /** Sort specification */
191
- sort?: SortSpec$1;
417
+ sort?: SortSpec$2;
192
418
  /** Fields to populate (simple comma-separated string) */
193
419
  populate?: string;
194
420
  /**
@@ -495,15 +721,23 @@ declare function isTransactionUnsupported(error: Error): boolean;
495
721
  /**
496
722
  * PROACTIVELY report whether a connection's deployment supports multi-document
497
723
  * transactions — the read-side companion to {@link isTransactionUnsupported}
498
- * (which classifies a FAILED attempt). Single source of truth for the topology
499
- * check so callers don't hand-roll `client.topology.description.type` probing.
500
- *
501
- * Returns `false` ONLY when the topology is positively a standalone (`'Single'`)
502
- * server; an unknown/undefined topology (not yet connected, non-standard
503
- * connection object) returns `true` — optimistic, because a genuine failure is
504
- * still caught reactively by `isTransactionUnsupported`. Lets a caller skip a
505
- * doomed transaction attempt on standalone dev Mongo rather than starting one
506
- * just to catch the error.
724
+ * (which classifies a FAILED attempt). Lets a caller skip a doomed transaction
725
+ * attempt on standalone dev Mongo rather than starting one just to catch the
726
+ * error.
727
+ *
728
+ * Delegates to {@link resolveTransactionSupport} so mongokit has exactly ONE
729
+ * topology reader. That also fixes a false NEGATIVE this function used to
730
+ * have: it tested `description.type !== 'Single'`, but a single-node replica
731
+ * set reached with `directConnection` is `Single` with a server type of
732
+ * `RSPrimary` and runs transactions fine. The shared reader looks at the
733
+ * SERVER descriptions first.
734
+ *
735
+ * **`unknown` is optimistic HERE and pessimistic in `capabilities.ts` — the
736
+ * difference is deliberate.** This answers "should I bother ATTEMPTING a
737
+ * transaction?", where guessing yes costs one caught error (`allowFallback`
738
+ * still recovers). The capability descriptor answers "may this deployment be
739
+ * trusted with money?", where guessing yes is the bug class this repo keeps
740
+ * hitting (AGENTS.md FAIL LOUD rule 3). Do not "unify" them.
507
741
  *
508
742
  * Accepts a Mongoose `Connection` (or anything exposing `getClient()`/`client`
509
743
  * with a driver `topology`), so it stays decoupled from mongoose types.
@@ -709,4 +943,4 @@ declare function createOptionsExtractor<TCtx extends Record<string, unknown>>(fi
709
943
  */
710
944
  declare function systemContext(extra?: SessionOptions): SessionOptions;
711
945
  //#endregion
712
- export { ALL_OPERATIONS, type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, AggregationBuilder, 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 CascadeOptions, type CascadePurgeReferencesOptions, type CascadeRelation, type CollationOptions, type CollectionRWLike, type CreateInput, type CreateOptions, type CreateRepositoryConfig, type CursorPayload, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EnsureAuditTrailReadyOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldType, type FilterQuery, type FindOneAndUpdateOptions, type GroupResult, 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, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, MONGOKIT_CAPABILITIES, MONGOKIT_PLUGIN_NAMES, MUTATING_OPERATIONS, type Middleware, type MiddlewareContext, type MinMaxResult, type MinimalRepoView, type MongoKitPluginName, type MongoOperationsMethods, type MongoOperatorUpdate, type MultiTenantOptions, type NonNullableFields, OP_REGISTRY, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OperationDescriptor, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PolicyKey, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, type PrioritizedHook, type PurgeMode, type PurgeableRepoLike, QueryParser, type QueryParserOptions, 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 SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type TenantContext, type TenantStore, type TransitionMachine, type UpdateManyResult, type UpdateOptions, type UpdatePatch, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidatorDefinition, type ValueType, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, adminBypass, aggregateHelpersPlugin, appendOnlyPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, batchTransaction, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, cascadePurgeReferences, compileFilterToMongo, configureLogger, createError, createFieldPreset, createMemoryCache, createOptionsExtractor, createRepository, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, ensureAuditTrailReady, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, getNextSequence, idVariants, idempotencyStorePlugin, immutableField, immutableStatesPlugin, isDuplicateKeyError, isTransactionUnsupported, leasePlugin, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, repoOptionsFromCtx, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, supportsTransactions, systemContext, timestampPlugin, toPlain, uniqueField, validationChainPlugin, withTransaction };
946
+ 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 };
package/dist/index.mjs CHANGED
@@ -1,19 +1,21 @@
1
1
  import { n as idVariants } from "./id-resolution-BqDrk0S2.mjs";
2
- import { a as supportsTransactions, c as ALL_OPERATIONS, d as READ_OPERATIONS, f as operationsByPolicyKey, i as isTransactionUnsupported, l as MUTATING_OPERATIONS, m as createMongoPurgePort, n as Repository, o as withTransaction, p as MONGOKIT_CAPABILITIES, r as batchTransaction, s as AggregationBuilder, t as HOOK_PRIORITY, u as OP_REGISTRY } from "./Repository-DThvFCaV.mjs";
3
- import { b as LookupBuilder, x as compileFilterToMongo } from "./update-CI2NdAW6.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-X7U2d0kU.mjs";
3
+ import { b as LookupBuilder, x as compileFilterToMongo } from "./update-DHdXdOk_.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 methodRegistryPlugin, c as getNextSequence, d as cachePlugin, f as batchOperationsPlugin, g as auditLogPlugin, h as ensureAuditTrailReady, i as multiTenantPlugin, l as prefixedId, m as auditTrailPlugin, n as softDeletePlugin, o as customIdPlugin, p as AuditTrailQuery, r as adminBypass, s as dateSequentialId, t as timestampPlugin, u as sequentialId } from "./timestamp.plugin-CFL6LlYZ.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-ChFRcLRJ.mjs";
8
+ import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-DblM7V6j.mjs";
8
9
  import { t as PaginationEngine } from "./PaginationEngine-CczbvCAq.mjs";
9
10
  import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
10
- import { t as createRepository } from "./create-repository-uhKt_oUT.mjs";
11
- 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-CwOcUJC1.mjs";
11
+ import { t as createRepository } from "./create-repository-DYe5YEie.mjs";
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-BxTl_dYR.mjs";
12
14
  import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-FSQFLpsU.mjs";
13
15
  import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
14
16
  import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
15
17
  import { n as createMemoryCache, t as toPlain } from "./to-plain-vksRrLtc.mjs";
16
- import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-CByt1VhQ.mjs";
18
+ import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-DKbnKduN.mjs";
17
19
  import { runChunkedPurge } from "@classytic/repo-core/repository";
18
20
  import { isControlParam } from "@classytic/repo-core/query-parser";
19
21
  //#region src/actions/cascade-references.ts
@@ -145,6 +147,77 @@ async function cascadePurgeReferences(options) {
145
147
  return out;
146
148
  }
147
149
  //#endregion
150
+ //#region src/model-blueprint.ts
151
+ function isProductionRuntime() {
152
+ return process.env.NODE_ENV === "production";
153
+ }
154
+ /**
155
+ * Describe a set of models as a connection-free blueprint. Duplicate spec names are rejected
156
+ * here, at describe time, before any connection is involved.
157
+ */
158
+ function defineModels(spec) {
159
+ const { models, assemble } = spec;
160
+ const names = [];
161
+ const seen = /* @__PURE__ */ new Set();
162
+ for (const m of models) {
163
+ if (seen.has(m.name)) throw new Error(`[mongokit] defineModels: duplicate model spec name '${m.name}'. Each model must be described exactly once.`);
164
+ seen.add(m.name);
165
+ names.push(m.name);
166
+ }
167
+ const modelNames = Object.freeze([...names]);
168
+ return {
169
+ modelNames,
170
+ bind(connection) {
171
+ const map = /* @__PURE__ */ new Map();
172
+ const created = [];
173
+ const replaced = [];
174
+ try {
175
+ for (const s of models) {
176
+ const preExisting = isModelRegistered(s.name, connection);
177
+ if (s.existing.mode === "replace") {
178
+ if (isProductionRuntime()) throw new Error(`[mongokit] model '${s.name}' declares existing policy 'replace', which is forbidden when NODE_ENV=production. Use a separate connection for a second engine; do not clobber a live production model.`);
179
+ if (preExisting) {
180
+ const original = connection.models[s.name];
181
+ replaced.push({
182
+ name: s.name,
183
+ schema: original.schema,
184
+ collection: original.collection.name
185
+ });
186
+ connection.deleteModel(s.name);
187
+ }
188
+ }
189
+ const onExisting = s.existing.mode === "reuse" ? "reuse" : "throw";
190
+ const throwHint = s.existing.mode === "throw" && s.existing.hint ? s.existing.hint : `Registering model set [${modelNames.join(", ")}]; already bound this call: [${created.join(", ") || "none"}]${s.collection ? ` (collection '${s.collection}')` : ""}.`;
191
+ const model = defineModel(s.name, s.schema, {
192
+ onExisting,
193
+ connection,
194
+ throwHint,
195
+ ...s.collection !== void 0 ? { collection: s.collection } : {}
196
+ });
197
+ if (!preExisting) created.push(s.name);
198
+ map.set(s.name, model);
199
+ }
200
+ return assemble(map);
201
+ } catch (err) {
202
+ const rollbackErrors = [];
203
+ for (const name of created) try {
204
+ connection.deleteModel(name);
205
+ } catch (e) {
206
+ rollbackErrors.push(e);
207
+ }
208
+ for (const r of replaced) try {
209
+ if (connection.models[r.name]) connection.deleteModel(r.name);
210
+ connection.model(r.name, r.schema, r.collection);
211
+ } catch (e) {
212
+ rollbackErrors.push(e);
213
+ }
214
+ if (rollbackErrors.length > 0) throw new AggregateError([err, ...rollbackErrors], `[mongokit] defineModels.bind failed AND ${rollbackErrors.length} rollback operation(s) failed — the connection model registry may be inconsistent.`);
215
+ throw err;
216
+ }
217
+ }
218
+ };
219
+ }
220
+ //#endregion
148
221
  //#region src/query/parser/pipeline-sanitizer.ts
149
222
  /**
150
223
  * Sanitize $match configuration to prevent dangerous operators.
@@ -1611,4 +1684,4 @@ function systemContext(extra) {
1611
1684
  */
1612
1685
  var src_default = Repository;
1613
1686
  //#endregion
1614
- export { ALL_OPERATIONS, AggregationBuilder, AuditTrailQuery, HOOK_PRIORITY, LookupBuilder, MONGOKIT_CAPABILITIES, MONGOKIT_PLUGIN_NAMES, MUTATING_OPERATIONS, OP_REGISTRY, PaginationEngine, QueryParser, READ_OPERATIONS, Repository, actions_exports as actions, adminBypass, aggregateHelpersPlugin, appendOnlyPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, batchTransaction, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, cascadePurgeReferences, compileFilterToMongo, configureLogger, createError, createFieldPreset, createMemoryCache, createOptionsExtractor, createRepository, createTenantContext, customIdPlugin, dateSequentialId, src_default as default, elasticSearchPlugin, ensureAuditTrailReady, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, getNextSequence, idVariants, idempotencyStorePlugin, immutableField, immutableStatesPlugin, isDuplicateKeyError, isTransactionUnsupported, leasePlugin, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, repoOptionsFromCtx, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, supportsTransactions, systemContext, timestampPlugin, toPlain, uniqueField, validationChainPlugin, withTransaction };
1687
+ export { ALL_OPERATIONS, AggregationBuilder, AuditTrailQuery, HOOK_PRIORITY, LookupBuilder, MONGOKIT_CAPABILITIES, MONGOKIT_PLUGIN_NAMES, MUTATING_OPERATIONS, ModelCollisionError, OP_REGISTRY, PaginationEngine, QueryParser, READ_OPERATIONS, Repository, actions_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, src_default as default, 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 };