@classytic/mongokit 3.44.0 → 3.46.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 +23 -3
- package/dist/{PaginationEngine-C9iS0U5l.mjs → PaginationEngine-BRlLTQQz.mjs} +1 -1
- package/dist/{PaginationEngine-D17AthKw.d.mts → PaginationEngine-BWb-c47a.d.mts} +1 -1
- package/dist/{Repository-B6oL6OMv.d.mts → Repository-DJuRmBNx.d.mts} +16 -7
- package/dist/{Repository-eMRYZ_2Y.mjs → Repository-DheA7oW-.mjs} +135 -29
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.mjs +2 -2
- package/dist/{actions-DExyXMTy.mjs → actions-DKQx9ToJ.mjs} +1 -1
- package/dist/ai/index.d.mts +1 -1
- package/dist/better-auth/index.d.mts +5 -2
- package/dist/better-auth/index.mjs +10 -20
- package/dist/{create-repository-D7MQpIZo.mjs → create-repository-C9DHHcl7.mjs} +3 -3
- package/dist/{create-repository-BOFUYj1l.d.mts → create-repository-DG-gwOf0.d.mts} +5 -5
- package/dist/{index-8QUEsOFI.d.mts → index-5mhQ63_B.d.mts} +2 -2
- package/dist/index.d.mts +19 -18
- package/dist/index.mjs +10 -10
- package/dist/kernel-conformance/index.d.mts +44 -3
- package/dist/kernel-conformance/index.mjs +43 -4
- package/dist/{method-registry.plugin-CGAepsBU.mjs → method-registry.plugin-BeJfQBJV.mjs} +2 -2
- package/dist/{multi-tenant.plugin-DfeDMiI8.d.mts → multi-tenant.plugin-BTPtCLNK.d.mts} +2 -2
- package/dist/{operations-Dw9OFV0V.d.mts → operations-D6XsHx4e.d.mts} +6 -7
- package/dist/outbox/index.d.mts +2 -2
- package/dist/outbox/index.mjs +2 -2
- package/dist/pagination/PaginationEngine.d.mts +1 -1
- package/dist/pagination/PaginationEngine.mjs +1 -1
- package/dist/pagination/utils/limits.d.mts +1 -1
- package/dist/{pagination-DAUg5zOY.d.mts → pagination-BAM9cA4N.d.mts} +5 -7
- package/dist/{plugin-options-Bpcuz9kS.d.mts → plugin-options-DrNGWV5b.d.mts} +2 -2
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +4 -4
- package/dist/{query-defaults-aUoKlEbh.mjs → query-defaults-DwvWUjZU.mjs} +16 -51
- package/dist/read-model/index.d.mts +1 -1
- package/dist/{repository-DzVIwhU2.d.mts → repository-B0aFVgP2.d.mts} +1 -1
- package/dist/{retention-purge-DqcYvRnG.d.mts → retention-purge-CCd_VXUf.d.mts} +4 -1
- package/dist/sync/index.d.mts +25 -9
- package/dist/sync/index.mjs +122 -12
- package/dist/testkit/index.d.mts +2 -2
- package/dist/testkit/index.mjs +1 -1
- package/dist/{timestamp.plugin-Bz_zL9PX.mjs → timestamp.plugin-B-IJrlYb.mjs} +1 -1
- package/dist/{to-plain-PO5r1Qoy.d.mts → to-plain-Do-8jTKC.d.mts} +2 -2
- package/dist/{transaction-C2PFxfIv.mjs → transaction-C6Oj941P.mjs} +14 -12
- package/dist/{update-DcfmNbJe.mjs → update-CYaJMu6j.mjs} +2 -4
- package/dist/utils/index.d.mts +1 -1
- package/dist/{validation-chain.plugin-B3gZCZj4.d.mts → validation-chain.plugin-COYrUdd8.d.mts} +19 -4
- package/dist/{validation-chain.plugin-DNY6MIF6.mjs → validation-chain.plugin-DJplVJ12.mjs} +10 -7
- package/package.json +11 -11
- package/skills/mongokit/references/plugins-tenancy.md +1 -0
- package/skills/mongokit/references/transactions-outbox.md +3 -1
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { n as idVariants } from "./id-resolution-Cqh49d9J.mjs";
|
|
2
|
-
import { a as ALL_OPERATIONS, c as READ_OPERATIONS, d as RETENTION_PURGE_ERROR_CODES, i as searchKeysPlugin, l as operationsByPolicyKey, n as Repository, o as MUTATING_OPERATIONS, r as AggregationBuilder, s as OP_REGISTRY, t as HOOK_PRIORITY, u as createMongoPurgePort } from "./Repository-
|
|
3
|
-
import { C as isCreateManyPartialError, g as LookupBuilder, v as compileFilterToMongo } from "./update-
|
|
4
|
-
import { t as actions_exports } from "./actions-
|
|
5
|
-
import { a as supportsTransactions, c as MONGOKIT_CAPABILITIES, d as probeMongoCapabilities, f as resetCapabilityProbeCache, h as transactionResolutionOf, i as runTransaction, l as capabilitiesForSupport, m as resolveTransactionSupport, n as batchTransaction, o as withTransaction, p as resolveMongoCapabilities, r as isTransactionUnsupported, t as TRANSACTION_ERROR_CODES, u as classifyHelloReply } from "./transaction-
|
|
6
|
-
import { t as createRepository } from "./create-repository-
|
|
2
|
+
import { a as ALL_OPERATIONS, c as READ_OPERATIONS, d as RETENTION_PURGE_ERROR_CODES, i as searchKeysPlugin, l as operationsByPolicyKey, n as Repository, o as MUTATING_OPERATIONS, r as AggregationBuilder, s as OP_REGISTRY, t as HOOK_PRIORITY, u as createMongoPurgePort } from "./Repository-DheA7oW-.mjs";
|
|
3
|
+
import { C as isCreateManyPartialError, g as LookupBuilder, v as compileFilterToMongo } from "./update-CYaJMu6j.mjs";
|
|
4
|
+
import { t as actions_exports } from "./actions-DKQx9ToJ.mjs";
|
|
5
|
+
import { a as supportsTransactions, c as MONGOKIT_CAPABILITIES, d as probeMongoCapabilities, f as resetCapabilityProbeCache, h as transactionResolutionOf, i as runTransaction, l as capabilitiesForSupport, m as resolveTransactionSupport, n as batchTransaction, o as withTransaction, p as resolveMongoCapabilities, r as isTransactionUnsupported, t as TRANSACTION_ERROR_CODES, u as classifyHelloReply } from "./transaction-C6Oj941P.mjs";
|
|
6
|
+
import { t as createRepository } from "./create-repository-C9DHHcl7.mjs";
|
|
7
7
|
import { n as defineModel, r as isModelRegistered, t as ModelCollisionError } from "./model-registry-DrVfJ3Nt.mjs";
|
|
8
|
-
import { c as PAGINATION_ERROR_CODES, h as resetPaginationDefaults, m as getPaginationDefaults, p as configurePaginationDefaults, t as PaginationEngine } from "./PaginationEngine-
|
|
9
|
-
import { C as ensureAuditTrailReady, S as auditTrailPlugin, _ as prefixedId, a as declareTenantContextKey, b as cachePlugin, c as tenantContextKeysOf, d as customIdPlugin, f as dateSequentialId, g as periodCounterKey, h as getNextSequence, i as multiTenantPlugin, l as civilPeriodKey, m as getNextPeriodSequence, n as softDeletePlugin, o as forwardScope, p as ensureSequenceAtLeast, r as adminBypass, s as isScopeKey, t as timestampPlugin, u as createSequenceCounter, v as readSequence, w as auditLogPlugin, x as AuditTrailQuery, y as sequentialId } from "./timestamp.plugin-
|
|
10
|
-
import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "./validation-chain.plugin-
|
|
11
|
-
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-
|
|
8
|
+
import { c as PAGINATION_ERROR_CODES, h as resetPaginationDefaults, m as getPaginationDefaults, p as configurePaginationDefaults, t as PaginationEngine } from "./PaginationEngine-BRlLTQQz.mjs";
|
|
9
|
+
import { C as ensureAuditTrailReady, S as auditTrailPlugin, _ as prefixedId, a as declareTenantContextKey, b as cachePlugin, c as tenantContextKeysOf, d as customIdPlugin, f as dateSequentialId, g as periodCounterKey, h as getNextSequence, i as multiTenantPlugin, l as civilPeriodKey, m as getNextPeriodSequence, n as softDeletePlugin, o as forwardScope, p as ensureSequenceAtLeast, r as adminBypass, s as isScopeKey, t as timestampPlugin, u as createSequenceCounter, v as readSequence, w as auditLogPlugin, x as AuditTrailQuery, y as sequentialId } from "./timestamp.plugin-B-IJrlYb.mjs";
|
|
10
|
+
import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "./validation-chain.plugin-DJplVJ12.mjs";
|
|
11
|
+
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-BeJfQBJV.mjs";
|
|
12
12
|
import { n as warn, t as configureLogger } from "./logger-hbWOlj_X.mjs";
|
|
13
13
|
import { GEO_OPERATORS, parseGeoFilter } from "./query/primitives/geo.mjs";
|
|
14
14
|
import { buildFieldTypeMap, coerceHeuristic } from "./query/primitives/coercion.mjs";
|
|
15
15
|
import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-DjdmPLWO.mjs";
|
|
16
16
|
import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
|
|
17
17
|
import { n as declareCollectionScope, t as JOIN_ERROR_CODES } from "./join-scope-C1gOtZ59.mjs";
|
|
18
|
-
import { a as
|
|
18
|
+
import { a as configureAggregateDefaults, c as resetQueryDefaults, i as assertQueryDefaultsConfigured, l as resolveQueryOptions, o as configureQueryDefaults, s as getQueryDefaults, t as QUERY_DEFAULTS_ERROR_CODES } from "./query-defaults-DwvWUjZU.mjs";
|
|
19
19
|
import { _ as tokenizeSearchText, d as buildSearchKeys, f as prefixSearchFilter, g as normalizeSearchText, h as findSearchMatches, l as DEFAULT_SEARCH_KEYS_FIELD, m as searchKeysPath, n as SearchKeysWriteError, p as searchKeysIndex, t as SEARCH_KEYS_ERROR_CODES, u as MAX_PREFIX_SEARCH_TERMS } from "./derive-Dxsc31fV.mjs";
|
|
20
20
|
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-DPFaFw9Y.mjs";
|
|
21
21
|
import "./search/index.mjs";
|
|
@@ -37,14 +37,16 @@ export declare const KERNEL_CONFORMANCE_CHECKS: readonly [
|
|
|
37
37
|
/** §11.5 — an injected outbox that does not enlist `ctx.session` is REFUSED. (conditional) */
|
|
38
38
|
'outbox-requires-transactional-save',
|
|
39
39
|
/** §11.10 — a blueprint with optional modules off registers no extra models. (conditional) */
|
|
40
|
-
'optional-modules-register-no-models'
|
|
40
|
+
'optional-modules-register-no-models',
|
|
41
|
+
/** scale D7 — every unique index leads with the tenant field, or is a registered global. (conditional) */
|
|
42
|
+
'unique-indexes-tenant-prefixed'];
|
|
41
43
|
type ConformanceCheck = (typeof KERNEL_CONFORMANCE_CHECKS)[number];
|
|
42
44
|
/**
|
|
43
45
|
* Checks that only run when the kernel supplies the input they need. When the input is
|
|
44
46
|
* absent they are reported as NOT EXERCISED — a visible marker test plus a report entry,
|
|
45
47
|
* never a silent pass.
|
|
46
48
|
*/
|
|
47
|
-
export declare const CONDITIONAL_CHECKS: readonly ["bind-verifies-requirements", "outbox-requires-transactional-save", "optional-modules-register-no-models"];
|
|
49
|
+
export declare const CONDITIONAL_CHECKS: readonly ["bind-verifies-requirements", "outbox-requires-transactional-save", "optional-modules-register-no-models", "unique-indexes-tenant-prefixed"];
|
|
48
50
|
/**
|
|
49
51
|
* The two runner functions the suite needs, INJECTED by the consumer.
|
|
50
52
|
*
|
|
@@ -118,6 +120,23 @@ interface KernelConformanceReport {
|
|
|
118
120
|
readonly skipped: readonly ConformanceCheckStatus[];
|
|
119
121
|
readonly notExercised: readonly ConformanceCheckStatus[];
|
|
120
122
|
}
|
|
123
|
+
/** What becomes of a deliberately global unique index once a deployment is sharded or podded (D7). */
|
|
124
|
+
type GlobalUniqueDisposition = 'shard-key-prefix' | 'identity-registry' | 'pod-local' | 'drop';
|
|
125
|
+
/** A unique index that is global ON PURPOSE. A bare name is not enough: the reason is the contract. */
|
|
126
|
+
interface AllowedGlobalUnique {
|
|
127
|
+
/** The index NAME as declared (`options.name`), or its keys joined by `,` when unnamed. */
|
|
128
|
+
readonly index: string;
|
|
129
|
+
readonly reason: string;
|
|
130
|
+
readonly t2: GlobalUniqueDisposition;
|
|
131
|
+
}
|
|
132
|
+
interface TenantUniquesOptions {
|
|
133
|
+
/** The tenant field the kernel prefixes with, e.g. `'organizationId'`. */
|
|
134
|
+
readonly tenantField: string;
|
|
135
|
+
/** Bind the kernel with tenancy ENABLED (field strategy) on the connection the suite supplies. */
|
|
136
|
+
readonly bindScoped: (connection: Connection) => unknown | Promise<unknown>;
|
|
137
|
+
/** Deliberate globals. Empty (the default) means every unique index must be tenant-led. */
|
|
138
|
+
readonly allowGlobal?: readonly AllowedGlobalUnique[];
|
|
139
|
+
}
|
|
121
140
|
interface KernelConformanceOptions<TBlueprint extends KernelBlueprintLike, TEngine> {
|
|
122
141
|
/** Kernel name, e.g. `'party'`. Used in test titles and to derive legacy export names. */
|
|
123
142
|
readonly name: string;
|
|
@@ -215,6 +234,28 @@ interface KernelConformanceOptions<TBlueprint extends KernelBlueprintLike, TEngi
|
|
|
215
234
|
* `optional-modules-register-no-models` (§11.10).
|
|
216
235
|
*/
|
|
217
236
|
readonly minimalBlueprint?: () => TBlueprint;
|
|
237
|
+
/**
|
|
238
|
+
* Enables `unique-indexes-tenant-prefixed` (scale decision D7).
|
|
239
|
+
*
|
|
240
|
+
* MongoDB refuses `shardCollection` on a tenant key when ANY unique index does not start with
|
|
241
|
+
* that key, so one global unique makes the whole collection unshardable by tenant and turns a
|
|
242
|
+
* later move to pods or shards into a data migration. The check binds the kernel with tenancy
|
|
243
|
+
* ON, reads every registered schema's indexes, and requires each unique one to lead with the
|
|
244
|
+
* tenant field, or to be registered in `allowGlobal` with a reason and a T2 disposition.
|
|
245
|
+
*
|
|
246
|
+
* It also fails when it inspected no unique index at all (a scan that finds nothing proves
|
|
247
|
+
* nothing), and when an `allowGlobal` entry names an index that no longer exists or is now
|
|
248
|
+
* tenant-led (a stale entry would hide a real one).
|
|
249
|
+
*
|
|
250
|
+
* ```ts
|
|
251
|
+
* tenantUniques: {
|
|
252
|
+
* tenantField: 'organizationId',
|
|
253
|
+
* bindScoped: (connection) => defineX({ tenant: { enabled: true } }).bind(connection, runtime),
|
|
254
|
+
* allowGlobal: [{ index: 'directory_site_slug', reason: 'public slug resolved without a tenant', t2: 'identity-registry' }],
|
|
255
|
+
* }
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
readonly tenantUniques?: TenantUniquesOptions;
|
|
218
259
|
/**
|
|
219
260
|
* Explicit, reasoned opt-outs. Unknown or duplicate ids throw at call time. Every skip is
|
|
220
261
|
* printed and registered as a visible marker test.
|
|
@@ -240,4 +281,4 @@ interface InstrumentedTransport {
|
|
|
240
281
|
* "did I create this?", never by inspecting the object.
|
|
241
282
|
*/
|
|
242
283
|
export declare function instrumentTransport(inner: EventTransportLike): InstrumentedTransport;
|
|
243
|
-
export type { ConformanceCheck, ConformanceCheckOutcome, ConformanceCheckStatus, ConformanceConnect, ConformanceConnectionHandle, ConformanceEvent, ConformanceRunner, ConformanceSkip, EventTransportLike, InstrumentedTransport, KernelBindContext, KernelBlueprintLike, KernelConformanceOptions, KernelConformanceReport };
|
|
284
|
+
export type { AllowedGlobalUnique, ConformanceCheck, ConformanceCheckOutcome, ConformanceCheckStatus, ConformanceConnect, ConformanceConnectionHandle, ConformanceEvent, ConformanceRunner, ConformanceSkip, EventTransportLike, GlobalUniqueDisposition, InstrumentedTransport, KernelBindContext, KernelBlueprintLike, KernelConformanceOptions, KernelConformanceReport, TenantUniquesOptions };
|
|
@@ -104,7 +104,8 @@ const KERNEL_CONFORMANCE_CHECKS = [
|
|
|
104
104
|
"maintenance-fails-loud",
|
|
105
105
|
"bind-verifies-requirements",
|
|
106
106
|
"outbox-requires-transactional-save",
|
|
107
|
-
"optional-modules-register-no-models"
|
|
107
|
+
"optional-modules-register-no-models",
|
|
108
|
+
"unique-indexes-tenant-prefixed"
|
|
108
109
|
];
|
|
109
110
|
/**
|
|
110
111
|
* Checks that only run when the kernel supplies the input they need. When the input is
|
|
@@ -114,7 +115,8 @@ const KERNEL_CONFORMANCE_CHECKS = [
|
|
|
114
115
|
const CONDITIONAL_CHECKS = [
|
|
115
116
|
"bind-verifies-requirements",
|
|
116
117
|
"outbox-requires-transactional-save",
|
|
117
|
-
"optional-modules-register-no-models"
|
|
118
|
+
"optional-modules-register-no-models",
|
|
119
|
+
"unique-indexes-tenant-prefixed"
|
|
118
120
|
];
|
|
119
121
|
// src/kernel-conformance/suite.ts
|
|
120
122
|
/**
|
|
@@ -217,12 +219,14 @@ function describeKernelConformance(opts) {
|
|
|
217
219
|
const conditionalInputs = {
|
|
218
220
|
"bind-verifies-requirements": "bindWithUnmetRequirement",
|
|
219
221
|
"outbox-requires-transactional-save": "bindWithNonTransactionalOutbox",
|
|
220
|
-
"optional-modules-register-no-models": "minimalBlueprint"
|
|
222
|
+
"optional-modules-register-no-models": "minimalBlueprint",
|
|
223
|
+
"unique-indexes-tenant-prefixed": "tenantUniques"
|
|
221
224
|
};
|
|
222
225
|
const conditionalSupplied = {
|
|
223
226
|
"bind-verifies-requirements": opts.bindWithUnmetRequirement !== void 0,
|
|
224
227
|
"outbox-requires-transactional-save": opts.bindWithNonTransactionalOutbox !== void 0,
|
|
225
|
-
"optional-modules-register-no-models": opts.minimalBlueprint !== void 0
|
|
228
|
+
"optional-modules-register-no-models": opts.minimalBlueprint !== void 0,
|
|
229
|
+
"unique-indexes-tenant-prefixed": opts.tenantUniques !== void 0
|
|
226
230
|
};
|
|
227
231
|
const statuses = KERNEL_CONFORMANCE_CHECKS.map((check) => {
|
|
228
232
|
const reason = skipReasons.get(check);
|
|
@@ -589,6 +593,41 @@ function describeKernelConformance(opts) {
|
|
|
589
593
|
assert(check, drift.extra.length === 0 && drift.missing.length === 0, `the minimal bind registered [${registered.join(", ")}] but declared [${minimal.modelNames.join(", ")}] — a disabled module still compiled a model`);
|
|
590
594
|
});
|
|
591
595
|
});
|
|
596
|
+
register("unique-indexes-tenant-prefixed", "every unique index leads with the tenant field, or is a registered global", async () => {
|
|
597
|
+
const check = "unique-indexes-tenant-prefixed";
|
|
598
|
+
const cfg = opts.tenantUniques;
|
|
599
|
+
const allowed = new Map((cfg.allowGlobal ?? []).map((g) => [g.index, g]));
|
|
600
|
+
for (const g of allowed.values()) assert(check, g.reason.trim().length > 0, `allowGlobal entry '${g.index}' has no reason — a global unique index without one is the defect this check exists to catch`);
|
|
601
|
+
await withConnection(async (connection) => {
|
|
602
|
+
const before = new Set(Object.keys(connection.models));
|
|
603
|
+
await opts.tenantUniques?.bindScoped(connection);
|
|
604
|
+
const offenders = [];
|
|
605
|
+
const seenGlobals = /* @__PURE__ */ new Set();
|
|
606
|
+
let inspected = 0;
|
|
607
|
+
for (const modelName of Object.keys(connection.models).filter((n) => !before.has(n))) {
|
|
608
|
+
const schema = connection.models[modelName]?.schema;
|
|
609
|
+
for (const [fields, options] of schema?.indexes() ?? []) {
|
|
610
|
+
if (!options?.unique) continue;
|
|
611
|
+
inspected++;
|
|
612
|
+
const keys = Object.keys(fields);
|
|
613
|
+
const name = String(options.name ?? keys.join(","));
|
|
614
|
+
if (keys[0] === cfg.tenantField) {
|
|
615
|
+
assert(check, !allowed.has(name), `allowGlobal lists '${name}' but it already leads with '${cfg.tenantField}' — remove the stale entry (it would hide a future global)`);
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
if (allowed.has(name)) {
|
|
619
|
+
seenGlobals.add(name);
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
622
|
+
offenders.push(`${modelName}.${name} {${keys.join(", ")}}`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
assert(check, offenders.length === 0, `unique index(es) that do not lead with '${cfg.tenantField}': [${offenders.join("; ")}]. MongoDB refuses shardCollection on a tenant key while any unique index lacks it. Prefix the index with the tenant field, or register it in tenantUniques.allowGlobal with a reason and a T2 disposition.`);
|
|
626
|
+
assert(check, inspected > 0, "no unique index was inspected — the scoped bind registered none, so this check proved nothing");
|
|
627
|
+
const stale = [...allowed.keys()].filter((n) => !seenGlobals.has(n));
|
|
628
|
+
assert(check, stale.length === 0, `allowGlobal names index(es) that no scoped model declares: [${stale.join(", ")}] — remove them`);
|
|
629
|
+
});
|
|
630
|
+
});
|
|
592
631
|
});
|
|
593
632
|
}
|
|
594
633
|
function defaultReport(report) {
|
|
@@ -31,7 +31,8 @@ const BULK_WRITE_OPTIONS = [
|
|
|
31
31
|
"bypassDocumentValidation",
|
|
32
32
|
"comment",
|
|
33
33
|
"let",
|
|
34
|
-
"ignoreUndefined"
|
|
34
|
+
"ignoreUndefined",
|
|
35
|
+
"maxTimeMS"
|
|
35
36
|
];
|
|
36
37
|
/**
|
|
37
38
|
* Driver options that EXIST but this method does not forward.
|
|
@@ -51,7 +52,6 @@ const BULK_WRITE_OPTIONS = [
|
|
|
51
52
|
const UNSUPPORTED_DRIVER_OPTIONS = /* @__PURE__ */ new Set([
|
|
52
53
|
"forceServerObjectId",
|
|
53
54
|
"timeoutMS",
|
|
54
|
-
"maxTimeMS",
|
|
55
55
|
"retryWrites",
|
|
56
56
|
"checkKeys",
|
|
57
57
|
"serializeFunctions",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as ObjectId } from "./pagination-
|
|
2
|
-
import { l as Plugin, p as RepositoryContext } from "./repository-
|
|
1
|
+
import { A as ObjectId } from "./pagination-BAM9cA4N.mjs";
|
|
2
|
+
import { l as Plugin, p as RepositoryContext } from "./repository-B0aFVgP2.mjs";
|
|
3
3
|
import mongoose, { Connection } from "mongoose";
|
|
4
4
|
import { CacheAdapter as CacheAdapter$1, CacheOptions, RepositoryCacheHandle as RepositoryCacheHandle$1, RepositoryCachePluginOptions, cachePlugin } from "@classytic/repo-core/cache";
|
|
5
5
|
import { TenantConfig } from "@classytic/repo-core/tenant";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as ObjectId, F as SortSpec, M as ReadPreferenceType, N as SelectSpec, b as WriteConcernSpec, i as CountStrategy, j as PopulateSpec, r as CollationOptions, v as ReadConcernLevel } from "./pagination-
|
|
1
|
+
import { A as ObjectId, F as SortSpec, M as ReadPreferenceType, N as SelectSpec, b as WriteConcernSpec, i as CountStrategy, j as PopulateSpec, r as CollationOptions, v as ReadConcernLevel } from "./pagination-BAM9cA4N.mjs";
|
|
2
2
|
import { DeleteManyResult, DeleteResult, LookupPopulateResult, UpdateManyResult } from "@classytic/repo-core/repository";
|
|
3
3
|
import { PipelineStage, PopulateOptions } from "mongoose";
|
|
4
4
|
import { Filter } from "@classytic/repo-core/filter";
|
|
@@ -378,12 +378,11 @@ interface CacheOperationOptions {
|
|
|
378
378
|
cache?: import('@classytic/repo-core/cache').CacheOptions;
|
|
379
379
|
}
|
|
380
380
|
/**
|
|
381
|
-
* `
|
|
382
|
-
*
|
|
383
|
-
* NOT
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
* from `maxCommitTimeMS`, which only bounds a single `commitTransaction` server call.
|
|
381
|
+
* `TransactionOptions` (readConcern, writeConcern, readPreference, maxCommitTimeMS) PLUS
|
|
382
|
+
* `timeoutMS`: the budget for the WHOLE transaction, including its retry loop (default 120 s).
|
|
383
|
+
* It is enforced by mongokit, NOT the driver (the driver's `timeoutMS` is a no-op since 7.8):
|
|
384
|
+
* every mongokit operation inside is sent with `maxTimeMS` = what remains, and the commit with
|
|
385
|
+
* `maxCommitTimeMS` = what remained when the attempt started.
|
|
387
386
|
*/
|
|
388
387
|
type ConvenientTransactionOptions = import('mongoose').mongo.TransactionOptions & {
|
|
389
388
|
timeoutMS?: number;
|
package/dist/outbox/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as Repository } from "../Repository-
|
|
2
|
-
import { u as PaginationConfig } from "../pagination-
|
|
1
|
+
import { r as Repository } from "../Repository-DJuRmBNx.mjs";
|
|
2
|
+
import { u as PaginationConfig } from "../pagination-BAM9cA4N.mjs";
|
|
3
3
|
import { Connection, Model } from "mongoose";
|
|
4
4
|
/** Delivery states. `dead_letter` is terminal and operator-visible. */
|
|
5
5
|
export declare const OUTBOX_STATUSES: readonly ['pending', 'delivered', 'dead_letter'];
|
package/dist/outbox/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-
|
|
2
|
-
import { n as Repository } from "../Repository-
|
|
1
|
+
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-BeJfQBJV.mjs";
|
|
2
|
+
import { n as Repository } from "../Repository-DheA7oW-.mjs";
|
|
3
3
|
import { Schema } from "mongoose";
|
|
4
4
|
// src/outbox/index.ts
|
|
5
5
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as PaginationEngine, t as CountMemoKey } from "../PaginationEngine-
|
|
1
|
+
import { n as PaginationEngine, t as CountMemoKey } from "../PaginationEngine-BWb-c47a.mjs";
|
|
2
2
|
export { CountMemoKey, PaginationEngine };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as PaginationEngine } from "../PaginationEngine-
|
|
1
|
+
export { t as PaginationEngine } from "../PaginationEngine-BRlLTQQz.mjs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Document, Model, PipelineStage, PopulateOptions, Types } from "mongoose";
|
|
2
2
|
/**
|
|
3
3
|
* Core query/document primitives shared across every mongokit module —
|
|
4
4
|
* sort/select/populate/filter specs and the mongoose-facing aliases.
|
|
@@ -99,17 +99,15 @@ declare function getQueryDefaults(): {
|
|
|
99
99
|
/** Back to no deployment defaults. For tests. */
|
|
100
100
|
declare function resetQueryDefaults(): void;
|
|
101
101
|
/**
|
|
102
|
-
* Boot check (M7): throws unless the deployment sets a query `maxTimeMS
|
|
103
|
-
* is
|
|
102
|
+
* Boot check (M7): throws unless the deployment sets a query `maxTimeMS`. Returns what it verified.
|
|
103
|
+
* A client `timeoutMS` is not checked: the driver (7.8+) drops it from the client options and only
|
|
104
|
+
* logs a process warning, so there is nothing to read; it bounds nothing either way.
|
|
104
105
|
*/
|
|
105
|
-
declare function assertQueryDefaultsConfigured(
|
|
106
|
+
declare function assertQueryDefaultsConfigured(): {
|
|
106
107
|
maxTimeMS: number;
|
|
107
|
-
timeoutMS?: number;
|
|
108
108
|
};
|
|
109
109
|
declare const QUERY_DEFAULTS_ERROR_CODES: {
|
|
110
110
|
readonly NOT_CONFIGURED: 'mongokit.query_defaults.not_configured';
|
|
111
|
-
/** A per-call bound inside a transaction that carries its own CSOT budget (the driver forbids both). */
|
|
112
|
-
readonly TIMEOUT_IN_TRANSACTION: 'mongokit.query_defaults.timeout_in_transaction';
|
|
113
111
|
};
|
|
114
112
|
/** Resolve the options one command runs with. `repo` is the repository's own defaults. */
|
|
115
113
|
declare function resolveQueryOptions(kind: CommandKind, perCall: PerCallQueryOptions, repo?: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as ObjectId, F as SortSpec, N as SelectSpec, j as PopulateSpec } from "./pagination-
|
|
2
|
-
import { h as RepositoryInstance, p as RepositoryContext } from "./repository-
|
|
1
|
+
import { A as ObjectId, F as SortSpec, N as SelectSpec, j as PopulateSpec } from "./pagination-BAM9cA4N.mjs";
|
|
2
|
+
import { h as RepositoryInstance, p as RepositoryContext } from "./repository-B0aFVgP2.mjs";
|
|
3
3
|
import { OffsetPaginationResult } from "@classytic/repo-core/pagination";
|
|
4
4
|
/** Field preset configuration (field-filter plugin) */
|
|
5
5
|
interface FieldPreset {
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as ImmutablePurgeEvent, B as elasticSearchPlugin, C as MethodRegistryRepository, D as LeasePluginOptions, E as LeasePendingFilter, F as IdempotencyStoreMethods, G as batchOperationsPlugin, H as BatchOperationsMethods, I as IdempotencyStorePluginOptions, J as AppendOnlyPurgeEvent, K as auditLogPlugin, L as idempotencyStorePlugin, M as ImmutableStatesPluginOptions, N as immutableStatesPlugin, O as leasePlugin, P as IdempotencyClaim, R as fieldFilterPlugin, S as mongoOperationsPlugin, T as LeaseMethods, V as cascadePlugin, X as AggregateHelpersMethods, Y as appendOnlyPlugin, Z as aggregateHelpersPlugin, _ as searchKeysPlugin, a as requireField, b as observabilityPlugin, c as timestampPlugin, d as createTenantContext, f as SubdocumentMethods, g as SearchKeysPluginOptions, h as softDeletePlugin, i as immutableField, j as ImmutablePurgeRequest, k as ImmutableClaimView, l as TenantContext, m as SoftDeleteMethods, n as autoInject, o as uniqueField, p as subdocumentPlugin, q as AppendOnlyPluginOptions, r as blockIf, s as validationChainPlugin, t as OperationType, u as TenantStore, v as ObservabilityOptions, w as methodRegistryPlugin, x as MongoOperationsMethods, y as OperationMetric, z as ElasticSearchOptions } from "../validation-chain.plugin-
|
|
2
|
-
import { A as cachePlugin, B as EnsureAuditTrailReadyOptions, C as prefixedId, D as CacheOptions, E as CacheAdapter, F as AuditTrailMethods, H as ensureAuditTrailReady, I as AuditTrailMode, L as AuditTrailOptions, M as AuditOperation, N as AuditQueryOptions, O as RepositoryCacheHandle, P as AuditQueryResult, R as AuditTrailQuery, T as sequentialId, V as auditTrailPlugin, _ as customIdPlugin, a as DateSequentialIdOptions, b as getNextPeriodSequence, i as CustomIdOptions, j as AuditEntry, k as RepositoryCachePluginOptions, m as SequentialIdOptions, o as IdGenerator, r as multiTenantPlugin, t as MultiTenantOptions, u as PrefixedIdOptions, v as dateSequentialId, x as getNextSequence, z as AuditTrailQueryOptions } from "../multi-tenant.plugin-
|
|
3
|
-
import { C as RepositoryPluginName, S as MongoKitPluginName, l as Plugin, x as MONGOKIT_PLUGIN_NAMES } from "../repository-
|
|
4
|
-
import { n as RetentionPurgeEvent, r as RetentionPurgeRequest, t as RETENTION_PURGE_ERROR_CODES } from "../retention-purge-
|
|
1
|
+
import { A as ImmutablePurgeEvent, B as elasticSearchPlugin, C as MethodRegistryRepository, D as LeasePluginOptions, E as LeasePendingFilter, F as IdempotencyStoreMethods, G as batchOperationsPlugin, H as BatchOperationsMethods, I as IdempotencyStorePluginOptions, J as AppendOnlyPurgeEvent, K as auditLogPlugin, L as idempotencyStorePlugin, M as ImmutableStatesPluginOptions, N as immutableStatesPlugin, O as leasePlugin, P as IdempotencyClaim, R as fieldFilterPlugin, S as mongoOperationsPlugin, T as LeaseMethods, V as cascadePlugin, X as AggregateHelpersMethods, Y as appendOnlyPlugin, Z as aggregateHelpersPlugin, _ as searchKeysPlugin, a as requireField, b as observabilityPlugin, c as timestampPlugin, d as createTenantContext, f as SubdocumentMethods, g as SearchKeysPluginOptions, h as softDeletePlugin, i as immutableField, j as ImmutablePurgeRequest, k as ImmutableClaimView, l as TenantContext, m as SoftDeleteMethods, n as autoInject, o as uniqueField, p as subdocumentPlugin, q as AppendOnlyPluginOptions, r as blockIf, s as validationChainPlugin, t as OperationType, u as TenantStore, v as ObservabilityOptions, w as methodRegistryPlugin, x as MongoOperationsMethods, y as OperationMetric, z as ElasticSearchOptions } from "../validation-chain.plugin-COYrUdd8.mjs";
|
|
2
|
+
import { A as cachePlugin, B as EnsureAuditTrailReadyOptions, C as prefixedId, D as CacheOptions, E as CacheAdapter, F as AuditTrailMethods, H as ensureAuditTrailReady, I as AuditTrailMode, L as AuditTrailOptions, M as AuditOperation, N as AuditQueryOptions, O as RepositoryCacheHandle, P as AuditQueryResult, R as AuditTrailQuery, T as sequentialId, V as auditTrailPlugin, _ as customIdPlugin, a as DateSequentialIdOptions, b as getNextPeriodSequence, i as CustomIdOptions, j as AuditEntry, k as RepositoryCachePluginOptions, m as SequentialIdOptions, o as IdGenerator, r as multiTenantPlugin, t as MultiTenantOptions, u as PrefixedIdOptions, v as dateSequentialId, x as getNextSequence, z as AuditTrailQueryOptions } from "../multi-tenant.plugin-BTPtCLNK.mjs";
|
|
3
|
+
import { C as RepositoryPluginName, S as MongoKitPluginName, l as Plugin, x as MONGOKIT_PLUGIN_NAMES } from "../repository-B0aFVgP2.mjs";
|
|
4
|
+
import { n as RetentionPurgeEvent, r as RetentionPurgeRequest, t as RETENTION_PURGE_ERROR_CODES } from "../retention-purge-CCd_VXUf.mjs";
|
|
5
5
|
import { ChangeLogStore } from "@classytic/repo-core/sync";
|
|
6
6
|
interface ChangeLogPluginOptions {
|
|
7
7
|
/** Durable feed implementing the repo-core/sync contract. */
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "../validation-chain.plugin-
|
|
2
|
-
import { C as ensureAuditTrailReady, S as auditTrailPlugin, _ as prefixedId, b as cachePlugin, d as customIdPlugin, f as dateSequentialId, h as getNextSequence, i as multiTenantPlugin, m as getNextPeriodSequence, n as softDeletePlugin, t as timestampPlugin, w as auditLogPlugin, x as AuditTrailQuery, y as sequentialId } from "../timestamp.plugin-
|
|
3
|
-
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-
|
|
4
|
-
import { d as RETENTION_PURGE_ERROR_CODES, i as searchKeysPlugin } from "../Repository-
|
|
1
|
+
import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "../validation-chain.plugin-DJplVJ12.mjs";
|
|
2
|
+
import { C as ensureAuditTrailReady, S as auditTrailPlugin, _ as prefixedId, b as cachePlugin, d as customIdPlugin, f as dateSequentialId, h as getNextSequence, i as multiTenantPlugin, m as getNextPeriodSequence, n as softDeletePlugin, t as timestampPlugin, w as auditLogPlugin, x as AuditTrailQuery, y as sequentialId } from "../timestamp.plugin-B-IJrlYb.mjs";
|
|
3
|
+
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-BeJfQBJV.mjs";
|
|
4
|
+
import { d as RETENTION_PURGE_ERROR_CODES, i as searchKeysPlugin } from "../Repository-DheA7oW-.mjs";
|
|
5
5
|
// src/plugins/change-log.plugin.ts
|
|
6
6
|
const PLUGIN_NAME = "changeLog";
|
|
7
7
|
/** Marks a repository already captured: the store and scope it writes to. */
|
|
@@ -9,13 +9,13 @@ import mongoose from "mongoose";
|
|
|
9
9
|
* An explicit value always wins (FL1). For an aggregation the aggregate chain is consulted before
|
|
10
10
|
* the generic query chain, because it is the more specific instruction.
|
|
11
11
|
*
|
|
12
|
-
* The bound travels as
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* checks
|
|
18
|
-
* dropped (the transaction owns them); a per-call one is passed and the driver judges it.
|
|
12
|
+
* The bound travels as the server-side `maxTimeMS` on the command (driver 7.8 made the client-side
|
|
13
|
+
* `timeoutMS` / CSOT a no-op, CVE-2026-119179, so there is no per-op client budget any more). It
|
|
14
|
+
* reaches find, findOne, countDocuments, distinct, findOneAndUpdate, aggregate, insertMany,
|
|
15
|
+
* update/delete and bulkWrite. A single-document `create()` goes through Mongoose `save()`, which
|
|
16
|
+
* forwards no `maxTimeMS`, so it is NOT server-bounded. Writes also get `writeConcern`.
|
|
17
|
+
* {@link assertQueryDefaultsConfigured} checks the deployment bound at boot. Inside a transaction a DEFAULT read/write concern or read
|
|
18
|
+
* preference is dropped (the transaction owns them); a per-call one is passed and the driver judges it.
|
|
19
19
|
*/
|
|
20
20
|
/** On `globalThis`, for the reason `pagination/defaults.ts` gives: a duplicated install must share it. */
|
|
21
21
|
const POLICY_SLOT = Symbol.for("classytic.mongokit.queryDefaults");
|
|
@@ -60,31 +60,19 @@ function resetQueryDefaults() {
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
|
-
* Boot check (M7): throws unless the deployment sets a query `maxTimeMS
|
|
64
|
-
* is
|
|
63
|
+
* Boot check (M7): throws unless the deployment sets a query `maxTimeMS`. Returns what it verified.
|
|
64
|
+
* A client `timeoutMS` is not checked: the driver (7.8+) drops it from the client options and only
|
|
65
|
+
* logs a process warning, so there is nothing to read; it bounds nothing either way.
|
|
65
66
|
*/
|
|
66
|
-
function assertQueryDefaultsConfigured(
|
|
67
|
+
function assertQueryDefaultsConfigured() {
|
|
67
68
|
const maxTimeMS = policy().query.maxTimeMS;
|
|
68
69
|
if (maxTimeMS === void 0) throw createError(500, "[mongokit] no deployment query time bound: call configureQueryDefaults({ maxTimeMS }) at boot", {
|
|
69
70
|
code: QUERY_DEFAULTS_ERROR_CODES.NOT_CONFIGURED,
|
|
70
71
|
meta: { missing: "maxTimeMS" }
|
|
71
72
|
});
|
|
72
|
-
|
|
73
|
-
const timeoutMS = connection.getClient().options.timeoutMS;
|
|
74
|
-
if (!(typeof timeoutMS === "number" && timeoutMS > 0)) throw createError(500, "[mongokit] the connection has no CSOT timeoutMS: pass { timeoutMS } to mongoose.connect()", {
|
|
75
|
-
code: QUERY_DEFAULTS_ERROR_CODES.NOT_CONFIGURED,
|
|
76
|
-
meta: { missing: "timeoutMS" }
|
|
77
|
-
});
|
|
78
|
-
return {
|
|
79
|
-
maxTimeMS,
|
|
80
|
-
timeoutMS
|
|
81
|
-
};
|
|
73
|
+
return { maxTimeMS };
|
|
82
74
|
}
|
|
83
|
-
const QUERY_DEFAULTS_ERROR_CODES = {
|
|
84
|
-
NOT_CONFIGURED: "mongokit.query_defaults.not_configured",
|
|
85
|
-
/** A per-call bound inside a transaction that carries its own CSOT budget (the driver forbids both). */
|
|
86
|
-
TIMEOUT_IN_TRANSACTION: "mongokit.query_defaults.timeout_in_transaction"
|
|
87
|
-
};
|
|
75
|
+
const QUERY_DEFAULTS_ERROR_CODES = { NOT_CONFIGURED: "mongokit.query_defaults.not_configured" };
|
|
88
76
|
const TX_DEADLINE = Symbol.for("@classytic/mongokit/transaction-deadline");
|
|
89
77
|
/**
|
|
90
78
|
* Set (or clear) the transaction budget's deadline (`performance.now()` ms) on a session.
|
|
@@ -108,14 +96,6 @@ function inTransaction(session) {
|
|
|
108
96
|
const s = session;
|
|
109
97
|
return typeof s?.inTransaction === "function" && s.inTransaction();
|
|
110
98
|
}
|
|
111
|
-
/**
|
|
112
|
-
* A `withTransaction` running under a CSOT budget: the driver refuses any per-op `timeoutMS`
|
|
113
|
-
* there (mongodb lib/utils.js:451, `session.explicit && session.timeoutContext != null`).
|
|
114
|
-
*/
|
|
115
|
-
function csotTransaction(session) {
|
|
116
|
-
const s = session;
|
|
117
|
-
return inTransaction(session) && s?.explicit === true && s.timeoutContext != null;
|
|
118
|
-
}
|
|
119
99
|
/** Resolve the options one command runs with. `repo` is the repository's own defaults. */
|
|
120
100
|
function resolveQueryOptions(kind, perCall, repo = {}) {
|
|
121
101
|
const deployment = policy();
|
|
@@ -132,7 +112,6 @@ function resolveQueryOptions(kind, perCall, repo = {}) {
|
|
|
132
112
|
const budget = tx ? transactionRemaining(perCall.session) : void 0;
|
|
133
113
|
if (budget !== void 0 && budget <= 0) throw new mongoose.mongo.MongoOperationTimeoutError("Transaction budget exhausted before this operation");
|
|
134
114
|
if (kind !== "write") {
|
|
135
|
-
if (csotTransaction(perCall.session) && perCall.maxTimeMS !== void 0) throw createError(400, "[mongokit] a per-call maxTimeMS cannot be honoured inside a transaction with its own timeoutMS budget; bound the transaction instead", { code: QUERY_DEFAULTS_ERROR_CODES.TIMEOUT_IN_TRANSACTION });
|
|
136
115
|
const bound = tx ? perCall.maxTimeMS : perCall.maxTimeMS ?? (kind === "aggregate" ? repo.aggregate?.maxTimeMs ?? deployment.aggregate.maxTimeMs : void 0) ?? q.maxTimeMS;
|
|
137
116
|
const capped = budget === void 0 ? bound : Math.min(bound ?? Number.POSITIVE_INFINITY, budget);
|
|
138
117
|
if (capped !== void 0) out.maxTimeMS = capped;
|
|
@@ -174,34 +153,20 @@ function readPreferenceMode(value) {
|
|
|
174
153
|
}
|
|
175
154
|
/** Apply resolved options to a mongoose Query. */
|
|
176
155
|
function applyToQuery(query, o) {
|
|
177
|
-
if (o.maxTimeMS !== void 0)
|
|
178
|
-
const csot = { timeoutMS: o.maxTimeMS };
|
|
179
|
-
query.setOptions(csot);
|
|
180
|
-
}
|
|
156
|
+
if (o.maxTimeMS !== void 0) query.maxTimeMS(o.maxTimeMS);
|
|
181
157
|
if (o.comment !== void 0) query.setOptions({ comment: o.comment });
|
|
182
158
|
if (o.readPreference !== void 0) query.read(readPreferenceMode(o.readPreference));
|
|
183
159
|
if (o.readConcern !== void 0) query.readConcern(o.readConcern);
|
|
184
160
|
if (o.writeConcern !== void 0) query.setOptions({ writeConcern: o.writeConcern });
|
|
185
161
|
if (o.hint !== void 0) query.hint(o.hint);
|
|
186
162
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Make a find cursor's bound apply PER BATCH (CSOT `timeoutMode: 'iteration'`). Only when some
|
|
189
|
-
* `timeoutMS` exists (this op's, or the client's): the driver refuses a timeoutMode without one
|
|
190
|
-
* (mongodb lib/cursor/abstract_cursor.js:114). In iteration mode the driver enforces the budget
|
|
191
|
-
* client-side per batch and sends no wire maxTimeMS.
|
|
192
|
-
*/
|
|
193
|
-
function applyCursorTimeoutMode(query, o, connection) {
|
|
194
|
-
const clientTimeout = connection.getClient().options.timeoutMS;
|
|
195
|
-
if (o.maxTimeMS === void 0 && clientTimeout === void 0) return;
|
|
196
|
-
query.setOptions({ timeoutMode: "iteration" });
|
|
197
|
-
}
|
|
198
163
|
/** Apply resolved options to a mongoose Aggregate. */
|
|
199
164
|
function applyToAggregate(aggregation, o) {
|
|
200
|
-
if (o.maxTimeMS !== void 0) aggregation.option({
|
|
165
|
+
if (o.maxTimeMS !== void 0) aggregation.option({ maxTimeMS: o.maxTimeMS });
|
|
201
166
|
if (o.comment !== void 0) aggregation.option({ comment: o.comment });
|
|
202
167
|
if (o.readPreference !== void 0) aggregation.read(readPreferenceMode(o.readPreference));
|
|
203
168
|
if (o.readConcern !== void 0) aggregation.readConcern(o.readConcern);
|
|
204
169
|
if (o.allowDiskUse !== void 0) aggregation.allowDiskUse(o.allowDiskUse);
|
|
205
170
|
if (o.hint !== void 0) aggregation.hint(o.hint);
|
|
206
171
|
}
|
|
207
|
-
export {
|
|
172
|
+
export { configureAggregateDefaults as a, resetQueryDefaults as c, assertQueryDefaultsConfigured as i, resolveQueryOptions as l, applyToAggregate as n, configureQueryDefaults as o, applyToQuery as r, getQueryDefaults as s, QUERY_DEFAULTS_ERROR_CODES as t, setTransactionDeadline as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as Repository } from "../Repository-
|
|
1
|
+
import { r as Repository } from "../Repository-DJuRmBNx.mjs";
|
|
2
2
|
import { BulkUpsertResult } from "@classytic/repo-core/repository";
|
|
3
3
|
export declare const READ_MODEL_ERROR_CODES: {
|
|
4
4
|
readonly MERGE_IN_TRANSACTION: 'mongokit.read_model.merge_in_transaction';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as ObjectId, D as AnyDocument, F as SortSpec, M as ReadPreferenceType, N as SelectSpec, _ as QueryDefaults, b as WriteConcernSpec, i as CountStrategy, j as PopulateSpec, k as FilterQuery, p as AggregateDefaults, v as ReadConcernLevel } from "./pagination-
|
|
1
|
+
import { A as ObjectId, D as AnyDocument, F as SortSpec, M as ReadPreferenceType, N as SelectSpec, _ as QueryDefaults, b as WriteConcernSpec, i as CountStrategy, j as PopulateSpec, k as FilterQuery, p as AggregateDefaults, v as ReadConcernLevel } from "./pagination-BAM9cA4N.mjs";
|
|
2
2
|
import { r as DocField } from "./type-utils-CKvuewAL.mjs";
|
|
3
3
|
import { DistributionConfig, DistributionMissHandler, RepoCapabilities, RepositoryBase } from "@classytic/repo-core/repository";
|
|
4
4
|
import { Model, PipelineStage } from "mongoose";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { p as RepositoryContext } from "./repository-
|
|
1
|
+
import { p as RepositoryContext } from "./repository-B0aFVgP2.mjs";
|
|
2
2
|
/** Per-call retention purge request (`options.retentionPurge`). */
|
|
3
3
|
interface RetentionPurgeRequest {
|
|
4
4
|
/** Why the rows are removed (e.g. `'retention: 7 years'`). Required, non-blank. */
|
|
@@ -17,6 +17,8 @@ interface RetentionPurgeEvent {
|
|
|
17
17
|
filter: Record<string, unknown> | undefined;
|
|
18
18
|
/** Rows removed (`delete`: 1 or 0). */
|
|
19
19
|
deletedCount: number;
|
|
20
|
+
/** True when the delete is an `archiveByFilter` chunk the sink acknowledged first. */
|
|
21
|
+
archived: boolean;
|
|
20
22
|
/**
|
|
21
23
|
* The delete's session, when the call ran in one. Write the audit row with it
|
|
22
24
|
* (`{ session: event.session }`) so the delete and its audit commit or abort
|
|
@@ -31,5 +33,6 @@ declare const RETENTION_PURGE_ERROR_CODES: {
|
|
|
31
33
|
readonly REASON_REQUIRED: 'RETENTION_PURGE_REASON_REQUIRED';
|
|
32
34
|
readonly INVALID_ACTOR: 'RETENTION_PURGE_INVALID_ACTOR';
|
|
33
35
|
readonly HARD_ONLY: 'RETENTION_PURGE_HARD_ONLY';
|
|
36
|
+
readonly ARCHIVE_UNATTESTED: 'RETENTION_PURGE_ARCHIVE_UNATTESTED';
|
|
34
37
|
};
|
|
35
38
|
export { RetentionPurgeEvent as n, RetentionPurgeRequest as r, RETENTION_PURGE_ERROR_CODES as t };
|
package/dist/sync/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ClientSession, Connection, Model } from "mongoose";
|
|
2
|
-
import { ChangeEntry, ChangeLogAppendOptions, ChangeLogStore, ChangesSinceOptions, CommandStreamStore, CommandStreamTx } from "@classytic/repo-core/sync";
|
|
2
|
+
import { ChangeEntry, ChangeLogAppendOptions, ChangeLogStore, ChangesPage, ChangesSinceOptions, CommandStreamStore, CommandStreamTx } from "@classytic/repo-core/sync";
|
|
3
3
|
export interface ChangeLogModelOptions {
|
|
4
4
|
/** Entries collection. Default `sync_changes`; its counter lives in `<collection>_counter`. */
|
|
5
5
|
collection?: string;
|
|
@@ -43,12 +43,21 @@ export interface ChangeLogModels {
|
|
|
43
43
|
feed: string;
|
|
44
44
|
}
|
|
45
45
|
export declare function createChangeLogModels(connection: Connection, options?: ChangeLogModelOptions): ChangeLogModels;
|
|
46
|
+
/** {@link MongoChangeLogStore.snapshot}'s options: the reader's view, plus the bound after the first page. */
|
|
47
|
+
export interface ChangesSnapshotOptions extends ChangesSinceOptions {
|
|
48
|
+
/** The `upTo` the first page returned; omit it on the first page. */
|
|
49
|
+
readonly upTo?: string;
|
|
50
|
+
}
|
|
51
|
+
/** One snapshot page. `cursor` pages the snapshot; `upTo` is where `since()` resumes once `hasMore` is false. */
|
|
52
|
+
export interface ChangesSnapshotPage extends ChangesPage {
|
|
53
|
+
readonly upTo: string;
|
|
54
|
+
}
|
|
46
55
|
/** The mongo change feed: the `ChangeLogStore` contract plus superseded-entry compaction. */
|
|
47
56
|
export interface MongoChangeLogStore extends ChangeLogStore {
|
|
48
57
|
/**
|
|
49
|
-
* Delete every entry
|
|
50
|
-
*
|
|
51
|
-
*
|
|
58
|
+
* Delete every entry of a `(tenantId, scope, docId)` but the one a reader ends on (the last
|
|
59
|
+
* tombstone, or the highest-version upsert after it). Safe for any client cursor: entries carry
|
|
60
|
+
* whole documents, and a reader would have skipped every deleted one. Idempotent; run it on a schedule.
|
|
52
61
|
*/
|
|
53
62
|
compactSuperseded(options?: {
|
|
54
63
|
batchSize?: number;
|
|
@@ -57,9 +66,8 @@ export interface MongoChangeLogStore extends ChangeLogStore {
|
|
|
57
66
|
}>;
|
|
58
67
|
/**
|
|
59
68
|
* Retention with a horizon (the `ChangeLogStore.prune` contract). Deletes every entry older than
|
|
60
|
-
* `before` (`at < before`)
|
|
61
|
-
*
|
|
62
|
-
* document. Records a HORIZON (the highest deleted cursor, never lowered) per `(tenantId, scope)`
|
|
69
|
+
* `before` (`at < before`) except, per `(tenantId, scope, docId)`, the one a reader ends on (as
|
|
70
|
+
* `compactSuperseded` keeps), so a snapshot still sees every document. Records a HORIZON (the highest deleted cursor, never lowered) per `(tenantId, scope)`
|
|
63
71
|
* and feed-wide, BEFORE deleting, and returns the feed-wide one, `''` while nothing was ever
|
|
64
72
|
* pruned. `since(cursor, options)` with a cursor below the horizon of what that reader can see
|
|
65
73
|
* (its tenant, shared scopes and `scopes`; the feed-wide horizon when unfiltered; `''` included)
|
|
@@ -73,6 +81,14 @@ export interface MongoChangeLogStore extends ChangeLogStore {
|
|
|
73
81
|
prune(before: Date, options?: {
|
|
74
82
|
batchSize?: number;
|
|
75
83
|
}): Promise<string>;
|
|
84
|
+
/**
|
|
85
|
+
* The resync bootstrap for a reader `since()` expired: each document's latest entry at or below
|
|
86
|
+
* `upTo` (the reader's horizon, fixed by the first page), tombstones left out, in feed order. Then
|
|
87
|
+
* `since(upTo)` carries on, delivering every change above it, deletes included. Complete because
|
|
88
|
+
* `prune` and `compactSuperseded` never delete a document's latest entry. If that `since(upTo)`
|
|
89
|
+
* expires again, a prune raised the horizon in between: bootstrap again.
|
|
90
|
+
*/
|
|
91
|
+
snapshot(cursor: string, options?: ChangesSnapshotOptions): Promise<ChangesSnapshotPage>;
|
|
76
92
|
/**
|
|
77
93
|
* The compaction horizon cursor a reader with these options is held to (`''` while nothing it
|
|
78
94
|
* can see was pruned); feed-wide without options.
|
|
@@ -94,8 +110,8 @@ export interface MongoChangeLogStore extends ChangeLogStore {
|
|
|
94
110
|
* entry; `null` when the feed holds none. Reads only (it never runs the sequencer), so it is cheap on a hot
|
|
95
111
|
* path, e.g. a writer that needs the last recorded state of a record before it appends the next change.
|
|
96
112
|
* A document is `(tenantId, scope, docId)`: `tenantId` omitted or `null` reads the untenanted document.
|
|
97
|
-
* Pass `session` to see what the caller staged or appended in its own transaction.
|
|
98
|
-
*
|
|
113
|
+
* Pass `session` to see what the caller staged or appended in its own transaction. Pruning and
|
|
114
|
+
* compaction keep the entry a reader ends on, which may not be the last one recorded.
|
|
99
115
|
*/
|
|
100
116
|
latestOf(scope: string, docId: string, options?: {
|
|
101
117
|
tenantId?: string | null;
|