@classytic/mongokit 3.43.1 → 3.44.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/README.md +14 -0
- package/dist/{PaginationEngine-DZnkbSrr.mjs → PaginationEngine-C9iS0U5l.mjs} +13 -27
- package/dist/{PaginationEngine-CRHyuUtw.d.mts → PaginationEngine-D17AthKw.d.mts} +1 -3
- package/dist/{Repository-DnL4xk5w.d.mts → Repository-B6oL6OMv.d.mts} +33 -11
- package/dist/{Repository-Dj6xqPxJ.mjs → Repository-eMRYZ_2Y.mjs} +204 -92
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.mjs +2 -2
- package/dist/{actions-ChYfkPYP.mjs → actions-DExyXMTy.mjs} +3 -4
- package/dist/adapter/index.d.mts +6 -10
- package/dist/adapter/index.mjs +1 -1
- package/dist/{adapter-CkMoMF83.mjs → adapter-Qzgc3ZD_.mjs} +4 -6
- package/dist/ai/index.d.mts +21 -8
- package/dist/ai/index.mjs +15 -9
- package/dist/better-auth/index.d.mts +17 -19
- package/dist/better-auth/index.mjs +3 -4
- package/dist/{coercion-BjdPX3YF.d.mts → coercion-COp9DRNw.d.mts} +0 -2
- package/dist/{create-repository-CJtVdwig.d.mts → create-repository-BOFUYj1l.d.mts} +5 -7
- package/dist/{create-repository-UjwPWR1z.mjs → create-repository-D7MQpIZo.mjs} +4 -5
- package/dist/{derive-DRBiegRH.mjs → derive-Dxsc31fV.mjs} +3 -6
- package/dist/{error-BuByZwKU.mjs → error-DjdmPLWO.mjs} +1 -2
- package/dist/{field-selection-FSQFLpsU.mjs → field-selection-DPFaFw9Y.mjs} +1 -2
- package/dist/{id-chunks-BmAwsqNk.mjs → id-chunks-DH-RAZWG.mjs} +13 -8
- package/dist/{id-resolution-BqDrk0S2.mjs → id-resolution-Cqh49d9J.mjs} +1 -2
- package/dist/idempotency/index.d.mts +4 -7
- package/dist/idempotency/index.mjs +1 -2
- package/dist/{index-SYF8N28D.d.mts → index-8QUEsOFI.d.mts} +3 -4
- package/dist/{index-C0AjVqX3.d.mts → index-ehGZLbrd.d.mts} +2 -8
- package/dist/index.d.mts +63 -96
- package/dist/index.mjs +36 -52
- package/dist/indexes/verify-indexes.d.mts +8 -11
- package/dist/indexes/verify-indexes.mjs +1 -2
- package/dist/{indexes-DIjMpYES.d.mts → indexes-FfyOuhDK.d.mts} +0 -2
- package/dist/{join-scope-DSAznE8E.mjs → join-scope-C1gOtZ59.mjs} +2 -3
- package/dist/kernel-conformance/index.d.mts +39 -13
- package/dist/kernel-conformance/index.mjs +4 -7
- package/dist/lock/index.d.mts +134 -7
- package/dist/lock/index.mjs +349 -14
- package/dist/{logger-K7dPmu2U.mjs → logger-hbWOlj_X.mjs} +1 -2
- package/dist/{method-registry.plugin-C63pGn1d.mjs → method-registry.plugin-CGAepsBU.mjs} +3 -5
- package/dist/{model-registry-ClKtWiHa.mjs → model-registry-DrVfJ3Nt.mjs} +1 -2
- package/dist/{mongooseToJsonSchema-C3k4ide0.mjs → mongooseToJsonSchema-DMDotz4_.mjs} +2 -3
- package/dist/{multi-tenant.plugin-B_q9NUHc.d.mts → multi-tenant.plugin-DfeDMiI8.d.mts} +143 -11
- package/dist/{operations-XiFgG5US.d.mts → operations-Dw9OFV0V.d.mts} +14 -5
- package/dist/outbox/index.d.mts +24 -9
- package/dist/outbox/index.mjs +17 -6
- package/dist/pagination/PaginationEngine.d.mts +1 -1
- package/dist/pagination/PaginationEngine.mjs +1 -1
- package/dist/pagination/utils/limits.d.mts +6 -9
- package/dist/pagination/utils/limits.mjs +2 -3
- package/dist/{pagination-D6psses0.d.mts → pagination-DAUg5zOY.d.mts} +2 -10
- package/dist/{plugin-options-Cirmb4Kp.d.mts → plugin-options-Bpcuz9kS.d.mts} +2 -4
- package/dist/plugins/index.d.mts +6 -7
- package/dist/plugins/index.mjs +6 -7
- package/dist/query/primitives/coercion.d.mts +1 -1
- package/dist/query/primitives/coercion.mjs +2 -3
- package/dist/query/primitives/geo.d.mts +11 -14
- package/dist/query/primitives/geo.mjs +1 -2
- package/dist/query/primitives/indexes.d.mts +1 -1
- package/dist/query/primitives/indexes.mjs +1 -2
- package/dist/{query-defaults-BxUcSOoF.mjs → query-defaults-aUoKlEbh.mjs} +2 -3
- package/dist/read-model/index.d.mts +18 -21
- package/dist/read-model/index.mjs +3 -4
- package/dist/{repository-MqAP409e.d.mts → repository-DzVIwhU2.d.mts} +25 -29
- package/dist/retention-purge-DqcYvRnG.d.mts +35 -0
- package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-D8jQpDG7.mjs} +1 -2
- package/dist/search/index.d.mts +1 -1
- package/dist/search/index.mjs +1 -1
- package/dist/sync/index.d.mts +95 -15
- package/dist/sync/index.mjs +308 -62
- package/dist/tenant/index.d.mts +8 -11
- package/dist/tenant/index.mjs +1 -2
- package/dist/testkit/index.d.mts +179 -23
- package/dist/testkit/index.mjs +421 -23
- package/dist/{timestamp.plugin-DpOWavVI.mjs → timestamp.plugin-Bz_zL9PX.mjs} +192 -49
- package/dist/{to-plain-vksRrLtc.mjs → to-plain-CEKv_ylg.mjs} +2 -4
- package/dist/{to-plain-o5tUY2nV.d.mts → to-plain-PO5r1Qoy.d.mts} +2 -16
- package/dist/{transaction-DmiB4k2P.mjs → transaction-C2PFxfIv.mjs} +5 -8
- package/dist/{type-utils-CLzRFtIA.d.mts → type-utils-CKvuewAL.d.mts} +0 -2
- package/dist/{update-WgeAUJ_I.mjs → update-DcfmNbJe.mjs} +12 -20
- package/dist/usage/index.d.mts +2 -5
- package/dist/usage/index.mjs +8 -6
- package/dist/utils/index.d.mts +8 -10
- package/dist/utils/index.mjs +7 -7
- package/dist/{validation-chain.plugin-BAeC5eVT.d.mts → validation-chain.plugin-B3gZCZj4.d.mts} +135 -48
- package/dist/{validation-chain.plugin-DRApTmkN.mjs → validation-chain.plugin-DNY6MIF6.mjs} +207 -55
- package/llms.txt +33 -0
- package/package.json +29 -25
- package/skills/mongokit/SKILL.md +112 -0
- package/skills/mongokit/references/pagination-search.md +87 -0
- package/skills/mongokit/references/plugins-tenancy.md +102 -0
- package/skills/mongokit/references/repository-api.md +83 -0
- package/skills/mongokit/references/transactions-outbox.md +101 -0
package/dist/utils/index.d.mts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { _ as getMongooseProjection, a as createMemoryCache, b as createError, c as IdType, d as isObjectIdInstance, f as isValidIdForType, g as getFieldsForUser, h as filterResponseData, i as buildCrudSchemasFromMongooseSchema, l as getSchemaIdType, m as createFieldPreset, n as CrudSchemasFramework, o as LoggerConfig, p as toObjectId, r as buildCrudSchemasFromModel, s as configureLogger, t as toPlain, v as CreateErrorOptions, y as ParseDuplicateKeyOptions } from "../to-plain-
|
|
1
|
+
import { _ as getMongooseProjection, a as createMemoryCache, b as createError, c as IdType, d as isObjectIdInstance, f as isValidIdForType, g as getFieldsForUser, h as filterResponseData, i as buildCrudSchemasFromMongooseSchema, l as getSchemaIdType, m as createFieldPreset, n as CrudSchemasFramework, o as LoggerConfig, p as toObjectId, r as buildCrudSchemasFromModel, s as configureLogger, t as toPlain, v as CreateErrorOptions, y as ParseDuplicateKeyOptions } from "../to-plain-PO5r1Qoy.mjs";
|
|
2
2
|
import { ClientSession, Model } from "mongoose";
|
|
3
|
-
//#region src/utils/id-chunks.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Default slice for `$in` fan-out. Larger than `runChunkedPurge`'s 1000 on purpose:
|
|
6
5
|
* a purge chunk bounds the WRITE LOCK SCOPE of each progressive strategy step, while a
|
|
7
6
|
* snapshot slice bounds only the query-document size and the per-call working set —
|
|
8
7
|
* 10k ObjectIds is ~120 KB of `$in`, far under every limit, at 10× fewer round trips.
|
|
9
8
|
*/
|
|
10
|
-
declare const DEFAULT_ID_CHUNK = 10000;
|
|
9
|
+
export declare const DEFAULT_ID_CHUNK = 10000;
|
|
11
10
|
/**
|
|
12
11
|
* Collect the bare id values matching `filter`, streaming via a driver cursor so the
|
|
13
12
|
* only O(n) allocation is the returned array itself (a `find().lean()` materializes an
|
|
14
13
|
* intermediate array of `{_id}` documents first — roughly double the peak for large n).
|
|
15
14
|
*/
|
|
16
|
-
declare function collectIds(model: Model<unknown>, filter: Record<string, unknown>, options?: {
|
|
15
|
+
export declare function collectIds(model: Model<unknown>, filter: Record<string, unknown>, options?: {
|
|
17
16
|
session?: ClientSession | undefined;
|
|
18
17
|
idField?: string;
|
|
19
18
|
}): Promise<unknown[]>;
|
|
@@ -22,7 +21,7 @@ declare function collectIds(model: Model<unknown>, filter: Record<string, unknow
|
|
|
22
21
|
* array. `size` must be a positive integer — sliced `$in` correctness depends on it,
|
|
23
22
|
* so a nonsense size throws instead of silently degrading to one giant slice.
|
|
24
23
|
*/
|
|
25
|
-
declare function idChunks<T>(ids: readonly T[], size: number): Generator<T[], void, undefined>;
|
|
24
|
+
export declare function idChunks<T>(ids: readonly T[], size: number): Generator<T[], void, undefined>;
|
|
26
25
|
/**
|
|
27
26
|
* Compose the keyset-progressed select filter: the base predicate, narrowed to rows past
|
|
28
27
|
* the last committed `_id`. `cursor == null` means "from the start". Selection paired
|
|
@@ -30,7 +29,7 @@ declare function idChunks<T>(ids: readonly T[], size: number): Generator<T[], vo
|
|
|
30
29
|
* never revisits a processed row and never skips an unprocessed one. Never mutates
|
|
31
30
|
* `baseFilter`.
|
|
32
31
|
*/
|
|
33
|
-
declare function keysetFilter(baseFilter: Record<string, unknown>, cursor: unknown): Record<string, unknown>;
|
|
32
|
+
export declare function keysetFilter(baseFilter: Record<string, unknown>, cursor: unknown): Record<string, unknown>;
|
|
34
33
|
/**
|
|
35
34
|
* The `_id`-ascending bounded chunk select both action ports share:
|
|
36
35
|
* `find(filter).sort({_id: 1}).limit(limit).lean()`. Lean on purpose — chunk consumers
|
|
@@ -38,7 +37,7 @@ declare function keysetFilter(baseFilter: Record<string, unknown>, cursor: unkno
|
|
|
38
37
|
* are needed (the purge port's common path); omit it for full docs (archive's readChunk,
|
|
39
38
|
* anonymize-functional).
|
|
40
39
|
*/
|
|
41
|
-
declare function selectKeysetChunk<T>(model: Model<T>, filter: Record<string, unknown>, limit: number, options?: {
|
|
40
|
+
export declare function selectKeysetChunk<T>(model: Model<T>, filter: Record<string, unknown>, limit: number, options?: {
|
|
42
41
|
session?: ClientSession | undefined;
|
|
43
42
|
projection?: Record<string, 1 | 0> | undefined;
|
|
44
43
|
}): Promise<T[]>;
|
|
@@ -49,6 +48,5 @@ declare function selectKeysetChunk<T>(model: Model<T>, filter: Record<string, un
|
|
|
49
48
|
* write — such a row is silently skipped instead of written outside its cohort. Both
|
|
50
49
|
* action ports use this shape; use it for any select-then-write over a chunk.
|
|
51
50
|
*/
|
|
52
|
-
declare function narrowToIds(baseFilter: Record<string, unknown>, ids: readonly unknown[]): Record<string, unknown>;
|
|
53
|
-
|
|
54
|
-
export { type CreateErrorOptions, type CrudSchemasFramework, DEFAULT_ID_CHUNK, type IdType, type LoggerConfig, type ParseDuplicateKeyOptions, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, collectIds, configureLogger, createError, createFieldPreset, createMemoryCache, filterResponseData, getFieldsForUser, getMongooseProjection, getSchemaIdType, idChunks, isObjectIdInstance, isValidIdForType, keysetFilter, narrowToIds, selectKeysetChunk, toObjectId, toPlain };
|
|
51
|
+
export declare function narrowToIds(baseFilter: Record<string, unknown>, ids: readonly unknown[]): Record<string, unknown>;
|
|
52
|
+
export { type CreateErrorOptions, type CrudSchemasFramework, type IdType, type LoggerConfig, type ParseDuplicateKeyOptions, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, configureLogger, createError, createFieldPreset, createMemoryCache, filterResponseData, getFieldsForUser, getMongooseProjection, getSchemaIdType, isObjectIdInstance, isValidIdForType, toObjectId, toPlain };
|
package/dist/utils/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import { t as
|
|
5
|
-
import {
|
|
6
|
-
import { n as createMemoryCache, t as toPlain } from "../to-plain-
|
|
7
|
-
import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-
|
|
1
|
+
import { t as createError } from "../error-DjdmPLWO.mjs";
|
|
2
|
+
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "../field-selection-DPFaFw9Y.mjs";
|
|
3
|
+
import { a as narrowToIds, i as keysetFilter, n as collectIds, o as selectKeysetChunk, r as idChunks, t as DEFAULT_ID_CHUNK } from "../id-chunks-DH-RAZWG.mjs";
|
|
4
|
+
import { a as toObjectId, i as isValidIdForType, r as isObjectIdInstance, t as getSchemaIdType } from "../id-resolution-Cqh49d9J.mjs";
|
|
5
|
+
import { t as configureLogger } from "../logger-hbWOlj_X.mjs";
|
|
6
|
+
import { n as createMemoryCache, t as toPlain } from "../to-plain-CEKv_ylg.mjs";
|
|
7
|
+
import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-DMDotz4_.mjs";
|
|
8
8
|
export { DEFAULT_ID_CHUNK, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, collectIds, configureLogger, createError, createFieldPreset, createMemoryCache, filterResponseData, getFieldsForUser, getMongooseProjection, getSchemaIdType, idChunks, isObjectIdInstance, isValidIdForType, keysetFilter, narrowToIds, selectKeysetChunk, toObjectId, toPlain };
|
package/dist/{validation-chain.plugin-BAeC5eVT.d.mts → validation-chain.plugin-B3gZCZj4.d.mts}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { A as ObjectId, F as SortSpec, N as SelectSpec, j as PopulateSpec } from "./pagination-
|
|
2
|
-
import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-
|
|
3
|
-
import {
|
|
1
|
+
import { A as ObjectId, F as SortSpec, N as SelectSpec, j as PopulateSpec } from "./pagination-DAUg5zOY.mjs";
|
|
2
|
+
import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-DzVIwhU2.mjs";
|
|
3
|
+
import { n as RetentionPurgeEvent, r as RetentionPurgeRequest } from "./retention-purge-DqcYvRnG.mjs";
|
|
4
|
+
import { c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, o as SoftDeleteOptions, r as FieldPreset, t as CascadeOptions } from "./plugin-options-Bpcuz9kS.mjs";
|
|
4
5
|
import { BulkWriteResult } from "@classytic/repo-core/repository";
|
|
5
6
|
import { OffsetPaginationResult } from "@classytic/repo-core/pagination";
|
|
6
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
|
-
//#region src/plugins/aggregate-helpers.plugin.d.ts
|
|
8
8
|
/**
|
|
9
9
|
* Aggregate helpers plugin
|
|
10
10
|
*
|
|
@@ -88,8 +88,6 @@ interface AggregateHelpersMethods {
|
|
|
88
88
|
*/
|
|
89
89
|
max(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
90
90
|
}
|
|
91
|
-
//#endregion
|
|
92
|
-
//#region src/plugins/append-only.plugin.d.ts
|
|
93
91
|
interface AppendOnlyPluginOptions {
|
|
94
92
|
/**
|
|
95
93
|
* Mutating ops to permit besides `create` / `createMany`. Use for a
|
|
@@ -106,13 +104,19 @@ interface AppendOnlyPluginOptions {
|
|
|
106
104
|
* "append-only", never "missing organizationId".
|
|
107
105
|
*/
|
|
108
106
|
priority?: number | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Allow the audited retention purge: `delete` / `deleteMany` with
|
|
109
|
+
* `{ mode: 'hard', retentionPurge: { reason, actor? } }` (and
|
|
110
|
+
* `purgeByFilter` / `purgeByField` with `retentionPurge`) pass the fence,
|
|
111
|
+
* emitting `after:append-only-purge`. Default `false`: the option is
|
|
112
|
+
* refused (403 `RETENTION_PURGE_DISABLED`).
|
|
113
|
+
*/
|
|
114
|
+
allowPurge?: boolean | undefined;
|
|
109
115
|
}
|
|
116
|
+
/** Payload of `after:append-only-purge`: one per successful purge call. */
|
|
117
|
+
type AppendOnlyPurgeEvent = RetentionPurgeEvent;
|
|
110
118
|
declare function appendOnlyPlugin(options?: AppendOnlyPluginOptions): Plugin;
|
|
111
|
-
//#endregion
|
|
112
|
-
//#region src/plugins/audit-log.plugin.d.ts
|
|
113
119
|
declare function auditLogPlugin(logger: Logger): Plugin;
|
|
114
|
-
//#endregion
|
|
115
|
-
//#region src/plugins/batch-operations.plugin.d.ts
|
|
116
120
|
/** Options accepted by `repo.bulkWrite`. Plugin context may ride alongside. */
|
|
117
121
|
interface BulkWriteOptions {
|
|
118
122
|
/** Stop at the first failure. Default `true`, matching the driver. */
|
|
@@ -144,19 +148,15 @@ interface BatchOperationsMethods {
|
|
|
144
148
|
* ]);
|
|
145
149
|
* console.log(result.insertedCount, result.modifiedCount, result.deletedCount);
|
|
146
150
|
*/
|
|
147
|
-
bulkWrite(operations: Record<string, unknown>[], options?: {
|
|
151
|
+
bulkWrite(operations: readonly Record<string, unknown>[], options?: {
|
|
148
152
|
session?: unknown;
|
|
149
153
|
ordered?: boolean;
|
|
150
154
|
}): Promise<BulkWriteResult>;
|
|
151
155
|
}
|
|
152
|
-
//#endregion
|
|
153
|
-
//#region src/plugins/cascade.plugin.d.ts
|
|
154
156
|
/**
|
|
155
157
|
* Cascade delete plugin.
|
|
156
158
|
*/
|
|
157
159
|
declare function cascadePlugin(options: CascadeOptions): Plugin;
|
|
158
|
-
//#endregion
|
|
159
|
-
//#region src/plugins/elastic.plugin.d.ts
|
|
160
160
|
interface ElasticSearchOptions {
|
|
161
161
|
/** Elasticsearch or OpenSearch client instance */
|
|
162
162
|
client: any;
|
|
@@ -166,8 +166,6 @@ interface ElasticSearchOptions {
|
|
|
166
166
|
idField?: string;
|
|
167
167
|
}
|
|
168
168
|
declare function elasticSearchPlugin(options: ElasticSearchOptions): Plugin;
|
|
169
|
-
//#endregion
|
|
170
|
-
//#region src/plugins/field-filter.plugin.d.ts
|
|
171
169
|
/**
|
|
172
170
|
* Field filter plugin that restricts fields based on user context
|
|
173
171
|
*
|
|
@@ -181,8 +179,6 @@ declare function elasticSearchPlugin(options: ElasticSearchOptions): Plugin;
|
|
|
181
179
|
* const repo = new Repository(Model, [fieldFilterPlugin(fieldPreset)]);
|
|
182
180
|
*/
|
|
183
181
|
declare function fieldFilterPlugin(fieldPreset: FieldPreset): Plugin;
|
|
184
|
-
//#endregion
|
|
185
|
-
//#region src/plugins/idempotency-store.plugin.d.ts
|
|
186
182
|
interface IdempotencyStorePluginOptions {
|
|
187
183
|
/** Field carrying the deterministic operation key. @default `'key'` */
|
|
188
184
|
keyField?: string;
|
|
@@ -323,8 +319,6 @@ interface IdempotencyStoreMethods<TProgress = Record<string, unknown>, TResult =
|
|
|
323
319
|
* failures, lapsed-claim sweeps). Removed in mongokit 4.
|
|
324
320
|
*/
|
|
325
321
|
declare function idempotencyStorePlugin(options?: IdempotencyStorePluginOptions): Plugin;
|
|
326
|
-
//#endregion
|
|
327
|
-
//#region src/plugins/immutable-states.plugin.d.ts
|
|
328
322
|
/** The slice of a `before:claim` context `allowClaim` predicates see. */
|
|
329
323
|
interface ImmutableClaimView {
|
|
330
324
|
id: unknown;
|
|
@@ -356,6 +350,14 @@ interface ImmutableStatesPluginOptions {
|
|
|
356
350
|
* state — keep the predicate a strict fingerprint.
|
|
357
351
|
*/
|
|
358
352
|
allowClaim?: ((view: ImmutableClaimView) => boolean) | undefined;
|
|
353
|
+
/**
|
|
354
|
+
* Allow the audited retention purge: `delete` / `deleteMany` with
|
|
355
|
+
* `{ mode: 'hard', retentionPurge: { reason, actor? } }` (and
|
|
356
|
+
* `purgeByFilter` / `purgeByField` with `retentionPurge`) may remove frozen
|
|
357
|
+
* rows, emitting `after:immutable-states-purge`. Default `false`: the
|
|
358
|
+
* option is refused (403 `RETENTION_PURGE_DISABLED`).
|
|
359
|
+
*/
|
|
360
|
+
allowPurge?: boolean | undefined;
|
|
359
361
|
/** Domain error to throw. Default: 403 `IMMUTABLE_STATE_VIOLATION`. */
|
|
360
362
|
errorFactory?: ((ctx: {
|
|
361
363
|
id: unknown;
|
|
@@ -363,9 +365,14 @@ interface ImmutableStatesPluginOptions {
|
|
|
363
365
|
state?: string | undefined;
|
|
364
366
|
}) => Error) | undefined;
|
|
365
367
|
}
|
|
368
|
+
/** Per-call purge request (`options.retentionPurge`). */
|
|
369
|
+
type ImmutablePurgeRequest = RetentionPurgeRequest;
|
|
370
|
+
/** Payload of `after:immutable-states-purge`: one per successful purge call. */
|
|
371
|
+
interface ImmutablePurgeEvent extends RetentionPurgeEvent {
|
|
372
|
+
/** The frozen states configured on the plugin. */
|
|
373
|
+
states: readonly string[];
|
|
374
|
+
}
|
|
366
375
|
declare function immutableStatesPlugin(options: ImmutableStatesPluginOptions): Plugin;
|
|
367
|
-
//#endregion
|
|
368
|
-
//#region src/plugins/lease.plugin.d.ts
|
|
369
376
|
interface LeasePluginOptions {
|
|
370
377
|
/** Field carrying the row's status. @default `'status'` */
|
|
371
378
|
statusField?: string;
|
|
@@ -381,7 +388,57 @@ interface LeasePluginOptions {
|
|
|
381
388
|
doneStatus?: string;
|
|
382
389
|
/** Sort fields used to pick the FIFO winner from the lease pool. @default `{ createdAt: 1 }` */
|
|
383
390
|
sort?: Record<string, 1 | -1>;
|
|
391
|
+
/**
|
|
392
|
+
* Clock used by `lease` / `extend` / `release` for both the CAS
|
|
393
|
+
* comparison and the new expiry. A per-call `now` wins over it.
|
|
394
|
+
* Inject one to drive lease expiry from a test or a host `Clock`
|
|
395
|
+
* port. @default `() => new Date()`
|
|
396
|
+
*/
|
|
397
|
+
nowFn?: () => Date;
|
|
398
|
+
/**
|
|
399
|
+
* Statuses whose expired lease `lease()` may recover. Only rows in
|
|
400
|
+
* one of these statuses AND with `leaseExpiresAt < now` are dead
|
|
401
|
+
* leases; a row in any other status is never re-leased, whatever its
|
|
402
|
+
* lease field says (a cancelled row with a stale expiry stays
|
|
403
|
+
* cancelled). @default `[processingStatus]`
|
|
404
|
+
*/
|
|
405
|
+
deadLeaseStatuses?: readonly string[];
|
|
406
|
+
/**
|
|
407
|
+
* Optional attempts counter. When set, every successful `lease()`
|
|
408
|
+
* (first claim and dead-lease recovery alike) applies
|
|
409
|
+
* `$inc: { [attemptsField]: 1 }`. Off by default.
|
|
410
|
+
*/
|
|
411
|
+
attemptsField?: string;
|
|
412
|
+
/**
|
|
413
|
+
* Cap on `attemptsField`. A row whose counter is already
|
|
414
|
+
* `>= maxAttempts` is not leasable; a row missing the field is.
|
|
415
|
+
* Exhausted rows stay where they are until `reapExhausted()` moves
|
|
416
|
+
* them to `exhaustedStatus` (or the host sweeps them itself).
|
|
417
|
+
* Requires `attemptsField` (throws at construction).
|
|
418
|
+
*/
|
|
419
|
+
maxAttempts?: number;
|
|
420
|
+
/**
|
|
421
|
+
* Terminal status `reapExhausted()` moves an exhausted row to (e.g.
|
|
422
|
+
* `'failed'`). Requires `maxAttempts`; must differ from
|
|
423
|
+
* `pendingStatus`, `processingStatus` and every `deadLeaseStatuses`
|
|
424
|
+
* entry (throws at construction). Without it `reapExhausted()` needs
|
|
425
|
+
* a per-call `status`.
|
|
426
|
+
*/
|
|
427
|
+
exhaustedStatus?: string;
|
|
428
|
+
/** Field `reapExhausted()` stamps with the reap time (e.g. `'failedAt'`). Off by default. */
|
|
429
|
+
exhaustedAtField?: string;
|
|
430
|
+
/**
|
|
431
|
+
* Extra predicate ANDed into the PENDING arm only, so not-yet-due rows
|
|
432
|
+
* wait while a dead lease is still recovered. The object form is
|
|
433
|
+
* STATIC (built once); for a time-relative predicate pass the function
|
|
434
|
+
* form, called per `lease()` with the resolved `now` (per-call `now`,
|
|
435
|
+
* else `nowFn()`): `pendingFilter: (now) => ({ dueAt: { $lte: now } })`.
|
|
436
|
+
* A per-call `pendingFilter` replaces this one.
|
|
437
|
+
*/
|
|
438
|
+
pendingFilter?: LeasePendingFilter;
|
|
384
439
|
}
|
|
440
|
+
/** Static pending-arm predicate, or a builder called with the claim's `now`. */
|
|
441
|
+
type LeasePendingFilter = Record<string, unknown> | ((now: Date) => Record<string, unknown>);
|
|
385
442
|
/**
|
|
386
443
|
* Methods contributed by `leasePlugin()`. Use as a type assertion when
|
|
387
444
|
* constructing the repo so call sites get autocomplete:
|
|
@@ -397,9 +454,18 @@ interface LeasePluginOptions {
|
|
|
397
454
|
interface LeaseMethods<TDoc> {
|
|
398
455
|
/**
|
|
399
456
|
* Atomically claim the next available row. Matches rows that are
|
|
400
|
-
* either in `pendingStatus`
|
|
401
|
-
*
|
|
402
|
-
*
|
|
457
|
+
* either in `pendingStatus` (AND `pendingFilter`, when given) OR in a
|
|
458
|
+
* `deadLeaseStatuses` status with an expired `leaseExpiresAt` (dead
|
|
459
|
+
* lease recovery). The caller's `filter` is kept as given (its own
|
|
460
|
+
* `$or` included) and the claim condition is ANDed beside it. Sets
|
|
461
|
+
* status to `processingStatus`, stamps `leasedBy`, pushes
|
|
462
|
+
* `leaseExpiresAt = now + leaseFor`, and bumps `attemptsField` when
|
|
463
|
+
* configured.
|
|
464
|
+
*
|
|
465
|
+
* `leasedBy` is the fencing token for `extend` / `release`: make it
|
|
466
|
+
* unique per claim (e.g. `${instanceId}:${randomUUID()}`). A worker
|
|
467
|
+
* that reuses one id could otherwise finalise a stale run after its
|
|
468
|
+
* own lapsed lease was re-leased under the same id.
|
|
403
469
|
*
|
|
404
470
|
* @returns The leased doc, or `null` when no row matches.
|
|
405
471
|
*/
|
|
@@ -407,17 +473,24 @@ interface LeaseMethods<TDoc> {
|
|
|
407
473
|
filter?: Record<string, unknown>;
|
|
408
474
|
leaseFor: number;
|
|
409
475
|
leasedBy: string;
|
|
476
|
+
/** Clock reading for this call. @default plugin `nowFn()` */
|
|
477
|
+
now?: Date;
|
|
478
|
+
/** Replaces the plugin-level `pendingFilter` for this call. */
|
|
479
|
+
pendingFilter?: LeasePendingFilter;
|
|
410
480
|
options?: Record<string, unknown>;
|
|
411
481
|
}): Promise<TDoc | null>;
|
|
412
482
|
/**
|
|
413
483
|
* Push a held lease's expiry further. Only succeeds when the lease
|
|
414
|
-
* is still ours (`leasedBy === leasedBy && leaseExpiresAt > now`)
|
|
484
|
+
* is still ours (`leasedBy === leasedBy && leaseExpiresAt > now`) and
|
|
485
|
+
* the row is still in `processingStatus` (a row the host moved to a
|
|
486
|
+
* terminal status, e.g. cancelled, is not kept alive).
|
|
415
487
|
* Returns `null` if the lease was lost — caller should drop the
|
|
416
488
|
* work, since someone else has already started replaying it.
|
|
417
489
|
*/
|
|
418
490
|
extend(id: string | ObjectId, opts: {
|
|
419
491
|
leasedBy: string;
|
|
420
492
|
leaseFor: number;
|
|
493
|
+
now?: Date;
|
|
421
494
|
options?: Record<string, unknown>;
|
|
422
495
|
}): Promise<TDoc | null>;
|
|
423
496
|
/**
|
|
@@ -434,17 +507,48 @@ interface LeaseMethods<TDoc> {
|
|
|
434
507
|
* `lease()` predicate) skip this row.
|
|
435
508
|
*
|
|
436
509
|
* Returns the released doc, or `null` when the CAS lost (lease
|
|
437
|
-
* expired / held by another worker / row gone
|
|
510
|
+
* expired / held by another worker / row gone / row no longer in
|
|
511
|
+
* `processingStatus`, e.g. the host cancelled it mid-run).
|
|
438
512
|
*/
|
|
439
513
|
release(id: string | ObjectId, opts: {
|
|
440
514
|
leasedBy: string;
|
|
441
515
|
finalStatus?: string;
|
|
516
|
+
now?: Date;
|
|
442
517
|
options?: Record<string, unknown>;
|
|
443
518
|
}): Promise<TDoc | null>;
|
|
519
|
+
/**
|
|
520
|
+
* Move every EXHAUSTED row to `exhaustedStatus` and return the moved
|
|
521
|
+
* rows (after the move), so the host only audits and alerts. A row is
|
|
522
|
+
* exhausted when `lease()` would claim it but for the attempts cap:
|
|
523
|
+
* `attemptsField >= maxAttempts` AND either pending (and passing
|
|
524
|
+
* `pendingFilter`) or in a `deadLeaseStatuses` status whose lease
|
|
525
|
+
* lapsed (`leaseExpiresAt < now`). A row whose lease is still live is
|
|
526
|
+
* left alone: its holder may still release it.
|
|
527
|
+
*
|
|
528
|
+
* Each move is a compare-and-set on that same condition, so two
|
|
529
|
+
* reapers never both return a row, and a row is returned once: once
|
|
530
|
+
* moved it no longer matches. Clears `leasedBy` / `leaseExpiresAt`
|
|
531
|
+
* and stamps `exhaustedAtField` with `now` when configured. The
|
|
532
|
+
* caller's `filter` is ANDed in as with `lease()`. Requires
|
|
533
|
+
* `maxAttempts`; reads at most `limit` rows (default 100) in `sort`
|
|
534
|
+
* order, so call it again until it returns `[]`. A batch shorter than
|
|
535
|
+
* `limit` does not mean none are left: a concurrent reaper may have
|
|
536
|
+
* moved some of the rows read (and keeps draining them).
|
|
537
|
+
*/
|
|
538
|
+
reapExhausted(opts?: {
|
|
539
|
+
filter?: Record<string, unknown>;
|
|
540
|
+
/** Clock reading for this call. @default plugin `nowFn()` */
|
|
541
|
+
now?: Date;
|
|
542
|
+
/** Rows read per call. @default 100 */
|
|
543
|
+
limit?: number;
|
|
544
|
+
/** Replaces the plugin-level `exhaustedStatus` for this call. */
|
|
545
|
+
status?: string;
|
|
546
|
+
/** Replaces the plugin-level `pendingFilter` for this call. */
|
|
547
|
+
pendingFilter?: LeasePendingFilter;
|
|
548
|
+
options?: Record<string, unknown>;
|
|
549
|
+
}): Promise<TDoc[]>;
|
|
444
550
|
}
|
|
445
551
|
declare function leasePlugin(options?: LeasePluginOptions): Plugin;
|
|
446
|
-
//#endregion
|
|
447
|
-
//#region src/plugins/method-registry.plugin.d.ts
|
|
448
552
|
/**
|
|
449
553
|
* Extended repository interface with method registry
|
|
450
554
|
*/
|
|
@@ -457,8 +561,6 @@ interface MethodRegistryRepository extends RepositoryInstance {
|
|
|
457
561
|
* Method registry plugin that enables dynamic method registration
|
|
458
562
|
*/
|
|
459
563
|
declare function methodRegistryPlugin(): Plugin;
|
|
460
|
-
//#endregion
|
|
461
|
-
//#region src/plugins/mongo-operations.plugin.d.ts
|
|
462
564
|
/**
|
|
463
565
|
* MongoDB operations plugin
|
|
464
566
|
*
|
|
@@ -689,8 +791,6 @@ interface MongoOperationsMethods<TDoc> {
|
|
|
689
791
|
*/
|
|
690
792
|
incrementIfBelow(id: string | ObjectId, field: string, ceiling: number, by?: number, options?: Record<string, unknown>): Promise<TDoc | null>;
|
|
691
793
|
}
|
|
692
|
-
//#endregion
|
|
693
|
-
//#region src/plugins/observability.plugin.d.ts
|
|
694
794
|
interface OperationMetric {
|
|
695
795
|
/** Operation name (e.g., 'create', 'getAll', 'update') */
|
|
696
796
|
operation: string;
|
|
@@ -718,8 +818,6 @@ interface ObservabilityOptions {
|
|
|
718
818
|
slowThresholdMs?: number;
|
|
719
819
|
}
|
|
720
820
|
declare function observabilityPlugin(options: ObservabilityOptions): Plugin;
|
|
721
|
-
//#endregion
|
|
722
|
-
//#region src/plugins/search-keys.plugin.d.ts
|
|
723
821
|
interface SearchKeysPluginOptions {
|
|
724
822
|
/** Source fields (dotted paths allowed; string, number, or arrays of them). */
|
|
725
823
|
fields: readonly string[];
|
|
@@ -727,8 +825,6 @@ interface SearchKeysPluginOptions {
|
|
|
727
825
|
keysField?: string;
|
|
728
826
|
}
|
|
729
827
|
declare function searchKeysPlugin(options: SearchKeysPluginOptions): Plugin;
|
|
730
|
-
//#endregion
|
|
731
|
-
//#region src/plugins/soft-delete.plugin.d.ts
|
|
732
828
|
/**
|
|
733
829
|
* Soft delete plugin
|
|
734
830
|
*
|
|
@@ -820,8 +916,6 @@ interface SoftDeleteMethods<TDoc> {
|
|
|
820
916
|
session?: unknown;
|
|
821
917
|
}): Promise<OffsetPaginationResult<TDoc>>;
|
|
822
918
|
}
|
|
823
|
-
//#endregion
|
|
824
|
-
//#region src/plugins/subdocument.plugin.d.ts
|
|
825
919
|
/**
|
|
826
920
|
* Subdocument plugin for managing nested arrays
|
|
827
921
|
*
|
|
@@ -902,8 +996,6 @@ interface SubdocumentMethods<TDoc> {
|
|
|
902
996
|
*/
|
|
903
997
|
deleteSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: Record<string, unknown>): Promise<TDoc>;
|
|
904
998
|
}
|
|
905
|
-
//#endregion
|
|
906
|
-
//#region src/plugins/tenant-context.d.ts
|
|
907
999
|
interface TenantStore {
|
|
908
1000
|
tenantId: string | undefined;
|
|
909
1001
|
[key: string]: unknown;
|
|
@@ -924,8 +1016,6 @@ interface TenantContext {
|
|
|
924
1016
|
readonly storage: AsyncLocalStorage<TenantStore>;
|
|
925
1017
|
}
|
|
926
1018
|
declare function createTenantContext(): TenantContext;
|
|
927
|
-
//#endregion
|
|
928
|
-
//#region src/plugins/timestamp.plugin.d.ts
|
|
929
1019
|
/**
|
|
930
1020
|
* Timestamp plugin that auto-injects timestamps
|
|
931
1021
|
*
|
|
@@ -933,8 +1023,6 @@ declare function createTenantContext(): TenantContext;
|
|
|
933
1023
|
* const repo = new Repository(Model, [timestampPlugin()]);
|
|
934
1024
|
*/
|
|
935
1025
|
declare function timestampPlugin(): Plugin;
|
|
936
|
-
//#endregion
|
|
937
|
-
//#region src/plugins/validation-chain.plugin.d.ts
|
|
938
1026
|
type OperationType = 'create' | 'createMany' | 'update' | 'findOneAndUpdate' | 'delete';
|
|
939
1027
|
/**
|
|
940
1028
|
* Validation chain plugin
|
|
@@ -972,5 +1060,4 @@ declare function immutableField(field: string): ValidatorDefinition;
|
|
|
972
1060
|
* Ensure field value is unique
|
|
973
1061
|
*/
|
|
974
1062
|
declare function uniqueField(field: string, errorMessage?: string): ValidatorDefinition;
|
|
975
|
-
|
|
976
|
-
export { immutableStatesPlugin as A, BulkWriteOptions as B, MethodRegistryRepository as C, leasePlugin as D, LeasePluginOptions as E, fieldFilterPlugin as F, appendOnlyPlugin as G, batchOperationsPlugin as H, ElasticSearchOptions as I, AggregateHelpersMethods as K, elasticSearchPlugin as L, IdempotencyStoreMethods as M, IdempotencyStorePluginOptions as N, ImmutableClaimView as O, idempotencyStorePlugin as P, cascadePlugin as R, mongoOperationsPlugin as S, LeaseMethods as T, auditLogPlugin as U, BulkWriteResult as V, AppendOnlyPluginOptions as W, searchKeysPlugin as _, requireField as a, observabilityPlugin as b, timestampPlugin as c, createTenantContext as d, SubdocumentMethods as f, SearchKeysPluginOptions as g, softDeletePlugin as h, immutableField as i, IdempotencyClaim as j, ImmutableStatesPluginOptions as k, TenantContext as l, SoftDeleteMethods as m, autoInject as n, uniqueField as o, subdocumentPlugin as p, aggregateHelpersPlugin as q, blockIf as r, validationChainPlugin as s, OperationType as t, TenantStore as u, ObservabilityOptions as v, methodRegistryPlugin as w, MongoOperationsMethods as x, OperationMetric as y, BatchOperationsMethods as z };
|
|
1063
|
+
export { ImmutablePurgeEvent as A, elasticSearchPlugin as B, MethodRegistryRepository as C, LeasePluginOptions as D, LeasePendingFilter as E, IdempotencyStoreMethods as F, batchOperationsPlugin as G, BatchOperationsMethods as H, IdempotencyStorePluginOptions as I, AppendOnlyPurgeEvent as J, auditLogPlugin as K, idempotencyStorePlugin as L, ImmutableStatesPluginOptions as M, immutableStatesPlugin as N, leasePlugin as O, IdempotencyClaim as P, fieldFilterPlugin as R, mongoOperationsPlugin as S, LeaseMethods as T, BulkWriteOptions as U, cascadePlugin as V, BulkWriteResult as W, AggregateHelpersMethods as X, appendOnlyPlugin as Y, aggregateHelpersPlugin as Z, searchKeysPlugin as _, requireField as a, observabilityPlugin as b, timestampPlugin as c, createTenantContext as d, SubdocumentMethods as f, SearchKeysPluginOptions as g, softDeletePlugin as h, immutableField as i, ImmutablePurgeRequest as j, ImmutableClaimView as k, TenantContext as l, SoftDeleteMethods as m, autoInject as n, uniqueField as o, subdocumentPlugin as p, AppendOnlyPluginOptions as q, blockIf as r, validationChainPlugin as s, OperationType as t, TenantStore as u, ObservabilityOptions as v, methodRegistryPlugin as w, MongoOperationsMethods as x, OperationMetric as y, ElasticSearchOptions as z };
|