@classytic/mongokit 3.7.0 → 3.8.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.
- package/dist/{PaginationEngine-CPmZv7Ds.mjs → PaginationEngine-C2_tAvAD.mjs} +2 -2
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.mjs +1 -1
- package/dist/ai/index.d.mts +1 -1
- package/dist/{index-C-qZUqv8.d.mts → index-DlSAFIc9.d.mts} +10 -2
- package/dist/index.d.mts +71 -5
- package/dist/index.mjs +4 -4
- package/dist/{mongooseToJsonSchema-Du-UopRK.d.mts → mongooseToJsonSchema-BZaKOXXI.d.mts} +1 -1
- package/dist/pagination/PaginationEngine.d.mts +1 -1
- package/dist/pagination/PaginationEngine.mjs +1 -1
- package/dist/plugins/index.d.mts +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/{types-BgdeBXI1.d.mts → types-D57SZJeE.d.mts} +28 -3
- package/dist/{update-BDsQ3cdy.mjs → update-yjSoNnWy.mjs} +24 -1
- package/dist/utils/index.d.mts +2 -2
- package/dist/{validation-chain.plugin-CEyJssZl.mjs → validation-chain.plugin-DwoOOWse.mjs} +337 -133
- package/dist/{validation-chain.plugin-Be9rG04B.d.mts → validation-chain.plugin-wGF34Ym-.d.mts} +3 -3
- package/package.json +1 -1
- /package/dist/{cursor-DZ9JSoMM.mjs → cursor-J84rR6wG.mjs} +0 -0
- /package/dist/{sort-ffe-9JBg.mjs → sort-CrZjTK25.mjs} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as warn } from "./logger-DJ7egMnd.mjs";
|
|
2
2
|
import { t as createError } from "./error-Lw9GEAro.mjs";
|
|
3
|
-
import { n as encodeCursor, r as resolveCursorFilter } from "./cursor-
|
|
4
|
-
import { r as validateKeysetSort, t as getPrimaryField } from "./sort-
|
|
3
|
+
import { n as encodeCursor, r as resolveCursorFilter } from "./cursor-J84rR6wG.mjs";
|
|
4
|
+
import { r as validateKeysetSort, t as getPrimaryField } from "./sort-CrZjTK25.mjs";
|
|
5
5
|
//#region src/pagination/utils/index-hint.ts
|
|
6
6
|
/**
|
|
7
7
|
* Read a Mongoose schema's declared indexes, defensively.
|
package/dist/actions/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-
|
|
1
|
+
import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-DlSAFIc9.mjs";
|
|
2
2
|
export { aggregate_d_exports as aggregate, create_d_exports as create, delete_d_exports as deleteActions, read_d_exports as read, update_d_exports as update };
|
package/dist/actions/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "../chunk-CfYAbeIz.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { g as create_exports, i as update_exports, p as delete_exports, u as read_exports, v as aggregate_exports } from "../update-yjSoNnWy.mjs";
|
|
3
3
|
//#region src/actions/index.ts
|
|
4
4
|
var actions_exports = /* @__PURE__ */ __exportAll({
|
|
5
5
|
aggregate: () => aggregate_exports,
|
package/dist/ai/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as MinMaxResult, D as FindOneAndUpdateOptions, G as OperationOptions, H as ObjectId, O as GroupResult, Q as PopulateSpec, _t as UpdateManyResult, a as AnyDocument, b as DeleteResult, ct as SelectSpec, et as ReadPreferenceType, g as CreateOptions, jt as LookupOptions, mt as SortSpec, vt as UpdateOptions, yt as UpdateWithValidationResult } from "./types-D57SZJeE.mjs";
|
|
2
2
|
import { ClientSession, Model, PipelineStage } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/actions/aggregate.d.ts
|
|
@@ -213,7 +213,7 @@ declare function exists<TDoc = AnyDocument>(Model: Model<TDoc>, query: Record<st
|
|
|
213
213
|
_id: unknown;
|
|
214
214
|
} | null>;
|
|
215
215
|
declare namespace update_d_exports {
|
|
216
|
-
export { increment, pullFromArray, pushToArray, update, updateByQuery, updateMany, updateWithConstraints, updateWithValidation };
|
|
216
|
+
export { findOneAndUpdate, increment, pullFromArray, pushToArray, update, updateByQuery, updateMany, updateWithConstraints, updateWithValidation };
|
|
217
217
|
}
|
|
218
218
|
/**
|
|
219
219
|
* Update by ID
|
|
@@ -255,6 +255,14 @@ declare function updateMany(Model: Model<unknown>, query: Record<string, unknown
|
|
|
255
255
|
* Update by query
|
|
256
256
|
*/
|
|
257
257
|
declare function updateByQuery<TDoc = AnyDocument>(Model: Model<TDoc>, query: Record<string, unknown>, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc | null>;
|
|
258
|
+
/**
|
|
259
|
+
* Atomic findOneAndUpdate primitive.
|
|
260
|
+
*
|
|
261
|
+
* Returns the matched document (post-update by default) or null when no doc
|
|
262
|
+
* matches and `upsert` is false. Used by outbox relays, distributed locks,
|
|
263
|
+
* and workflow semaphores that need compare-and-set in a single round-trip.
|
|
264
|
+
*/
|
|
265
|
+
declare function findOneAndUpdate<TDoc = AnyDocument>(Model: Model<TDoc>, filter: Record<string, unknown>, update: Record<string, unknown> | Record<string, unknown>[], options?: FindOneAndUpdateOptions): Promise<TDoc | null>;
|
|
258
266
|
/**
|
|
259
267
|
* Increment field
|
|
260
268
|
*/
|
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,49 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { t as index_d_exports } from "./index-
|
|
1
|
+
import { $ as ReadOptions, A as HttpError, At as LookupBuilder, B as MinMaxResult, C as EventPayload, Ct as ValidatorDefinition, D as FindOneAndUpdateOptions, Dt as IControllerResponse, E as FieldRules, Et as IController, F as KeysetPaginationOptions, G as OperationOptions, H as ObjectId, I as KeysetPaginationResult, J as PartialBy, K as PaginationConfig, L as Logger, M as InferRawDoc, N as JsonSchema, O as GroupResult, Ot as IRequestContext, P as KeysOfType, Q as PopulateSpec, R as LookupPopulateOptions, S as EventHandlers, St as ValidationResult, T as FieldPreset, Tt as WithTransactionOptions, U as OffsetPaginationOptions, V as NonNullableFields, W as OffsetPaginationResult, X as PluginFunction, Y as Plugin, Z as PluginType, _ as CrudSchemas, _t as UpdateManyResult, a as AnyDocument, at as RepositoryOptions, b as DeleteResult, bt as UserContext, c as CacheOperationOptions, ct as SelectSpec, d as CacheableOptions, dt as SoftDeleteOptions, et as ReadPreferenceType, f as CascadeOptions, ft as SoftDeleteRepository, g as CreateOptions, gt as UpdateInput, h as CreateInput, ht as Strict, i as AllPluginMethods, it as RepositoryOperation, j as InferDocument, jt as LookupOptions, k as HookMode, kt as IResponseFormatter, l as CacheOptions, lt as SessionOptions, m as CollationOptions, mt as SortSpec, n as AggregatePaginationOptions, nt as RepositoryEvent, o as AnyModel, ot as RequiredBy, p as CascadeRelation, pt as SortDirection, q as PaginationResult, r as AggregatePaginationResult, rt as RepositoryInstance, s as CacheAdapter, st as SchemaBuilderOptions, t as AggregateOptions, tt as RepositoryContext, u as CacheStats, ut as SoftDeleteFilterMode, v as DecodedCursor, vt as UpdateOptions, w as EventPhase, wt as WithPlugins, x as DocField, xt as ValidationChainOptions, y as DeepPartial, yt as UpdateWithValidationResult, z as LookupPopulateResult } from "./types-D57SZJeE.mjs";
|
|
2
|
+
import { t as index_d_exports } from "./index-DlSAFIc9.mjs";
|
|
3
3
|
import { PaginationEngine } from "./pagination/PaginationEngine.mjs";
|
|
4
|
-
import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, T as ElasticSearchOptions, U as AuditEntry, V as BulkWriteResult, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "./validation-chain.plugin-
|
|
4
|
+
import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, T as ElasticSearchOptions, U as AuditEntry, V as BulkWriteResult, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "./validation-chain.plugin-wGF34Ym-.mjs";
|
|
5
5
|
import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-oM8G4b6m.mjs";
|
|
6
6
|
import { n as SchemaIndexes } from "./indexes-C26GNZRU.mjs";
|
|
7
|
-
import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, m as parseDuplicateKeyError, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "./mongooseToJsonSchema-
|
|
7
|
+
import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, m as parseDuplicateKeyError, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "./mongooseToJsonSchema-BZaKOXXI.mjs";
|
|
8
8
|
import * as _$mongoose from "mongoose";
|
|
9
9
|
import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
|
|
10
10
|
|
|
11
|
+
//#region src/operations.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* Where a plugin should inject its scoping filter (multi-tenant scope,
|
|
14
|
+
* soft-delete filter, etc.) on the RepositoryContext.
|
|
15
|
+
*
|
|
16
|
+
* - `data` — single-doc create payload (`context.data`)
|
|
17
|
+
* - `dataArray` — multi-doc create payload (`context.dataArray`)
|
|
18
|
+
* - `query` — raw filter (`context.query`); the dominant convention
|
|
19
|
+
* - `filters` — paginated list options' filter sub-bag (`context.filters`)
|
|
20
|
+
* - `operations` — bulkWrite per-sub-op (special — plugins walk each entry)
|
|
21
|
+
* - `none` — no scoping target (op accepts no filter input)
|
|
22
|
+
*/
|
|
23
|
+
type PolicyKey = 'data' | 'dataArray' | 'query' | 'filters' | 'operations' | 'none';
|
|
24
|
+
interface OperationDescriptor {
|
|
25
|
+
/** Where multi-tenant / soft-delete plugins inject their scoping filter. */
|
|
26
|
+
policyKey: PolicyKey;
|
|
27
|
+
/** Whether this op writes to the database. Drives audit + cache invalidation. */
|
|
28
|
+
mutates: boolean;
|
|
29
|
+
/** True when `context.id` is populated by the time before/after hooks fire. */
|
|
30
|
+
hasIdContext: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The registry. Order intentionally groups by category for readability.
|
|
34
|
+
* Adding a new RepositoryOperation requires exactly one entry here, after
|
|
35
|
+
* which every bundled plugin auto-classifies it correctly.
|
|
36
|
+
*/
|
|
37
|
+
declare const OP_REGISTRY: Readonly<Record<RepositoryOperation, OperationDescriptor>>;
|
|
38
|
+
/** All known repository operations, in registry order. */
|
|
39
|
+
declare const ALL_OPERATIONS: RepositoryOperation[];
|
|
40
|
+
/** Operations that mutate the database. Drives audit + cache invalidation lists. */
|
|
41
|
+
declare const MUTATING_OPERATIONS: readonly RepositoryOperation[];
|
|
42
|
+
/** Operations that don't mutate. Drives default cacheable ops. */
|
|
43
|
+
declare const READ_OPERATIONS: readonly RepositoryOperation[];
|
|
44
|
+
/** Filter ops by their policy injection key. */
|
|
45
|
+
declare function operationsByPolicyKey(key: PolicyKey): RepositoryOperation[];
|
|
46
|
+
//#endregion
|
|
11
47
|
//#region src/query/AggregationBuilder.d.ts
|
|
12
48
|
/** Options for $vectorSearch stage (Atlas only) */
|
|
13
49
|
interface VectorSearchOptions {
|
|
@@ -998,6 +1034,36 @@ declare class Repository<TDoc = unknown> {
|
|
|
998
1034
|
* Update document by ID
|
|
999
1035
|
*/
|
|
1000
1036
|
update(id: string | ObjectId, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc>;
|
|
1037
|
+
/**
|
|
1038
|
+
* Atomic findOneAndUpdate (compare-and-set primitive).
|
|
1039
|
+
*
|
|
1040
|
+
* Single round-trip match-and-mutate for outbox relays, distributed locks,
|
|
1041
|
+
* and workflow semaphores. Goes through the full hook pipeline so
|
|
1042
|
+
* multi-tenant scope, soft-delete, audit, and cache plugins all apply.
|
|
1043
|
+
*
|
|
1044
|
+
* Returns the matched document (post-update by default) or `null` when no
|
|
1045
|
+
* document matches and `upsert` is false.
|
|
1046
|
+
*
|
|
1047
|
+
* @example FIFO claim-lease for an outbox worker
|
|
1048
|
+
* ```ts
|
|
1049
|
+
* const claimed = await outboxRepo.findOneAndUpdate(
|
|
1050
|
+
* { status: 'pending', leaseExpiresAt: { $lt: new Date() } },
|
|
1051
|
+
* { $set: { status: 'processing', leaseExpiresAt: leaseUntil, leasedBy: workerId } },
|
|
1052
|
+
* { sort: { createdAt: 1 }, returnDocument: 'after' },
|
|
1053
|
+
* );
|
|
1054
|
+
* if (!claimed) return; // queue empty
|
|
1055
|
+
* ```
|
|
1056
|
+
*
|
|
1057
|
+
* @example CAS upsert
|
|
1058
|
+
* ```ts
|
|
1059
|
+
* const lock = await locksRepo.findOneAndUpdate(
|
|
1060
|
+
* { _id: lockKey, ownerId: { $in: [null, workerId] } },
|
|
1061
|
+
* { $set: { ownerId: workerId, expiresAt: leaseUntil } },
|
|
1062
|
+
* { upsert: true },
|
|
1063
|
+
* );
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
findOneAndUpdate<TResult = TDoc>(filter: Record<string, unknown>, update: Record<string, unknown> | Record<string, unknown>[], options?: FindOneAndUpdateOptions): Promise<TResult | null>;
|
|
1001
1067
|
/**
|
|
1002
1068
|
* Delete a document by ID.
|
|
1003
1069
|
*
|
|
@@ -1232,4 +1298,4 @@ declare function isTransactionUnsupported(error: Error): boolean;
|
|
|
1232
1298
|
*/
|
|
1233
1299
|
declare function createRepository<TDoc>(Model: _$mongoose.Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions): Repository<TDoc>;
|
|
1234
1300
|
//#endregion
|
|
1235
|
-
export { type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, type FieldType, type FilterQuery, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type JsonSchema, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type TenantContext, type TenantStore, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidationResult, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, isTransactionUnsupported, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin, withTransaction };
|
|
1301
|
+
export { ALL_OPERATIONS, type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, type FieldType, type FilterQuery, type FindOneAndUpdateOptions, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type JsonSchema, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, MUTATING_OPERATIONS, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, OP_REGISTRY, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationDescriptor, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PolicyKey, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, READ_OPERATIONS, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type TenantContext, type TenantStore, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidationResult, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, isTransactionUnsupported, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin, withTransaction };
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as warn, t as configureLogger } from "./logger-DJ7egMnd.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { b as LookupBuilder } from "./update-yjSoNnWy.mjs";
|
|
3
3
|
import { n as parseDuplicateKeyError, t as createError } from "./error-Lw9GEAro.mjs";
|
|
4
4
|
import { t as actions_exports } from "./actions/index.mjs";
|
|
5
|
-
import { t as
|
|
6
|
-
import {
|
|
5
|
+
import { A as AuditTrailQuery, C as cachePlugin, D as withTransaction, E as isTransactionUnsupported, F as MUTATING_OPERATIONS, I as OP_REGISTRY, L as READ_OPERATIONS, M as auditLogPlugin, N as aggregateHelpersPlugin, O as AggregationBuilder, P as ALL_OPERATIONS, R as operationsByPolicyKey, S as cascadePlugin, T as Repository, _ as customIdPlugin, a as uniqueField, b as prefixedId, c as createTenantContext, d as observabilityPlugin, f as multiTenantPlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, j as auditTrailPlugin, k as batchOperationsPlugin, l as subdocumentPlugin, m as methodRegistryPlugin, n as blockIf, o as validationChainPlugin, p as mongoOperationsPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as softDeletePlugin, v as dateSequentialId, w as HOOK_PRIORITY, x as sequentialId, y as getNextSequence } from "./validation-chain.plugin-DwoOOWse.mjs";
|
|
6
|
+
import { t as PaginationEngine } from "./PaginationEngine-C2_tAvAD.mjs";
|
|
7
7
|
import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
|
|
8
8
|
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-dI0m4RBs.mjs";
|
|
9
9
|
import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
|
|
@@ -986,4 +986,4 @@ function createRepository(Model, plugins = [], paginationConfig = {}, options =
|
|
|
986
986
|
}
|
|
987
987
|
var src_default = Repository;
|
|
988
988
|
//#endregion
|
|
989
|
-
export { AggregationBuilder, AuditTrailQuery, HOOK_PRIORITY, LookupBuilder, PaginationEngine, QueryParser, Repository, actions_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, createTenantContext, customIdPlugin, dateSequentialId, src_default as default, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, isTransactionUnsupported, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin, withTransaction };
|
|
989
|
+
export { ALL_OPERATIONS, AggregationBuilder, AuditTrailQuery, HOOK_PRIORITY, LookupBuilder, MUTATING_OPERATIONS, OP_REGISTRY, PaginationEngine, QueryParser, READ_OPERATIONS, Repository, actions_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, createTenantContext, customIdPlugin, dateSequentialId, src_default as default, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, isTransactionUnsupported, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin, withTransaction };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as HttpError, St as ValidationResult, T as FieldPreset, _ as CrudSchemas, bt as UserContext, s as CacheAdapter, st as SchemaBuilderOptions } from "./types-D57SZJeE.mjs";
|
|
2
2
|
import mongoose, { Schema } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/error.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as
|
|
1
|
+
import { F as KeysetPaginationOptions, I as KeysetPaginationResult, K as PaginationConfig, U as OffsetPaginationOptions, W as OffsetPaginationResult, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-D57SZJeE.mjs";
|
|
2
2
|
import { Model } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/pagination/PaginationEngine.d.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as PaginationEngine } from "../PaginationEngine-
|
|
1
|
+
import { t as PaginationEngine } from "../PaginationEngine-C2_tAvAD.mjs";
|
|
2
2
|
export { PaginationEngine };
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, S as MethodRegistryRepository, T as ElasticSearchOptions, U as AuditEntry, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "../validation-chain.plugin-
|
|
1
|
+
import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, S as MethodRegistryRepository, T as ElasticSearchOptions, U as AuditEntry, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "../validation-chain.plugin-wGF34Ym-.mjs";
|
|
2
2
|
export { type AggregateHelpersMethods, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type CacheMethods, type CustomIdOptions, type DateSequentialIdOptions, type ElasticSearchOptions, type IdGenerator, type MethodRegistryRepository, type MongoOperationsMethods, type MultiTenantOptions, type ObservabilityOptions, type OperationMetric, type PrefixedIdOptions, type SequentialIdOptions, type SoftDeleteMethods, type SubdocumentMethods, type TenantContext, type TenantStore, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as AuditTrailQuery, C as cachePlugin, M as auditLogPlugin, N as aggregateHelpersPlugin, S as cascadePlugin, _ as customIdPlugin, a as uniqueField, b as prefixedId, c as createTenantContext, d as observabilityPlugin, f as multiTenantPlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, j as auditTrailPlugin, k as batchOperationsPlugin, l as subdocumentPlugin, m as methodRegistryPlugin, n as blockIf, o as validationChainPlugin, p as mongoOperationsPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as softDeletePlugin, v as dateSequentialId, x as sequentialId, y as getNextSequence } from "../validation-chain.plugin-
|
|
1
|
+
import { A as AuditTrailQuery, C as cachePlugin, M as auditLogPlugin, N as aggregateHelpersPlugin, S as cascadePlugin, _ as customIdPlugin, a as uniqueField, b as prefixedId, c as createTenantContext, d as observabilityPlugin, f as multiTenantPlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, j as auditTrailPlugin, k as batchOperationsPlugin, l as subdocumentPlugin, m as methodRegistryPlugin, n as blockIf, o as validationChainPlugin, p as mongoOperationsPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as softDeletePlugin, v as dateSequentialId, x as sequentialId, y as getNextSequence } from "../validation-chain.plugin-DwoOOWse.mjs";
|
|
2
2
|
export { AuditTrailQuery, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
|
|
@@ -822,6 +822,31 @@ interface UpdateOptions extends OperationOptions {
|
|
|
822
822
|
/** Array filters for positional operator $[<identifier>] updates */
|
|
823
823
|
arrayFilters?: Record<string, unknown>[];
|
|
824
824
|
}
|
|
825
|
+
/**
|
|
826
|
+
* Options for atomic findOneAndUpdate (compare-and-set primitive).
|
|
827
|
+
*
|
|
828
|
+
* Designed for outbox/lock/semaphore patterns that need a single round-trip
|
|
829
|
+
* match-and-mutate. Goes through the full hook pipeline (multi-tenant scope,
|
|
830
|
+
* soft-delete, audit) the same way `update()` does.
|
|
831
|
+
*/
|
|
832
|
+
interface FindOneAndUpdateOptions extends OperationOptions {
|
|
833
|
+
/** Sort to disambiguate when filter matches multiple docs (e.g. FIFO claim). */
|
|
834
|
+
sort?: SortSpec;
|
|
835
|
+
/** Return doc state before or after the update. Default: 'after'. */
|
|
836
|
+
returnDocument?: 'before' | 'after';
|
|
837
|
+
/** Insert if no doc matches. Default: false. */
|
|
838
|
+
upsert?: boolean;
|
|
839
|
+
/** Array filters for positional `$[<identifier>]` updates. */
|
|
840
|
+
arrayFilters?: Record<string, unknown>[];
|
|
841
|
+
/** Allow aggregation-pipeline updates (array form). Default: false. */
|
|
842
|
+
updatePipeline?: boolean;
|
|
843
|
+
/** Run mongoose schema validators on the update. Default: true. */
|
|
844
|
+
runValidators?: boolean;
|
|
845
|
+
/** Collation for locale-aware string comparison. */
|
|
846
|
+
collation?: CollationOptions;
|
|
847
|
+
/** Maximum execution time in milliseconds. */
|
|
848
|
+
maxTimeMS?: number;
|
|
849
|
+
}
|
|
825
850
|
/** Aggregate operation options */
|
|
826
851
|
interface AggregateOptions extends ReadOptions {
|
|
827
852
|
/** Allow aggregation to use disk for large sorts/groups */
|
|
@@ -1027,7 +1052,7 @@ interface RepositoryInstance {
|
|
|
1027
1052
|
[key: string]: unknown;
|
|
1028
1053
|
}
|
|
1029
1054
|
/** Repository operation names */
|
|
1030
|
-
type RepositoryOperation = 'create' | 'createMany' | 'update' | 'updateMany' | 'delete' | 'deleteMany' | 'restore' | 'getById' | 'getByQuery' | 'getOne' | 'getAll' | 'findAll' | 'getOrCreate' | 'count' | 'exists' | 'distinct' | 'aggregate' | 'aggregatePaginate' | 'lookupPopulate' | 'bulkWrite';
|
|
1055
|
+
type RepositoryOperation = 'create' | 'createMany' | 'update' | 'updateMany' | 'findOneAndUpdate' | 'delete' | 'deleteMany' | 'restore' | 'getById' | 'getByQuery' | 'getOne' | 'getAll' | 'findAll' | 'getOrCreate' | 'count' | 'exists' | 'distinct' | 'aggregate' | 'aggregatePaginate' | 'lookupPopulate' | 'bulkWrite';
|
|
1031
1056
|
/** Event lifecycle phases */
|
|
1032
1057
|
type EventPhase = 'before' | 'after' | 'error';
|
|
1033
1058
|
/** Repository event names (generated from template literals) */
|
|
@@ -1173,7 +1198,7 @@ interface ValidatorDefinition {
|
|
|
1173
1198
|
/** Validator name */
|
|
1174
1199
|
name: string;
|
|
1175
1200
|
/** Operations to apply validator to */
|
|
1176
|
-
operations?: Array<'create' | 'createMany' | 'update' | 'delete'>;
|
|
1201
|
+
operations?: Array<'create' | 'createMany' | 'update' | 'findOneAndUpdate' | 'delete'>;
|
|
1177
1202
|
/** Validation function */
|
|
1178
1203
|
validate: (context: RepositoryContext, repo?: RepositoryInstance) => void | Promise<void>;
|
|
1179
1204
|
}
|
|
@@ -1525,4 +1550,4 @@ type AllPluginMethods<TDoc> = {
|
|
|
1525
1550
|
*/
|
|
1526
1551
|
type WithPlugins<TDoc, TRepo extends RepositoryInstance = RepositoryInstance> = TRepo & AllPluginMethods<TDoc>;
|
|
1527
1552
|
//#endregion
|
|
1528
|
-
export {
|
|
1553
|
+
export { ReadOptions as $, HttpError as A, LookupBuilder as At, MinMaxResult as B, EventPayload as C, ValidatorDefinition as Ct, FindOneAndUpdateOptions as D, IControllerResponse as Dt, FieldRules as E, IController as Et, KeysetPaginationOptions as F, OperationOptions as G, ObjectId as H, KeysetPaginationResult as I, PartialBy as J, PaginationConfig as K, Logger as L, InferRawDoc as M, JsonSchema as N, GroupResult as O, IRequestContext as Ot, KeysOfType as P, PopulateSpec as Q, LookupPopulateOptions as R, EventHandlers as S, ValidationResult as St, FieldPreset as T, WithTransactionOptions as Tt, OffsetPaginationOptions as U, NonNullableFields as V, OffsetPaginationResult as W, PluginFunction as X, Plugin as Y, PluginType as Z, CrudSchemas as _, UpdateManyResult as _t, AnyDocument as a, RepositoryOptions as at, DeleteResult as b, UserContext as bt, CacheOperationOptions as c, SelectSpec as ct, CacheableOptions as d, SoftDeleteOptions as dt, ReadPreferenceType as et, CascadeOptions as f, SoftDeleteRepository as ft, CreateOptions as g, UpdateInput as gt, CreateInput as h, Strict as ht, AllPluginMethods as i, RepositoryOperation as it, InferDocument as j, LookupOptions as jt, HookMode as k, IResponseFormatter as kt, CacheOptions as l, SessionOptions as lt, CollationOptions as m, SortSpec as mt, AggregatePaginationOptions as n, RepositoryEvent as nt, AnyModel as o, RequiredBy as ot, CascadeRelation as p, SortDirection as pt, PaginationResult as q, AggregatePaginationResult as r, RepositoryInstance as rt, CacheAdapter as s, SchemaBuilderOptions as st, AggregateOptions as t, RepositoryContext as tt, CacheStats as u, SoftDeleteFilterMode as ut, DecodedCursor as v, UpdateOptions as vt, EventPhase as w, WithPlugins as wt, DocField as x, ValidationChainOptions as xt, DeepPartial as y, UpdateWithValidationResult as yt, LookupPopulateResult as z };
|
|
@@ -729,6 +729,7 @@ async function exists(Model, query, options = {}) {
|
|
|
729
729
|
//#endregion
|
|
730
730
|
//#region src/actions/update.ts
|
|
731
731
|
var update_exports = /* @__PURE__ */ __exportAll({
|
|
732
|
+
findOneAndUpdate: () => findOneAndUpdate,
|
|
732
733
|
increment: () => increment,
|
|
733
734
|
pullFromArray: () => pullFromArray,
|
|
734
735
|
pushToArray: () => pushToArray,
|
|
@@ -861,6 +862,28 @@ async function updateByQuery(Model, query, data, options = {}) {
|
|
|
861
862
|
return document;
|
|
862
863
|
}
|
|
863
864
|
/**
|
|
865
|
+
* Atomic findOneAndUpdate primitive.
|
|
866
|
+
*
|
|
867
|
+
* Returns the matched document (post-update by default) or null when no doc
|
|
868
|
+
* matches and `upsert` is false. Used by outbox relays, distributed locks,
|
|
869
|
+
* and workflow semaphores that need compare-and-set in a single round-trip.
|
|
870
|
+
*/
|
|
871
|
+
async function findOneAndUpdate(Model, filter, update, options = {}) {
|
|
872
|
+
assertUpdatePipelineAllowed(update, options.updatePipeline);
|
|
873
|
+
const returnDocument = options.returnDocument ?? "after";
|
|
874
|
+
return await Model.findOneAndUpdate(filter, update, {
|
|
875
|
+
returnDocument,
|
|
876
|
+
upsert: options.upsert ?? false,
|
|
877
|
+
runValidators: options.runValidators ?? true,
|
|
878
|
+
session: options.session,
|
|
879
|
+
...options.sort ? { sort: options.sort } : {},
|
|
880
|
+
...options.arrayFilters ? { arrayFilters: options.arrayFilters } : {},
|
|
881
|
+
...options.collation ? { collation: options.collation } : {},
|
|
882
|
+
...options.maxTimeMS ? { maxTimeMS: options.maxTimeMS } : {},
|
|
883
|
+
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
884
|
+
}).select(options.select || "").populate(parsePopulate(options.populate)).lean(options.lean ?? true);
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
864
887
|
* Increment field
|
|
865
888
|
*/
|
|
866
889
|
async function increment(Model, id, field, value = 1, options = {}) {
|
|
@@ -879,4 +902,4 @@ async function pullFromArray(Model, id, field, value, options = {}) {
|
|
|
879
902
|
return update(Model, id, { $pull: { [field]: value } }, options);
|
|
880
903
|
}
|
|
881
904
|
//#endregion
|
|
882
|
-
export {
|
|
905
|
+
export { upsert as _, count as a, LookupBuilder as b, getByQuery as c, deleteById as d, deleteByQuery as f, create_exports as g, createMany as h, update_exports as i, getOrCreate as l, create as m, update as n, exists as o, delete_exports as p, updateByQuery as r, getById as s, findOneAndUpdate as t, read_exports as u, aggregate_exports as v, distinct as y };
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "../mongooseToJsonSchema-
|
|
1
|
+
import { Q as PopulateSpec, ct as SelectSpec, mt as SortSpec } from "../types-D57SZJeE.mjs";
|
|
2
|
+
import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "../mongooseToJsonSchema-BZaKOXXI.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/cache-keys.d.ts
|
|
5
5
|
/**
|
|
@@ -1,12 +1,136 @@
|
|
|
1
1
|
import { n as debug, r as warn } from "./logger-DJ7egMnd.mjs";
|
|
2
|
-
import { a as
|
|
2
|
+
import { _ as upsert, a as count, b as LookupBuilder, c as getByQuery, d as deleteById, f as deleteByQuery, h as createMany, l as getOrCreate, m as create, n as update, o as exists, r as updateByQuery, s as getById, t as findOneAndUpdate, y as distinct } from "./update-yjSoNnWy.mjs";
|
|
3
3
|
import { n as parseDuplicateKeyError, t as createError } from "./error-Lw9GEAro.mjs";
|
|
4
|
-
import { t as PaginationEngine } from "./PaginationEngine-
|
|
4
|
+
import { t as PaginationEngine } from "./PaginationEngine-C2_tAvAD.mjs";
|
|
5
5
|
import { hasNearOperator, rewriteNearForCount } from "./query/primitives/geo.mjs";
|
|
6
6
|
import { r as isValidIdForType, t as getSchemaIdType } from "./id-resolution-e4BT9zAV.mjs";
|
|
7
7
|
import { a as byIdKey, c as listQueryKey, l as modelPattern, o as byQueryKey, r as getFieldsForUser, u as versionKey } from "./field-selection-dI0m4RBs.mjs";
|
|
8
8
|
import mongoose from "mongoose";
|
|
9
9
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
|
+
//#region src/operations.ts
|
|
11
|
+
/**
|
|
12
|
+
* The registry. Order intentionally groups by category for readability.
|
|
13
|
+
* Adding a new RepositoryOperation requires exactly one entry here, after
|
|
14
|
+
* which every bundled plugin auto-classifies it correctly.
|
|
15
|
+
*/
|
|
16
|
+
const OP_REGISTRY = {
|
|
17
|
+
create: {
|
|
18
|
+
policyKey: "data",
|
|
19
|
+
mutates: true,
|
|
20
|
+
hasIdContext: false
|
|
21
|
+
},
|
|
22
|
+
update: {
|
|
23
|
+
policyKey: "query",
|
|
24
|
+
mutates: true,
|
|
25
|
+
hasIdContext: true
|
|
26
|
+
},
|
|
27
|
+
findOneAndUpdate: {
|
|
28
|
+
policyKey: "query",
|
|
29
|
+
mutates: true,
|
|
30
|
+
hasIdContext: false
|
|
31
|
+
},
|
|
32
|
+
delete: {
|
|
33
|
+
policyKey: "query",
|
|
34
|
+
mutates: true,
|
|
35
|
+
hasIdContext: true
|
|
36
|
+
},
|
|
37
|
+
restore: {
|
|
38
|
+
policyKey: "query",
|
|
39
|
+
mutates: true,
|
|
40
|
+
hasIdContext: true
|
|
41
|
+
},
|
|
42
|
+
createMany: {
|
|
43
|
+
policyKey: "dataArray",
|
|
44
|
+
mutates: true,
|
|
45
|
+
hasIdContext: false
|
|
46
|
+
},
|
|
47
|
+
updateMany: {
|
|
48
|
+
policyKey: "query",
|
|
49
|
+
mutates: true,
|
|
50
|
+
hasIdContext: false
|
|
51
|
+
},
|
|
52
|
+
deleteMany: {
|
|
53
|
+
policyKey: "query",
|
|
54
|
+
mutates: true,
|
|
55
|
+
hasIdContext: false
|
|
56
|
+
},
|
|
57
|
+
bulkWrite: {
|
|
58
|
+
policyKey: "operations",
|
|
59
|
+
mutates: true,
|
|
60
|
+
hasIdContext: false
|
|
61
|
+
},
|
|
62
|
+
getById: {
|
|
63
|
+
policyKey: "query",
|
|
64
|
+
mutates: false,
|
|
65
|
+
hasIdContext: true
|
|
66
|
+
},
|
|
67
|
+
getByQuery: {
|
|
68
|
+
policyKey: "query",
|
|
69
|
+
mutates: false,
|
|
70
|
+
hasIdContext: false
|
|
71
|
+
},
|
|
72
|
+
getOne: {
|
|
73
|
+
policyKey: "query",
|
|
74
|
+
mutates: false,
|
|
75
|
+
hasIdContext: false
|
|
76
|
+
},
|
|
77
|
+
findAll: {
|
|
78
|
+
policyKey: "query",
|
|
79
|
+
mutates: false,
|
|
80
|
+
hasIdContext: false
|
|
81
|
+
},
|
|
82
|
+
getOrCreate: {
|
|
83
|
+
policyKey: "query",
|
|
84
|
+
mutates: false,
|
|
85
|
+
hasIdContext: false
|
|
86
|
+
},
|
|
87
|
+
count: {
|
|
88
|
+
policyKey: "query",
|
|
89
|
+
mutates: false,
|
|
90
|
+
hasIdContext: false
|
|
91
|
+
},
|
|
92
|
+
exists: {
|
|
93
|
+
policyKey: "query",
|
|
94
|
+
mutates: false,
|
|
95
|
+
hasIdContext: false
|
|
96
|
+
},
|
|
97
|
+
distinct: {
|
|
98
|
+
policyKey: "query",
|
|
99
|
+
mutates: false,
|
|
100
|
+
hasIdContext: false
|
|
101
|
+
},
|
|
102
|
+
aggregate: {
|
|
103
|
+
policyKey: "query",
|
|
104
|
+
mutates: false,
|
|
105
|
+
hasIdContext: false
|
|
106
|
+
},
|
|
107
|
+
getAll: {
|
|
108
|
+
policyKey: "filters",
|
|
109
|
+
mutates: false,
|
|
110
|
+
hasIdContext: false
|
|
111
|
+
},
|
|
112
|
+
aggregatePaginate: {
|
|
113
|
+
policyKey: "filters",
|
|
114
|
+
mutates: false,
|
|
115
|
+
hasIdContext: false
|
|
116
|
+
},
|
|
117
|
+
lookupPopulate: {
|
|
118
|
+
policyKey: "filters",
|
|
119
|
+
mutates: false,
|
|
120
|
+
hasIdContext: false
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
/** All known repository operations, in registry order. */
|
|
124
|
+
const ALL_OPERATIONS = Object.keys(OP_REGISTRY);
|
|
125
|
+
/** Operations that mutate the database. Drives audit + cache invalidation lists. */
|
|
126
|
+
const MUTATING_OPERATIONS = ALL_OPERATIONS.filter((op) => OP_REGISTRY[op].mutates);
|
|
127
|
+
/** Operations that don't mutate. Drives default cacheable ops. */
|
|
128
|
+
const READ_OPERATIONS = ALL_OPERATIONS.filter((op) => !OP_REGISTRY[op].mutates);
|
|
129
|
+
/** Filter ops by their policy injection key. */
|
|
130
|
+
function operationsByPolicyKey(key) {
|
|
131
|
+
return ALL_OPERATIONS.filter((op) => OP_REGISTRY[op].policyKey === key);
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
10
134
|
//#region src/plugins/aggregate-helpers.plugin.ts
|
|
11
135
|
/**
|
|
12
136
|
* Aggregate helpers plugin
|
|
@@ -99,6 +223,22 @@ function auditLogPlugin(logger) {
|
|
|
99
223
|
organizationId: context.organizationId
|
|
100
224
|
});
|
|
101
225
|
});
|
|
226
|
+
repo.on("after:findOneAndUpdate", ({ context, result }) => {
|
|
227
|
+
if (!result) return;
|
|
228
|
+
logger?.info?.("Document upserted/updated (findOneAndUpdate)", {
|
|
229
|
+
model: context.model || repo.model,
|
|
230
|
+
id: result?.[repo.idField || "_id"],
|
|
231
|
+
userId: context.user?._id || context.user?.id,
|
|
232
|
+
organizationId: context.organizationId
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
repo.on("error:findOneAndUpdate", ({ context, error }) => {
|
|
236
|
+
logger?.error?.("findOneAndUpdate failed", {
|
|
237
|
+
model: context.model || repo.model,
|
|
238
|
+
error: error.message,
|
|
239
|
+
userId: context.user?._id || context.user?.id
|
|
240
|
+
});
|
|
241
|
+
});
|
|
102
242
|
repo.on("after:delete", ({ context }) => {
|
|
103
243
|
logger?.info?.("Document deleted", {
|
|
104
244
|
model: context.model || repo.model,
|
|
@@ -178,6 +318,7 @@ function getAuditModel(collectionName, ttlDays) {
|
|
|
178
318
|
enum: [
|
|
179
319
|
"create",
|
|
180
320
|
"update",
|
|
321
|
+
"findOneAndUpdate",
|
|
181
322
|
"delete"
|
|
182
323
|
]
|
|
183
324
|
},
|
|
@@ -327,6 +468,19 @@ function auditTrailPlugin(options = {}) {
|
|
|
327
468
|
});
|
|
328
469
|
});
|
|
329
470
|
}
|
|
471
|
+
if (opsSet.has("findOneAndUpdate")) repo.on("after:findOneAndUpdate", ({ context, result }) => {
|
|
472
|
+
if (!result) return;
|
|
473
|
+
const doc = result;
|
|
474
|
+
const idKey = repo.idField || "_id";
|
|
475
|
+
writeAudit(AuditModel, {
|
|
476
|
+
model: context.model || repo.model,
|
|
477
|
+
operation: "findOneAndUpdate",
|
|
478
|
+
documentId: doc?.[idKey],
|
|
479
|
+
userId: getUserId(context),
|
|
480
|
+
orgId: context.organizationId,
|
|
481
|
+
metadata: metadata?.(context)
|
|
482
|
+
});
|
|
483
|
+
});
|
|
330
484
|
if (opsSet.has("delete")) repo.on("after:delete", ({ context }) => {
|
|
331
485
|
writeAudit(AuditModel, {
|
|
332
486
|
model: context.model || repo.model,
|
|
@@ -1576,10 +1730,10 @@ var Repository = class {
|
|
|
1576
1730
|
*/
|
|
1577
1731
|
async findAll(filters = {}, options = {}) {
|
|
1578
1732
|
const context = await this._buildContext("findAll", {
|
|
1579
|
-
filters,
|
|
1733
|
+
query: filters,
|
|
1580
1734
|
...options
|
|
1581
1735
|
});
|
|
1582
|
-
const resolvedFilters = context.
|
|
1736
|
+
const resolvedFilters = context.query ?? filters;
|
|
1583
1737
|
try {
|
|
1584
1738
|
const query = this.Model.find(resolvedFilters);
|
|
1585
1739
|
const sortSpec = context.sort || options.sort;
|
|
@@ -1872,6 +2026,64 @@ var Repository = class {
|
|
|
1872
2026
|
}
|
|
1873
2027
|
}
|
|
1874
2028
|
/**
|
|
2029
|
+
* Atomic findOneAndUpdate (compare-and-set primitive).
|
|
2030
|
+
*
|
|
2031
|
+
* Single round-trip match-and-mutate for outbox relays, distributed locks,
|
|
2032
|
+
* and workflow semaphores. Goes through the full hook pipeline so
|
|
2033
|
+
* multi-tenant scope, soft-delete, audit, and cache plugins all apply.
|
|
2034
|
+
*
|
|
2035
|
+
* Returns the matched document (post-update by default) or `null` when no
|
|
2036
|
+
* document matches and `upsert` is false.
|
|
2037
|
+
*
|
|
2038
|
+
* @example FIFO claim-lease for an outbox worker
|
|
2039
|
+
* ```ts
|
|
2040
|
+
* const claimed = await outboxRepo.findOneAndUpdate(
|
|
2041
|
+
* { status: 'pending', leaseExpiresAt: { $lt: new Date() } },
|
|
2042
|
+
* { $set: { status: 'processing', leaseExpiresAt: leaseUntil, leasedBy: workerId } },
|
|
2043
|
+
* { sort: { createdAt: 1 }, returnDocument: 'after' },
|
|
2044
|
+
* );
|
|
2045
|
+
* if (!claimed) return; // queue empty
|
|
2046
|
+
* ```
|
|
2047
|
+
*
|
|
2048
|
+
* @example CAS upsert
|
|
2049
|
+
* ```ts
|
|
2050
|
+
* const lock = await locksRepo.findOneAndUpdate(
|
|
2051
|
+
* { _id: lockKey, ownerId: { $in: [null, workerId] } },
|
|
2052
|
+
* { $set: { ownerId: workerId, expiresAt: leaseUntil } },
|
|
2053
|
+
* { upsert: true },
|
|
2054
|
+
* );
|
|
2055
|
+
* ```
|
|
2056
|
+
*/
|
|
2057
|
+
async findOneAndUpdate(filter, update, options = {}) {
|
|
2058
|
+
const context = await this._buildContext("findOneAndUpdate", {
|
|
2059
|
+
query: filter,
|
|
2060
|
+
data: update,
|
|
2061
|
+
...options
|
|
2062
|
+
});
|
|
2063
|
+
try {
|
|
2064
|
+
const finalQuery = context.query || filter;
|
|
2065
|
+
const finalUpdate = context.data || update;
|
|
2066
|
+
const result = await findOneAndUpdate(this.Model, finalQuery, finalUpdate, {
|
|
2067
|
+
...options,
|
|
2068
|
+
sort: options.sort,
|
|
2069
|
+
returnDocument: options.returnDocument ?? "after",
|
|
2070
|
+
upsert: options.upsert ?? false,
|
|
2071
|
+
session: options.session
|
|
2072
|
+
});
|
|
2073
|
+
await this._emitHook("after:findOneAndUpdate", {
|
|
2074
|
+
context,
|
|
2075
|
+
result
|
|
2076
|
+
});
|
|
2077
|
+
return result;
|
|
2078
|
+
} catch (error) {
|
|
2079
|
+
await this._emitErrorHook("error:findOneAndUpdate", {
|
|
2080
|
+
context,
|
|
2081
|
+
error
|
|
2082
|
+
});
|
|
2083
|
+
throw this._handleError(error);
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
/**
|
|
1875
2087
|
* Delete a document by ID.
|
|
1876
2088
|
*
|
|
1877
2089
|
* By default the behavior is decided by the plugin stack:
|
|
@@ -2100,9 +2312,9 @@ var Repository = class {
|
|
|
2100
2312
|
};
|
|
2101
2313
|
if (isKeyset && sort) {
|
|
2102
2314
|
const parsedSort = this._parseSort(sort);
|
|
2103
|
-
const { validateKeysetSort } = await import("./sort-
|
|
2104
|
-
const { encodeCursor, resolveCursorFilter } = await import("./cursor-
|
|
2105
|
-
const { getPrimaryField } = await import("./sort-
|
|
2315
|
+
const { validateKeysetSort } = await import("./sort-CrZjTK25.mjs").then((n) => n.n);
|
|
2316
|
+
const { encodeCursor, resolveCursorFilter } = await import("./cursor-J84rR6wG.mjs").then((n) => n.t);
|
|
2317
|
+
const { getPrimaryField } = await import("./sort-CrZjTK25.mjs").then((n) => n.n);
|
|
2106
2318
|
const normalizedSort = validateKeysetSort(parsedSort, this._pagination.config.strictKeysetSortFields);
|
|
2107
2319
|
const cursorVersion = this._pagination.config.cursorVersion ?? 1;
|
|
2108
2320
|
const minCursorVersion = this._pagination.config.minCursorVersion ?? 1;
|
|
@@ -2823,6 +3035,22 @@ function cachePlugin(options) {
|
|
|
2823
3035
|
await bumpVersion();
|
|
2824
3036
|
});
|
|
2825
3037
|
/**
|
|
3038
|
+
* after:findOneAndUpdate — atomic CAS may insert (upsert) or mutate.
|
|
3039
|
+
* Result carries the matched/inserted doc; invalidate that ID and bump
|
|
3040
|
+
* version. Null result (no match, no upsert) is a no-op.
|
|
3041
|
+
*/
|
|
3042
|
+
repo.on("after:findOneAndUpdate", async (payload) => {
|
|
3043
|
+
const { result } = payload;
|
|
3044
|
+
if (!result) return;
|
|
3045
|
+
const idKey = repo.idField || "_id";
|
|
3046
|
+
const id = result?.[idKey];
|
|
3047
|
+
if (id == null) {
|
|
3048
|
+
await bumpVersion();
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
3051
|
+
await Promise.all([invalidateById(String(id)), bumpVersion()]);
|
|
3052
|
+
});
|
|
3053
|
+
/**
|
|
2826
3054
|
* after:delete - Invalidate by ID and bump version
|
|
2827
3055
|
*/
|
|
2828
3056
|
repo.on("after:delete", async (payload) => {
|
|
@@ -3781,45 +4009,20 @@ function mongoOperationsPlugin() {
|
|
|
3781
4009
|
*/
|
|
3782
4010
|
function multiTenantPlugin(options = {}) {
|
|
3783
4011
|
const { tenantField = "organizationId", contextKey = "organizationId", required = true, skipOperations = [], skipWhen, resolveContext, fieldType = "string" } = options;
|
|
3784
|
-
const
|
|
3785
|
-
"
|
|
3786
|
-
"
|
|
3787
|
-
|
|
3788
|
-
"lookupPopulate"
|
|
3789
|
-
];
|
|
3790
|
-
const queryReadOps = [
|
|
3791
|
-
"getById",
|
|
3792
|
-
"getByQuery",
|
|
3793
|
-
"getOne",
|
|
3794
|
-
"count",
|
|
3795
|
-
"exists",
|
|
3796
|
-
"getOrCreate",
|
|
3797
|
-
"distinct",
|
|
3798
|
-
"aggregate"
|
|
3799
|
-
];
|
|
3800
|
-
const constrainedWriteOps = [
|
|
3801
|
-
"update",
|
|
3802
|
-
"delete",
|
|
3803
|
-
"restore"
|
|
3804
|
-
];
|
|
3805
|
-
const filterReadOps = ["getDeleted"];
|
|
3806
|
-
const createOps = ["create", "createMany"];
|
|
3807
|
-
const batchQueryOps = ["updateMany", "deleteMany"];
|
|
3808
|
-
const bulkOps = ["bulkWrite"];
|
|
3809
|
-
const allOps = [
|
|
3810
|
-
...filterOps,
|
|
3811
|
-
...filterReadOps,
|
|
3812
|
-
...queryReadOps,
|
|
3813
|
-
...constrainedWriteOps,
|
|
3814
|
-
...createOps,
|
|
3815
|
-
...batchQueryOps,
|
|
3816
|
-
...bulkOps
|
|
3817
|
-
];
|
|
4012
|
+
const extraOps = [{
|
|
4013
|
+
op: "getDeleted",
|
|
4014
|
+
policyKey: "filters"
|
|
4015
|
+
}];
|
|
3818
4016
|
return {
|
|
3819
4017
|
name: "multi-tenant",
|
|
3820
4018
|
apply(repo) {
|
|
3821
|
-
|
|
4019
|
+
const allOps = [...ALL_OPERATIONS.map((op) => ({
|
|
4020
|
+
op,
|
|
4021
|
+
policyKey: OP_REGISTRY[op].policyKey
|
|
4022
|
+
})), ...extraOps];
|
|
4023
|
+
for (const { op, policyKey } of allOps) {
|
|
3822
4024
|
if (skipOperations.includes(op)) continue;
|
|
4025
|
+
if (policyKey === "none") continue;
|
|
3823
4026
|
repo.on(`before:${op}`, (context) => {
|
|
3824
4027
|
if (skipWhen?.(context, op)) return;
|
|
3825
4028
|
let tenantId = context[contextKey];
|
|
@@ -3830,45 +4033,49 @@ function multiTenantPlugin(options = {}) {
|
|
|
3830
4033
|
if (!tenantId && required) throw new Error(`[mongokit] Multi-tenant: Missing '${contextKey}' in context for '${op}'. Pass it via options or set required: false.`);
|
|
3831
4034
|
if (!tenantId) return;
|
|
3832
4035
|
const castId = fieldType === "objectId" ? new mongoose.Types.ObjectId(tenantId) : tenantId;
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
};
|
|
3853
|
-
if (op === "bulkWrite" && context.operations) {
|
|
3854
|
-
const ops = context.operations;
|
|
3855
|
-
for (const subOp of ops) {
|
|
3856
|
-
for (const key of [
|
|
3857
|
-
"updateOne",
|
|
3858
|
-
"updateMany",
|
|
3859
|
-
"deleteOne",
|
|
3860
|
-
"deleteMany",
|
|
3861
|
-
"replaceOne"
|
|
3862
|
-
]) {
|
|
3863
|
-
const opBody = subOp[key];
|
|
3864
|
-
if (opBody?.filter) opBody.filter = {
|
|
3865
|
-
...opBody.filter,
|
|
3866
|
-
[tenantField]: castId
|
|
3867
|
-
};
|
|
4036
|
+
switch (policyKey) {
|
|
4037
|
+
case "filters":
|
|
4038
|
+
context.filters = {
|
|
4039
|
+
...context.filters,
|
|
4040
|
+
[tenantField]: castId
|
|
4041
|
+
};
|
|
4042
|
+
break;
|
|
4043
|
+
case "query":
|
|
4044
|
+
context.query = {
|
|
4045
|
+
...context.query,
|
|
4046
|
+
[tenantField]: castId
|
|
4047
|
+
};
|
|
4048
|
+
break;
|
|
4049
|
+
case "data":
|
|
4050
|
+
if (context.data) context.data[tenantField] = castId;
|
|
4051
|
+
break;
|
|
4052
|
+
case "dataArray":
|
|
4053
|
+
if (context.dataArray) {
|
|
4054
|
+
for (const doc of context.dataArray) if (doc && typeof doc === "object") doc[tenantField] = castId;
|
|
3868
4055
|
}
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
4056
|
+
break;
|
|
4057
|
+
case "operations":
|
|
4058
|
+
if (context.operations) {
|
|
4059
|
+
const ops = context.operations;
|
|
4060
|
+
for (const subOp of ops) {
|
|
4061
|
+
for (const key of [
|
|
4062
|
+
"updateOne",
|
|
4063
|
+
"updateMany",
|
|
4064
|
+
"deleteOne",
|
|
4065
|
+
"deleteMany",
|
|
4066
|
+
"replaceOne"
|
|
4067
|
+
]) {
|
|
4068
|
+
const opBody = subOp[key];
|
|
4069
|
+
if (opBody?.filter) opBody.filter = {
|
|
4070
|
+
...opBody.filter,
|
|
4071
|
+
[tenantField]: castId
|
|
4072
|
+
};
|
|
4073
|
+
}
|
|
4074
|
+
const insertBody = subOp.insertOne;
|
|
4075
|
+
if (insertBody?.document) insertBody.document[tenantField] = castId;
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
break;
|
|
3872
4079
|
}
|
|
3873
4080
|
}, { priority: HOOK_PRIORITY.POLICY });
|
|
3874
4081
|
}
|
|
@@ -3877,24 +4084,26 @@ function multiTenantPlugin(options = {}) {
|
|
|
3877
4084
|
}
|
|
3878
4085
|
//#endregion
|
|
3879
4086
|
//#region src/plugins/observability.plugin.ts
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
4087
|
+
/**
|
|
4088
|
+
* Observability Plugin
|
|
4089
|
+
*
|
|
4090
|
+
* Adds operation timing, structured metrics, and APM hook points.
|
|
4091
|
+
* Works with any monitoring system — just provide an onMetric callback.
|
|
4092
|
+
*
|
|
4093
|
+
* @example
|
|
4094
|
+
* ```typescript
|
|
4095
|
+
* const repo = new Repository(User, [
|
|
4096
|
+
* observabilityPlugin({
|
|
4097
|
+
* onMetric: (metric) => {
|
|
4098
|
+
* // Send to DataDog, New Relic, OpenTelemetry, or console
|
|
4099
|
+
* console.log(`${metric.operation} took ${metric.durationMs}ms`);
|
|
4100
|
+
* statsd.histogram('mongokit.operation', metric.durationMs, { op: metric.operation });
|
|
4101
|
+
* },
|
|
4102
|
+
* }),
|
|
4103
|
+
* ]);
|
|
4104
|
+
* ```
|
|
4105
|
+
*/
|
|
4106
|
+
const DEFAULT_OPS = ALL_OPERATIONS;
|
|
3898
4107
|
const timers = /* @__PURE__ */ new WeakMap();
|
|
3899
4108
|
function observabilityPlugin(options) {
|
|
3900
4109
|
const { onMetric, slowThresholdMs } = options;
|
|
@@ -4065,22 +4274,19 @@ function softDeletePlugin(options = {}) {
|
|
|
4065
4274
|
};
|
|
4066
4275
|
}
|
|
4067
4276
|
};
|
|
4068
|
-
|
|
4069
|
-
"
|
|
4070
|
-
"
|
|
4071
|
-
"
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
"
|
|
4077
|
-
|
|
4078
|
-
"
|
|
4079
|
-
"
|
|
4080
|
-
|
|
4081
|
-
"distinct",
|
|
4082
|
-
"aggregate"
|
|
4083
|
-
]) repo.on(`before:${op}`, injectDeleteFilterToQuery, { priority: HOOK_PRIORITY.POLICY });
|
|
4277
|
+
const SOFT_DELETE_SPECIAL = new Set([
|
|
4278
|
+
"updateMany",
|
|
4279
|
+
"deleteMany",
|
|
4280
|
+
"bulkWrite"
|
|
4281
|
+
]);
|
|
4282
|
+
for (const op of ALL_OPERATIONS) {
|
|
4283
|
+
if (SOFT_DELETE_SPECIAL.has(op)) continue;
|
|
4284
|
+
const desc = OP_REGISTRY[op];
|
|
4285
|
+
const isFilterableMutation = op === "findOneAndUpdate";
|
|
4286
|
+
if (desc.mutates && !isFilterableMutation) continue;
|
|
4287
|
+
if (desc.policyKey === "filters") repo.on(`before:${op}`, injectDeleteFilterToFilters, { priority: HOOK_PRIORITY.POLICY });
|
|
4288
|
+
else if (desc.policyKey === "query") repo.on(`before:${op}`, injectDeleteFilterToQuery, { priority: HOOK_PRIORITY.POLICY });
|
|
4289
|
+
}
|
|
4084
4290
|
repo.on("before:updateMany", (context) => {
|
|
4085
4291
|
if (options.soft !== false) {
|
|
4086
4292
|
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
@@ -4102,24 +4308,6 @@ function softDeletePlugin(options = {}) {
|
|
|
4102
4308
|
context.softDeleted = true;
|
|
4103
4309
|
}
|
|
4104
4310
|
}, { priority: HOOK_PRIORITY.POLICY });
|
|
4105
|
-
repo.on("before:aggregate", (context) => {
|
|
4106
|
-
if (options.soft !== false) {
|
|
4107
|
-
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
4108
|
-
if (Object.keys(deleteFilter).length > 0) context.query = {
|
|
4109
|
-
...context.query || {},
|
|
4110
|
-
...deleteFilter
|
|
4111
|
-
};
|
|
4112
|
-
}
|
|
4113
|
-
}, { priority: HOOK_PRIORITY.POLICY });
|
|
4114
|
-
repo.on("before:aggregatePaginate", (context) => {
|
|
4115
|
-
if (options.soft !== false) {
|
|
4116
|
-
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
4117
|
-
if (Object.keys(deleteFilter).length > 0) context.filters = {
|
|
4118
|
-
...context.filters || {},
|
|
4119
|
-
...deleteFilter
|
|
4120
|
-
};
|
|
4121
|
-
}
|
|
4122
|
-
}, { priority: HOOK_PRIORITY.POLICY });
|
|
4123
4311
|
if (addRestoreMethod) {
|
|
4124
4312
|
const restoreMethod = async function(id, restoreOptions = {}) {
|
|
4125
4313
|
const context = await this._buildContext("restore", {
|
|
@@ -4348,6 +4536,20 @@ function timestampPlugin() {
|
|
|
4348
4536
|
if (!context.data) return;
|
|
4349
4537
|
context.data.updatedAt = /* @__PURE__ */ new Date();
|
|
4350
4538
|
});
|
|
4539
|
+
repo.on("before:findOneAndUpdate", (context) => {
|
|
4540
|
+
if (!context.data) return;
|
|
4541
|
+
const now = /* @__PURE__ */ new Date();
|
|
4542
|
+
if (Array.isArray(context.data)) return;
|
|
4543
|
+
const update = context.data;
|
|
4544
|
+
if (Object.keys(update).some((k) => k.startsWith("$"))) {
|
|
4545
|
+
const set = update.$set || {};
|
|
4546
|
+
set.updatedAt = now;
|
|
4547
|
+
update.$set = set;
|
|
4548
|
+
const setOnInsert = update.$setOnInsert || {};
|
|
4549
|
+
if (!("createdAt" in setOnInsert)) setOnInsert.createdAt = now;
|
|
4550
|
+
update.$setOnInsert = setOnInsert;
|
|
4551
|
+
} else update.updatedAt = now;
|
|
4552
|
+
});
|
|
4351
4553
|
}
|
|
4352
4554
|
};
|
|
4353
4555
|
}
|
|
@@ -4374,6 +4576,7 @@ function validationChainPlugin(validators = [], options = {}) {
|
|
|
4374
4576
|
const validatorsByOperation = {
|
|
4375
4577
|
create: [],
|
|
4376
4578
|
update: [],
|
|
4579
|
+
findOneAndUpdate: [],
|
|
4377
4580
|
delete: [],
|
|
4378
4581
|
createMany: []
|
|
4379
4582
|
};
|
|
@@ -4412,6 +4615,7 @@ function validationChainPlugin(validators = [], options = {}) {
|
|
|
4412
4615
|
repo.on("before:create", async (context) => runValidators("create", context));
|
|
4413
4616
|
repo.on("before:createMany", async (context) => runValidators("createMany", context));
|
|
4414
4617
|
repo.on("before:update", async (context) => runValidators("update", context));
|
|
4618
|
+
repo.on("before:findOneAndUpdate", async (context) => runValidators("findOneAndUpdate", context));
|
|
4415
4619
|
repo.on("before:delete", async (context) => runValidators("delete", context));
|
|
4416
4620
|
}
|
|
4417
4621
|
};
|
|
@@ -4500,4 +4704,4 @@ function uniqueField(field, errorMessage) {
|
|
|
4500
4704
|
};
|
|
4501
4705
|
}
|
|
4502
4706
|
//#endregion
|
|
4503
|
-
export { AuditTrailQuery as A, cachePlugin as C, withTransaction as D, isTransactionUnsupported as E, auditLogPlugin as M, aggregateHelpersPlugin as N, AggregationBuilder as O, cascadePlugin as S, Repository as T, customIdPlugin as _, uniqueField as a, prefixedId as b, createTenantContext as c, observabilityPlugin as d, multiTenantPlugin as f, elasticSearchPlugin as g, fieldFilterPlugin as h, requireField as i, auditTrailPlugin as j, batchOperationsPlugin as k, subdocumentPlugin as l, methodRegistryPlugin as m, blockIf as n, validationChainPlugin as o, mongoOperationsPlugin as p, immutableField as r, timestampPlugin as s, autoInject as t, softDeletePlugin as u, dateSequentialId as v, HOOK_PRIORITY as w, sequentialId as x, getNextSequence as y };
|
|
4707
|
+
export { AuditTrailQuery as A, cachePlugin as C, withTransaction as D, isTransactionUnsupported as E, MUTATING_OPERATIONS as F, OP_REGISTRY as I, READ_OPERATIONS as L, auditLogPlugin as M, aggregateHelpersPlugin as N, AggregationBuilder as O, ALL_OPERATIONS as P, operationsByPolicyKey as R, cascadePlugin as S, Repository as T, customIdPlugin as _, uniqueField as a, prefixedId as b, createTenantContext as c, observabilityPlugin as d, multiTenantPlugin as f, elasticSearchPlugin as g, fieldFilterPlugin as h, requireField as i, auditTrailPlugin as j, batchOperationsPlugin as k, subdocumentPlugin as l, methodRegistryPlugin as m, blockIf as n, validationChainPlugin as o, mongoOperationsPlugin as p, immutableField as r, timestampPlugin as s, autoInject as t, softDeletePlugin as u, dateSequentialId as v, HOOK_PRIORITY as w, sequentialId as x, getNextSequence as y };
|
package/dist/{validation-chain.plugin-Be9rG04B.d.mts → validation-chain.plugin-wGF34Ym-.d.mts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ct as ValidatorDefinition, H as ObjectId, L as Logger, Q as PopulateSpec, T as FieldPreset, W as OffsetPaginationResult, Y as Plugin, ct as SelectSpec, dt as SoftDeleteOptions, f as CascadeOptions, l as CacheOptions, mt as SortSpec, rt as RepositoryInstance, tt as RepositoryContext, u as CacheStats, xt as ValidationChainOptions } from "./types-D57SZJeE.mjs";
|
|
2
2
|
import mongoose, { ClientSession } from "mongoose";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
|
|
@@ -119,7 +119,7 @@ interface AuditTrailOptions {
|
|
|
119
119
|
*/
|
|
120
120
|
excludeFields?: string[];
|
|
121
121
|
}
|
|
122
|
-
type AuditOperation = 'create' | 'update' | 'delete';
|
|
122
|
+
type AuditOperation = 'create' | 'update' | 'delete' | 'findOneAndUpdate';
|
|
123
123
|
interface AuditEntry {
|
|
124
124
|
model: string;
|
|
125
125
|
operation: AuditOperation;
|
|
@@ -1095,7 +1095,7 @@ declare function createTenantContext(): TenantContext;
|
|
|
1095
1095
|
declare function timestampPlugin(): Plugin;
|
|
1096
1096
|
//#endregion
|
|
1097
1097
|
//#region src/plugins/validation-chain.plugin.d.ts
|
|
1098
|
-
type OperationType = 'create' | 'createMany' | 'update' | 'delete';
|
|
1098
|
+
type OperationType = 'create' | 'createMany' | 'update' | 'findOneAndUpdate' | 'delete';
|
|
1099
1099
|
/**
|
|
1100
1100
|
* Validation chain plugin
|
|
1101
1101
|
*
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|