@classytic/mongokit 3.43.1 → 3.45.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 +18 -3
- package/dist/{PaginationEngine-DZnkbSrr.mjs → PaginationEngine-BRlLTQQz.mjs} +13 -27
- package/dist/{PaginationEngine-CRHyuUtw.d.mts → PaginationEngine-BWb-c47a.d.mts} +1 -3
- package/dist/{Repository-DnL4xk5w.d.mts → Repository-DJuRmBNx.d.mts} +44 -13
- package/dist/{Repository-Dj6xqPxJ.mjs → Repository-DheA7oW-.mjs} +330 -112
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.mjs +2 -2
- package/dist/{actions-ChYfkPYP.mjs → actions-DKQx9ToJ.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 +21 -20
- package/dist/better-auth/index.mjs +12 -23
- package/dist/{coercion-BjdPX3YF.d.mts → coercion-COp9DRNw.d.mts} +0 -2
- package/dist/{create-repository-UjwPWR1z.mjs → create-repository-C9DHHcl7.mjs} +4 -5
- package/dist/{create-repository-CJtVdwig.d.mts → create-repository-DG-gwOf0.d.mts} +5 -7
- 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-5mhQ63_B.d.mts} +3 -4
- package/dist/{index-C0AjVqX3.d.mts → index-ehGZLbrd.d.mts} +2 -8
- package/dist/index.d.mts +70 -102
- 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-BeJfQBJV.mjs} +5 -7
- 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-BTPtCLNK.d.mts} +143 -11
- package/dist/{operations-XiFgG5US.d.mts → operations-D6XsHx4e.d.mts} +19 -11
- 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-BAM9cA4N.d.mts} +6 -16
- package/dist/{plugin-options-Cirmb4Kp.d.mts → plugin-options-DrNGWV5b.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-DwvWUjZU.mjs} +18 -54
- package/dist/read-model/index.d.mts +18 -21
- package/dist/read-model/index.mjs +3 -4
- package/dist/{repository-MqAP409e.d.mts → repository-B0aFVgP2.d.mts} +25 -29
- package/dist/retention-purge-CCd_VXUf.d.mts +38 -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 +113 -17
- package/dist/sync/index.mjs +421 -65
- 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-B-IJrlYb.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-Do-8jTKC.d.mts} +2 -16
- package/dist/{transaction-DmiB4k2P.mjs → transaction-C6Oj941P.mjs} +18 -19
- package/dist/{type-utils-CLzRFtIA.d.mts → type-utils-CKvuewAL.d.mts} +0 -2
- package/dist/{update-WgeAUJ_I.mjs → update-CYaJMu6j.mjs} +13 -23
- 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-COYrUdd8.d.mts} +150 -48
- package/dist/{validation-chain.plugin-DRApTmkN.mjs → validation-chain.plugin-DJplVJ12.mjs} +210 -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 +103 -0
- package/skills/mongokit/references/repository-api.md +83 -0
- package/skills/mongokit/references/transactions-outbox.md +103 -0
package/dist/usage/index.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Connection } from "mongoose";
|
|
2
2
|
import { UsageStore } from "@classytic/repo-core/usage";
|
|
3
|
-
//#region src/usage/index.d.ts
|
|
4
3
|
/** Adapter-construction options. */
|
|
5
|
-
interface MongoUsageStoreOptions {
|
|
4
|
+
export interface MongoUsageStoreOptions {
|
|
6
5
|
/**
|
|
7
6
|
* Mongoose connection. Defaults to `mongoose.connection` (the
|
|
8
7
|
* default global connection). Apps using a named connection pass
|
|
@@ -18,6 +17,4 @@ interface MongoUsageStoreOptions {
|
|
|
18
17
|
* Build a Mongo-backed usage store. Idempotent — the underlying model
|
|
19
18
|
* is registered once per `(connection, modelName)` pair.
|
|
20
19
|
*/
|
|
21
|
-
declare function createMongoUsageStore(options?: MongoUsageStoreOptions): UsageStore;
|
|
22
|
-
//#endregion
|
|
23
|
-
export { MongoUsageStoreOptions, createMongoUsageStore };
|
|
20
|
+
export declare function createMongoUsageStore(options?: MongoUsageStoreOptions): UsageStore;
|
package/dist/usage/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as isDuplicateKeyError } from "../error-
|
|
1
|
+
import { n as isDuplicateKeyError } from "../error-DjdmPLWO.mjs";
|
|
2
2
|
import mongoose, { Schema } from "mongoose";
|
|
3
|
-
|
|
3
|
+
// src/usage/index.ts
|
|
4
4
|
/**
|
|
5
5
|
* Build a Mongo-backed usage store. Idempotent — the underlying model
|
|
6
6
|
* is registered once per `(connection, modelName)` pair.
|
|
@@ -8,9 +8,12 @@ import mongoose, { Schema } from "mongoose";
|
|
|
8
8
|
function createMongoUsageStore(options = {}) {
|
|
9
9
|
const { connection, collectionName = "usage_counters", modelName = "MongoUsageCounter" } = options;
|
|
10
10
|
const model = getOrCreateModel(connection ?? mongoose, modelName, collectionName);
|
|
11
|
+
const ready = model.init();
|
|
12
|
+
ready.catch(() => void 0);
|
|
11
13
|
return {
|
|
12
14
|
name: "mongo",
|
|
13
15
|
async increment(bucket, amount) {
|
|
16
|
+
await ready;
|
|
14
17
|
const filter = {
|
|
15
18
|
actor: bucket.actor,
|
|
16
19
|
period: bucket.period,
|
|
@@ -28,9 +31,9 @@ function createMongoUsageStore(options = {}) {
|
|
|
28
31
|
actor,
|
|
29
32
|
period
|
|
30
33
|
}).select("kind count").lean();
|
|
31
|
-
const
|
|
32
|
-
for (const row of rows)
|
|
33
|
-
return
|
|
34
|
+
const sums = /* @__PURE__ */ new Map();
|
|
35
|
+
for (const row of rows) sums.set(row.kind, (sums.get(row.kind) ?? 0) + row.count);
|
|
36
|
+
return Object.fromEntries(sums);
|
|
34
37
|
}
|
|
35
38
|
};
|
|
36
39
|
}
|
|
@@ -63,5 +66,4 @@ function getOrCreateModel(conn, modelName, collectionName) {
|
|
|
63
66
|
}, { unique: true });
|
|
64
67
|
return conn.model(modelName, schema, collectionName);
|
|
65
68
|
}
|
|
66
|
-
//#endregion
|
|
67
69
|
export { createMongoUsageStore };
|
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-Do-8jTKC.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-COYrUdd8.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-BAM9cA4N.mjs";
|
|
2
|
+
import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-B0aFVgP2.mjs";
|
|
3
|
+
import { n as RetentionPurgeEvent, r as RetentionPurgeRequest } from "./retention-purge-CCd_VXUf.mjs";
|
|
4
|
+
import { c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, o as SoftDeleteOptions, r as FieldPreset, t as CascadeOptions } from "./plugin-options-DrNGWV5b.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,26 @@ 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;
|
|
115
|
+
/**
|
|
116
|
+
* Allow `archiveByFilter(filter, sink, { retentionPurge })` to delete the rows its
|
|
117
|
+
* sink acknowledged, and nothing else: a retentionPurge delete without the run's
|
|
118
|
+
* attestation is still refused. Audited via `after:append-only-purge` with
|
|
119
|
+
* `archived: true`. Implied by `allowPurge`. Default `false`.
|
|
120
|
+
*/
|
|
121
|
+
allowArchive?: boolean | undefined;
|
|
109
122
|
}
|
|
123
|
+
/** Payload of `after:append-only-purge`: one per successful purge call. */
|
|
124
|
+
type AppendOnlyPurgeEvent = RetentionPurgeEvent;
|
|
110
125
|
declare function appendOnlyPlugin(options?: AppendOnlyPluginOptions): Plugin;
|
|
111
|
-
//#endregion
|
|
112
|
-
//#region src/plugins/audit-log.plugin.d.ts
|
|
113
126
|
declare function auditLogPlugin(logger: Logger): Plugin;
|
|
114
|
-
//#endregion
|
|
115
|
-
//#region src/plugins/batch-operations.plugin.d.ts
|
|
116
127
|
/** Options accepted by `repo.bulkWrite`. Plugin context may ride alongside. */
|
|
117
128
|
interface BulkWriteOptions {
|
|
118
129
|
/** Stop at the first failure. Default `true`, matching the driver. */
|
|
@@ -123,6 +134,8 @@ interface BulkWriteOptions {
|
|
|
123
134
|
comment?: unknown;
|
|
124
135
|
let?: Record<string, unknown>;
|
|
125
136
|
ignoreUndefined?: boolean;
|
|
137
|
+
/** Server-side time bound for the write. */
|
|
138
|
+
maxTimeMS?: number;
|
|
126
139
|
/** Plugin context (tenant id, actor, ...) - spread into the op context. */
|
|
127
140
|
[key: string]: unknown;
|
|
128
141
|
}
|
|
@@ -144,19 +157,15 @@ interface BatchOperationsMethods {
|
|
|
144
157
|
* ]);
|
|
145
158
|
* console.log(result.insertedCount, result.modifiedCount, result.deletedCount);
|
|
146
159
|
*/
|
|
147
|
-
bulkWrite(operations: Record<string, unknown>[], options?: {
|
|
160
|
+
bulkWrite(operations: readonly Record<string, unknown>[], options?: {
|
|
148
161
|
session?: unknown;
|
|
149
162
|
ordered?: boolean;
|
|
150
163
|
}): Promise<BulkWriteResult>;
|
|
151
164
|
}
|
|
152
|
-
//#endregion
|
|
153
|
-
//#region src/plugins/cascade.plugin.d.ts
|
|
154
165
|
/**
|
|
155
166
|
* Cascade delete plugin.
|
|
156
167
|
*/
|
|
157
168
|
declare function cascadePlugin(options: CascadeOptions): Plugin;
|
|
158
|
-
//#endregion
|
|
159
|
-
//#region src/plugins/elastic.plugin.d.ts
|
|
160
169
|
interface ElasticSearchOptions {
|
|
161
170
|
/** Elasticsearch or OpenSearch client instance */
|
|
162
171
|
client: any;
|
|
@@ -166,8 +175,6 @@ interface ElasticSearchOptions {
|
|
|
166
175
|
idField?: string;
|
|
167
176
|
}
|
|
168
177
|
declare function elasticSearchPlugin(options: ElasticSearchOptions): Plugin;
|
|
169
|
-
//#endregion
|
|
170
|
-
//#region src/plugins/field-filter.plugin.d.ts
|
|
171
178
|
/**
|
|
172
179
|
* Field filter plugin that restricts fields based on user context
|
|
173
180
|
*
|
|
@@ -181,8 +188,6 @@ declare function elasticSearchPlugin(options: ElasticSearchOptions): Plugin;
|
|
|
181
188
|
* const repo = new Repository(Model, [fieldFilterPlugin(fieldPreset)]);
|
|
182
189
|
*/
|
|
183
190
|
declare function fieldFilterPlugin(fieldPreset: FieldPreset): Plugin;
|
|
184
|
-
//#endregion
|
|
185
|
-
//#region src/plugins/idempotency-store.plugin.d.ts
|
|
186
191
|
interface IdempotencyStorePluginOptions {
|
|
187
192
|
/** Field carrying the deterministic operation key. @default `'key'` */
|
|
188
193
|
keyField?: string;
|
|
@@ -323,8 +328,6 @@ interface IdempotencyStoreMethods<TProgress = Record<string, unknown>, TResult =
|
|
|
323
328
|
* failures, lapsed-claim sweeps). Removed in mongokit 4.
|
|
324
329
|
*/
|
|
325
330
|
declare function idempotencyStorePlugin(options?: IdempotencyStorePluginOptions): Plugin;
|
|
326
|
-
//#endregion
|
|
327
|
-
//#region src/plugins/immutable-states.plugin.d.ts
|
|
328
331
|
/** The slice of a `before:claim` context `allowClaim` predicates see. */
|
|
329
332
|
interface ImmutableClaimView {
|
|
330
333
|
id: unknown;
|
|
@@ -356,6 +359,20 @@ interface ImmutableStatesPluginOptions {
|
|
|
356
359
|
* state — keep the predicate a strict fingerprint.
|
|
357
360
|
*/
|
|
358
361
|
allowClaim?: ((view: ImmutableClaimView) => boolean) | undefined;
|
|
362
|
+
/**
|
|
363
|
+
* Allow the audited retention purge: `delete` / `deleteMany` with
|
|
364
|
+
* `{ mode: 'hard', retentionPurge: { reason, actor? } }` (and
|
|
365
|
+
* `purgeByFilter` / `purgeByField` with `retentionPurge`) may remove frozen
|
|
366
|
+
* rows, emitting `after:immutable-states-purge`. Default `false`: the
|
|
367
|
+
* option is refused (403 `RETENTION_PURGE_DISABLED`).
|
|
368
|
+
*/
|
|
369
|
+
allowPurge?: boolean | undefined;
|
|
370
|
+
/**
|
|
371
|
+
* Allow `archiveByFilter(filter, sink, { retentionPurge })` to delete frozen rows its
|
|
372
|
+
* sink acknowledged, and nothing else (see `appendOnlyPlugin`'s `allowArchive`).
|
|
373
|
+
* Implied by `allowPurge`. Default `false`.
|
|
374
|
+
*/
|
|
375
|
+
allowArchive?: boolean | undefined;
|
|
359
376
|
/** Domain error to throw. Default: 403 `IMMUTABLE_STATE_VIOLATION`. */
|
|
360
377
|
errorFactory?: ((ctx: {
|
|
361
378
|
id: unknown;
|
|
@@ -363,9 +380,14 @@ interface ImmutableStatesPluginOptions {
|
|
|
363
380
|
state?: string | undefined;
|
|
364
381
|
}) => Error) | undefined;
|
|
365
382
|
}
|
|
383
|
+
/** Per-call purge request (`options.retentionPurge`). */
|
|
384
|
+
type ImmutablePurgeRequest = RetentionPurgeRequest;
|
|
385
|
+
/** Payload of `after:immutable-states-purge`: one per successful purge call. */
|
|
386
|
+
interface ImmutablePurgeEvent extends RetentionPurgeEvent {
|
|
387
|
+
/** The frozen states configured on the plugin. */
|
|
388
|
+
states: readonly string[];
|
|
389
|
+
}
|
|
366
390
|
declare function immutableStatesPlugin(options: ImmutableStatesPluginOptions): Plugin;
|
|
367
|
-
//#endregion
|
|
368
|
-
//#region src/plugins/lease.plugin.d.ts
|
|
369
391
|
interface LeasePluginOptions {
|
|
370
392
|
/** Field carrying the row's status. @default `'status'` */
|
|
371
393
|
statusField?: string;
|
|
@@ -381,7 +403,57 @@ interface LeasePluginOptions {
|
|
|
381
403
|
doneStatus?: string;
|
|
382
404
|
/** Sort fields used to pick the FIFO winner from the lease pool. @default `{ createdAt: 1 }` */
|
|
383
405
|
sort?: Record<string, 1 | -1>;
|
|
406
|
+
/**
|
|
407
|
+
* Clock used by `lease` / `extend` / `release` for both the CAS
|
|
408
|
+
* comparison and the new expiry. A per-call `now` wins over it.
|
|
409
|
+
* Inject one to drive lease expiry from a test or a host `Clock`
|
|
410
|
+
* port. @default `() => new Date()`
|
|
411
|
+
*/
|
|
412
|
+
nowFn?: () => Date;
|
|
413
|
+
/**
|
|
414
|
+
* Statuses whose expired lease `lease()` may recover. Only rows in
|
|
415
|
+
* one of these statuses AND with `leaseExpiresAt < now` are dead
|
|
416
|
+
* leases; a row in any other status is never re-leased, whatever its
|
|
417
|
+
* lease field says (a cancelled row with a stale expiry stays
|
|
418
|
+
* cancelled). @default `[processingStatus]`
|
|
419
|
+
*/
|
|
420
|
+
deadLeaseStatuses?: readonly string[];
|
|
421
|
+
/**
|
|
422
|
+
* Optional attempts counter. When set, every successful `lease()`
|
|
423
|
+
* (first claim and dead-lease recovery alike) applies
|
|
424
|
+
* `$inc: { [attemptsField]: 1 }`. Off by default.
|
|
425
|
+
*/
|
|
426
|
+
attemptsField?: string;
|
|
427
|
+
/**
|
|
428
|
+
* Cap on `attemptsField`. A row whose counter is already
|
|
429
|
+
* `>= maxAttempts` is not leasable; a row missing the field is.
|
|
430
|
+
* Exhausted rows stay where they are until `reapExhausted()` moves
|
|
431
|
+
* them to `exhaustedStatus` (or the host sweeps them itself).
|
|
432
|
+
* Requires `attemptsField` (throws at construction).
|
|
433
|
+
*/
|
|
434
|
+
maxAttempts?: number;
|
|
435
|
+
/**
|
|
436
|
+
* Terminal status `reapExhausted()` moves an exhausted row to (e.g.
|
|
437
|
+
* `'failed'`). Requires `maxAttempts`; must differ from
|
|
438
|
+
* `pendingStatus`, `processingStatus` and every `deadLeaseStatuses`
|
|
439
|
+
* entry (throws at construction). Without it `reapExhausted()` needs
|
|
440
|
+
* a per-call `status`.
|
|
441
|
+
*/
|
|
442
|
+
exhaustedStatus?: string;
|
|
443
|
+
/** Field `reapExhausted()` stamps with the reap time (e.g. `'failedAt'`). Off by default. */
|
|
444
|
+
exhaustedAtField?: string;
|
|
445
|
+
/**
|
|
446
|
+
* Extra predicate ANDed into the PENDING arm only, so not-yet-due rows
|
|
447
|
+
* wait while a dead lease is still recovered. The object form is
|
|
448
|
+
* STATIC (built once); for a time-relative predicate pass the function
|
|
449
|
+
* form, called per `lease()` with the resolved `now` (per-call `now`,
|
|
450
|
+
* else `nowFn()`): `pendingFilter: (now) => ({ dueAt: { $lte: now } })`.
|
|
451
|
+
* A per-call `pendingFilter` replaces this one.
|
|
452
|
+
*/
|
|
453
|
+
pendingFilter?: LeasePendingFilter;
|
|
384
454
|
}
|
|
455
|
+
/** Static pending-arm predicate, or a builder called with the claim's `now`. */
|
|
456
|
+
type LeasePendingFilter = Record<string, unknown> | ((now: Date) => Record<string, unknown>);
|
|
385
457
|
/**
|
|
386
458
|
* Methods contributed by `leasePlugin()`. Use as a type assertion when
|
|
387
459
|
* constructing the repo so call sites get autocomplete:
|
|
@@ -397,9 +469,18 @@ interface LeasePluginOptions {
|
|
|
397
469
|
interface LeaseMethods<TDoc> {
|
|
398
470
|
/**
|
|
399
471
|
* Atomically claim the next available row. Matches rows that are
|
|
400
|
-
* either in `pendingStatus`
|
|
401
|
-
*
|
|
402
|
-
*
|
|
472
|
+
* either in `pendingStatus` (AND `pendingFilter`, when given) OR in a
|
|
473
|
+
* `deadLeaseStatuses` status with an expired `leaseExpiresAt` (dead
|
|
474
|
+
* lease recovery). The caller's `filter` is kept as given (its own
|
|
475
|
+
* `$or` included) and the claim condition is ANDed beside it. Sets
|
|
476
|
+
* status to `processingStatus`, stamps `leasedBy`, pushes
|
|
477
|
+
* `leaseExpiresAt = now + leaseFor`, and bumps `attemptsField` when
|
|
478
|
+
* configured.
|
|
479
|
+
*
|
|
480
|
+
* `leasedBy` is the fencing token for `extend` / `release`: make it
|
|
481
|
+
* unique per claim (e.g. `${instanceId}:${randomUUID()}`). A worker
|
|
482
|
+
* that reuses one id could otherwise finalise a stale run after its
|
|
483
|
+
* own lapsed lease was re-leased under the same id.
|
|
403
484
|
*
|
|
404
485
|
* @returns The leased doc, or `null` when no row matches.
|
|
405
486
|
*/
|
|
@@ -407,17 +488,24 @@ interface LeaseMethods<TDoc> {
|
|
|
407
488
|
filter?: Record<string, unknown>;
|
|
408
489
|
leaseFor: number;
|
|
409
490
|
leasedBy: string;
|
|
491
|
+
/** Clock reading for this call. @default plugin `nowFn()` */
|
|
492
|
+
now?: Date;
|
|
493
|
+
/** Replaces the plugin-level `pendingFilter` for this call. */
|
|
494
|
+
pendingFilter?: LeasePendingFilter;
|
|
410
495
|
options?: Record<string, unknown>;
|
|
411
496
|
}): Promise<TDoc | null>;
|
|
412
497
|
/**
|
|
413
498
|
* Push a held lease's expiry further. Only succeeds when the lease
|
|
414
|
-
* is still ours (`leasedBy === leasedBy && leaseExpiresAt > now`)
|
|
499
|
+
* is still ours (`leasedBy === leasedBy && leaseExpiresAt > now`) and
|
|
500
|
+
* the row is still in `processingStatus` (a row the host moved to a
|
|
501
|
+
* terminal status, e.g. cancelled, is not kept alive).
|
|
415
502
|
* Returns `null` if the lease was lost — caller should drop the
|
|
416
503
|
* work, since someone else has already started replaying it.
|
|
417
504
|
*/
|
|
418
505
|
extend(id: string | ObjectId, opts: {
|
|
419
506
|
leasedBy: string;
|
|
420
507
|
leaseFor: number;
|
|
508
|
+
now?: Date;
|
|
421
509
|
options?: Record<string, unknown>;
|
|
422
510
|
}): Promise<TDoc | null>;
|
|
423
511
|
/**
|
|
@@ -434,17 +522,48 @@ interface LeaseMethods<TDoc> {
|
|
|
434
522
|
* `lease()` predicate) skip this row.
|
|
435
523
|
*
|
|
436
524
|
* Returns the released doc, or `null` when the CAS lost (lease
|
|
437
|
-
* expired / held by another worker / row gone
|
|
525
|
+
* expired / held by another worker / row gone / row no longer in
|
|
526
|
+
* `processingStatus`, e.g. the host cancelled it mid-run).
|
|
438
527
|
*/
|
|
439
528
|
release(id: string | ObjectId, opts: {
|
|
440
529
|
leasedBy: string;
|
|
441
530
|
finalStatus?: string;
|
|
531
|
+
now?: Date;
|
|
442
532
|
options?: Record<string, unknown>;
|
|
443
533
|
}): Promise<TDoc | null>;
|
|
534
|
+
/**
|
|
535
|
+
* Move every EXHAUSTED row to `exhaustedStatus` and return the moved
|
|
536
|
+
* rows (after the move), so the host only audits and alerts. A row is
|
|
537
|
+
* exhausted when `lease()` would claim it but for the attempts cap:
|
|
538
|
+
* `attemptsField >= maxAttempts` AND either pending (and passing
|
|
539
|
+
* `pendingFilter`) or in a `deadLeaseStatuses` status whose lease
|
|
540
|
+
* lapsed (`leaseExpiresAt < now`). A row whose lease is still live is
|
|
541
|
+
* left alone: its holder may still release it.
|
|
542
|
+
*
|
|
543
|
+
* Each move is a compare-and-set on that same condition, so two
|
|
544
|
+
* reapers never both return a row, and a row is returned once: once
|
|
545
|
+
* moved it no longer matches. Clears `leasedBy` / `leaseExpiresAt`
|
|
546
|
+
* and stamps `exhaustedAtField` with `now` when configured. The
|
|
547
|
+
* caller's `filter` is ANDed in as with `lease()`. Requires
|
|
548
|
+
* `maxAttempts`; reads at most `limit` rows (default 100) in `sort`
|
|
549
|
+
* order, so call it again until it returns `[]`. A batch shorter than
|
|
550
|
+
* `limit` does not mean none are left: a concurrent reaper may have
|
|
551
|
+
* moved some of the rows read (and keeps draining them).
|
|
552
|
+
*/
|
|
553
|
+
reapExhausted(opts?: {
|
|
554
|
+
filter?: Record<string, unknown>;
|
|
555
|
+
/** Clock reading for this call. @default plugin `nowFn()` */
|
|
556
|
+
now?: Date;
|
|
557
|
+
/** Rows read per call. @default 100 */
|
|
558
|
+
limit?: number;
|
|
559
|
+
/** Replaces the plugin-level `exhaustedStatus` for this call. */
|
|
560
|
+
status?: string;
|
|
561
|
+
/** Replaces the plugin-level `pendingFilter` for this call. */
|
|
562
|
+
pendingFilter?: LeasePendingFilter;
|
|
563
|
+
options?: Record<string, unknown>;
|
|
564
|
+
}): Promise<TDoc[]>;
|
|
444
565
|
}
|
|
445
566
|
declare function leasePlugin(options?: LeasePluginOptions): Plugin;
|
|
446
|
-
//#endregion
|
|
447
|
-
//#region src/plugins/method-registry.plugin.d.ts
|
|
448
567
|
/**
|
|
449
568
|
* Extended repository interface with method registry
|
|
450
569
|
*/
|
|
@@ -457,8 +576,6 @@ interface MethodRegistryRepository extends RepositoryInstance {
|
|
|
457
576
|
* Method registry plugin that enables dynamic method registration
|
|
458
577
|
*/
|
|
459
578
|
declare function methodRegistryPlugin(): Plugin;
|
|
460
|
-
//#endregion
|
|
461
|
-
//#region src/plugins/mongo-operations.plugin.d.ts
|
|
462
579
|
/**
|
|
463
580
|
* MongoDB operations plugin
|
|
464
581
|
*
|
|
@@ -689,8 +806,6 @@ interface MongoOperationsMethods<TDoc> {
|
|
|
689
806
|
*/
|
|
690
807
|
incrementIfBelow(id: string | ObjectId, field: string, ceiling: number, by?: number, options?: Record<string, unknown>): Promise<TDoc | null>;
|
|
691
808
|
}
|
|
692
|
-
//#endregion
|
|
693
|
-
//#region src/plugins/observability.plugin.d.ts
|
|
694
809
|
interface OperationMetric {
|
|
695
810
|
/** Operation name (e.g., 'create', 'getAll', 'update') */
|
|
696
811
|
operation: string;
|
|
@@ -718,8 +833,6 @@ interface ObservabilityOptions {
|
|
|
718
833
|
slowThresholdMs?: number;
|
|
719
834
|
}
|
|
720
835
|
declare function observabilityPlugin(options: ObservabilityOptions): Plugin;
|
|
721
|
-
//#endregion
|
|
722
|
-
//#region src/plugins/search-keys.plugin.d.ts
|
|
723
836
|
interface SearchKeysPluginOptions {
|
|
724
837
|
/** Source fields (dotted paths allowed; string, number, or arrays of them). */
|
|
725
838
|
fields: readonly string[];
|
|
@@ -727,8 +840,6 @@ interface SearchKeysPluginOptions {
|
|
|
727
840
|
keysField?: string;
|
|
728
841
|
}
|
|
729
842
|
declare function searchKeysPlugin(options: SearchKeysPluginOptions): Plugin;
|
|
730
|
-
//#endregion
|
|
731
|
-
//#region src/plugins/soft-delete.plugin.d.ts
|
|
732
843
|
/**
|
|
733
844
|
* Soft delete plugin
|
|
734
845
|
*
|
|
@@ -820,8 +931,6 @@ interface SoftDeleteMethods<TDoc> {
|
|
|
820
931
|
session?: unknown;
|
|
821
932
|
}): Promise<OffsetPaginationResult<TDoc>>;
|
|
822
933
|
}
|
|
823
|
-
//#endregion
|
|
824
|
-
//#region src/plugins/subdocument.plugin.d.ts
|
|
825
934
|
/**
|
|
826
935
|
* Subdocument plugin for managing nested arrays
|
|
827
936
|
*
|
|
@@ -902,8 +1011,6 @@ interface SubdocumentMethods<TDoc> {
|
|
|
902
1011
|
*/
|
|
903
1012
|
deleteSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: Record<string, unknown>): Promise<TDoc>;
|
|
904
1013
|
}
|
|
905
|
-
//#endregion
|
|
906
|
-
//#region src/plugins/tenant-context.d.ts
|
|
907
1014
|
interface TenantStore {
|
|
908
1015
|
tenantId: string | undefined;
|
|
909
1016
|
[key: string]: unknown;
|
|
@@ -924,8 +1031,6 @@ interface TenantContext {
|
|
|
924
1031
|
readonly storage: AsyncLocalStorage<TenantStore>;
|
|
925
1032
|
}
|
|
926
1033
|
declare function createTenantContext(): TenantContext;
|
|
927
|
-
//#endregion
|
|
928
|
-
//#region src/plugins/timestamp.plugin.d.ts
|
|
929
1034
|
/**
|
|
930
1035
|
* Timestamp plugin that auto-injects timestamps
|
|
931
1036
|
*
|
|
@@ -933,8 +1038,6 @@ declare function createTenantContext(): TenantContext;
|
|
|
933
1038
|
* const repo = new Repository(Model, [timestampPlugin()]);
|
|
934
1039
|
*/
|
|
935
1040
|
declare function timestampPlugin(): Plugin;
|
|
936
|
-
//#endregion
|
|
937
|
-
//#region src/plugins/validation-chain.plugin.d.ts
|
|
938
1041
|
type OperationType = 'create' | 'createMany' | 'update' | 'findOneAndUpdate' | 'delete';
|
|
939
1042
|
/**
|
|
940
1043
|
* Validation chain plugin
|
|
@@ -972,5 +1075,4 @@ declare function immutableField(field: string): ValidatorDefinition;
|
|
|
972
1075
|
* Ensure field value is unique
|
|
973
1076
|
*/
|
|
974
1077
|
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 };
|
|
1078
|
+
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 };
|