@classytic/mongokit 3.41.0 → 3.43.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 +28 -0
- package/dist/{Repository-DlhPbXlG.mjs → Repository-Dj6xqPxJ.mjs} +148 -1
- package/dist/{Repository-pnLw1rG5.d.mts → Repository-DnL4xk5w.d.mts} +10 -2
- package/dist/ai/index.d.mts +1 -1
- package/dist/better-auth/index.mjs +1 -1
- package/dist/{create-repository-BUx9vfG9.d.mts → create-repository-CJtVdwig.d.mts} +4 -4
- package/dist/{create-repository-Bg0H5rte.mjs → create-repository-UjwPWR1z.mjs} +2 -2
- package/dist/derive-DRBiegRH.mjs +375 -0
- package/dist/index-C0AjVqX3.d.mts +169 -0
- package/dist/index.d.mts +37 -8
- package/dist/index.mjs +53 -5
- package/dist/{multi-tenant.plugin-a3UhQARj.d.mts → multi-tenant.plugin-B_q9NUHc.d.mts} +1 -1
- package/dist/outbox/index.d.mts +1 -1
- package/dist/outbox/index.mjs +1 -1
- package/dist/{plugin-options-CRhIvSzx.d.mts → plugin-options-Cirmb4Kp.d.mts} +1 -1
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +50 -18
- package/dist/read-model/index.d.mts +1 -1
- package/dist/{repository-DNHfjAZX.d.mts → repository-MqAP409e.d.mts} +14 -3
- package/dist/search/index.d.mts +2 -0
- package/dist/search/index.mjs +2 -0
- package/dist/sync/index.d.mts +22 -1
- package/dist/sync/index.mjs +236 -61
- package/dist/testkit/index.d.mts +2 -2
- package/dist/testkit/index.mjs +1 -1
- package/dist/{timestamp.plugin-DvZlnKEc.mjs → timestamp.plugin-DpOWavVI.mjs} +1 -1
- package/dist/{to-plain-CjgEInWV.d.mts → to-plain-o5tUY2nV.d.mts} +2 -2
- package/dist/utils/index.d.mts +1 -1
- package/dist/{validation-chain.plugin-CTcNJCmV.d.mts → validation-chain.plugin-BAeC5eVT.d.mts} +12 -3
- package/dist/{validation-chain.plugin-D1WsGCYr.mjs → validation-chain.plugin-DRApTmkN.mjs} +3 -2
- package/package.json +6 -2
package/dist/sync/index.mjs
CHANGED
|
@@ -1,77 +1,133 @@
|
|
|
1
1
|
import { o as withTransaction } from "../transaction-DmiB4k2P.mjs";
|
|
2
|
-
import { Schema } from "mongoose";
|
|
2
|
+
import { Schema, Types } from "mongoose";
|
|
3
3
|
//#region src/sync/index.ts
|
|
4
4
|
function createChangeLogModels(connection, options = {}) {
|
|
5
|
-
const { collection = "sync_changes", modelName = "SyncChange" } = options;
|
|
5
|
+
const { collection = "sync_changes", modelName = "SyncChange", sequencing = "in-transaction" } = options;
|
|
6
6
|
const entriesName = modelName;
|
|
7
7
|
const counterName = `${modelName}Counter`;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
scope: {
|
|
16
|
-
type: String,
|
|
17
|
-
required: true
|
|
18
|
-
},
|
|
19
|
-
docId: {
|
|
20
|
-
type: String,
|
|
21
|
-
required: true
|
|
22
|
-
},
|
|
23
|
-
op: {
|
|
24
|
-
type: String,
|
|
25
|
-
enum: ["upsert", "delete"],
|
|
26
|
-
required: true
|
|
27
|
-
},
|
|
28
|
-
version: {
|
|
29
|
-
type: Number,
|
|
30
|
-
required: true
|
|
31
|
-
},
|
|
32
|
-
doc: { type: Schema.Types.Mixed },
|
|
33
|
-
tenantId: { type: String },
|
|
34
|
-
at: {
|
|
35
|
-
type: Date,
|
|
36
|
-
required: true
|
|
37
|
-
}
|
|
38
|
-
}, {
|
|
39
|
-
collection,
|
|
40
|
-
versionKey: false,
|
|
41
|
-
minimize: false
|
|
42
|
-
});
|
|
43
|
-
schema.index({ seq: 1 }, {
|
|
44
|
-
unique: true,
|
|
45
|
-
name: "feed_order"
|
|
46
|
-
});
|
|
47
|
-
schema.index({
|
|
48
|
-
tenantId: 1,
|
|
49
|
-
scope: 1,
|
|
50
|
-
seq: 1
|
|
51
|
-
}, { name: "tenant_scope_feed" });
|
|
52
|
-
schema.index({
|
|
53
|
-
scope: 1,
|
|
54
|
-
docId: 1,
|
|
55
|
-
seq: 1
|
|
56
|
-
}, { name: "doc_versions" });
|
|
57
|
-
return schema;
|
|
58
|
-
})()),
|
|
59
|
-
counter: connection.models[counterName] ?? connection.model(counterName, new Schema({
|
|
60
|
-
_id: {
|
|
8
|
+
const entries = connection.models[entriesName] ?? connection.model(entriesName, (() => {
|
|
9
|
+
const schema = new Schema({
|
|
10
|
+
seq: {
|
|
11
|
+
type: Number,
|
|
12
|
+
required: true
|
|
13
|
+
},
|
|
14
|
+
scope: {
|
|
61
15
|
type: String,
|
|
62
16
|
required: true
|
|
63
17
|
},
|
|
64
|
-
|
|
18
|
+
docId: {
|
|
19
|
+
type: String,
|
|
20
|
+
required: true
|
|
21
|
+
},
|
|
22
|
+
op: {
|
|
23
|
+
type: String,
|
|
24
|
+
enum: ["upsert", "delete"],
|
|
25
|
+
required: true
|
|
26
|
+
},
|
|
27
|
+
version: {
|
|
65
28
|
type: Number,
|
|
66
29
|
required: true
|
|
67
|
-
}
|
|
30
|
+
},
|
|
31
|
+
doc: { type: Schema.Types.Mixed },
|
|
32
|
+
tenantId: { type: String },
|
|
33
|
+
at: {
|
|
34
|
+
type: Date,
|
|
35
|
+
required: true
|
|
36
|
+
},
|
|
37
|
+
/** The staged row this entry was numbered from (deferred sequencing) — the sequencer's idempotency key. */
|
|
38
|
+
pendingId: { type: String }
|
|
68
39
|
}, {
|
|
69
|
-
collection
|
|
70
|
-
versionKey: false
|
|
71
|
-
|
|
40
|
+
collection,
|
|
41
|
+
versionKey: false,
|
|
42
|
+
minimize: false
|
|
43
|
+
});
|
|
44
|
+
schema.index({ seq: 1 }, {
|
|
45
|
+
unique: true,
|
|
46
|
+
name: "feed_order"
|
|
47
|
+
});
|
|
48
|
+
schema.index({ pendingId: 1 }, {
|
|
49
|
+
unique: true,
|
|
50
|
+
name: "sequenced_from",
|
|
51
|
+
partialFilterExpression: { pendingId: { $gte: "" } }
|
|
52
|
+
});
|
|
53
|
+
schema.index({
|
|
54
|
+
tenantId: 1,
|
|
55
|
+
scope: 1,
|
|
56
|
+
seq: 1
|
|
57
|
+
}, { name: "tenant_scope_feed" });
|
|
58
|
+
schema.index({
|
|
59
|
+
scope: 1,
|
|
60
|
+
docId: 1,
|
|
61
|
+
seq: 1
|
|
62
|
+
}, { name: "doc_versions" });
|
|
63
|
+
return schema;
|
|
64
|
+
})());
|
|
65
|
+
const counter = connection.models[counterName] ?? connection.model(counterName, new Schema({
|
|
66
|
+
_id: {
|
|
67
|
+
type: String,
|
|
68
|
+
required: true
|
|
69
|
+
},
|
|
70
|
+
seq: {
|
|
71
|
+
type: Number,
|
|
72
|
+
required: true
|
|
73
|
+
},
|
|
74
|
+
/** The deferred sequencer's lease. */
|
|
75
|
+
lockUntil: { type: Date },
|
|
76
|
+
lockBy: { type: String }
|
|
77
|
+
}, {
|
|
78
|
+
collection: `${collection}_counter`,
|
|
79
|
+
versionKey: false
|
|
80
|
+
}));
|
|
81
|
+
const pendingName = `${modelName}Pending`;
|
|
82
|
+
const pending = sequencing === "deferred" ? connection.models[pendingName] ?? connection.model(pendingName, new Schema({
|
|
83
|
+
scope: {
|
|
84
|
+
type: String,
|
|
85
|
+
required: true
|
|
86
|
+
},
|
|
87
|
+
docId: {
|
|
88
|
+
type: String,
|
|
89
|
+
required: true
|
|
90
|
+
},
|
|
91
|
+
op: {
|
|
92
|
+
type: String,
|
|
93
|
+
enum: ["upsert", "delete"],
|
|
94
|
+
required: true
|
|
95
|
+
},
|
|
96
|
+
version: {
|
|
97
|
+
type: Number,
|
|
98
|
+
required: true
|
|
99
|
+
},
|
|
100
|
+
doc: { type: Schema.Types.Mixed },
|
|
101
|
+
tenantId: { type: String },
|
|
102
|
+
at: {
|
|
103
|
+
type: Date,
|
|
104
|
+
required: true
|
|
105
|
+
}
|
|
106
|
+
}, {
|
|
107
|
+
collection: `${collection}_pending`,
|
|
108
|
+
versionKey: false,
|
|
109
|
+
minimize: false
|
|
110
|
+
})) : void 0;
|
|
111
|
+
return {
|
|
112
|
+
entries,
|
|
113
|
+
counter,
|
|
114
|
+
...pending ? { pending } : {},
|
|
115
|
+
sequencing,
|
|
72
116
|
feed: collection
|
|
73
117
|
};
|
|
74
118
|
}
|
|
119
|
+
/** A change as staged under deferred sequencing — the feed row without its `seq`. */
|
|
120
|
+
function stagedRow(entry, at) {
|
|
121
|
+
return {
|
|
122
|
+
scope: entry.scope,
|
|
123
|
+
docId: entry.docId,
|
|
124
|
+
op: entry.op,
|
|
125
|
+
version: entry.version,
|
|
126
|
+
...entry.op === "upsert" && entry.doc !== void 0 ? { doc: entry.doc } : {},
|
|
127
|
+
...entry.tenantId !== void 0 ? { tenantId: entry.tenantId } : {},
|
|
128
|
+
at
|
|
129
|
+
};
|
|
130
|
+
}
|
|
75
131
|
/** Fixed-width, so the opaque cursor also sorts as text. */
|
|
76
132
|
const toCursor = (seq) => String(seq).padStart(16, "0");
|
|
77
133
|
const fromCursor = (cursor) => {
|
|
@@ -81,8 +137,96 @@ const fromCursor = (cursor) => {
|
|
|
81
137
|
return seq;
|
|
82
138
|
};
|
|
83
139
|
const DEFAULT_LIMIT = 500;
|
|
140
|
+
/** How long one sequencer holds the lease — far above one batch, so a live holder never loses it mid-batch. */
|
|
141
|
+
const SEQUENCER_LEASE_MS = 3e4;
|
|
142
|
+
const SEQUENCER_BATCH = 500;
|
|
84
143
|
function createChangeLogStore(models) {
|
|
85
|
-
const { entries, counter, feed } = models;
|
|
144
|
+
const { entries, counter, feed, pending } = models;
|
|
145
|
+
const deferred = models.sequencing === "deferred" && pending !== void 0;
|
|
146
|
+
/**
|
|
147
|
+
* One pass under the lease: committed staged rows → the feed, in staging order, numbered above everything.
|
|
148
|
+
* Nothing staged costs ONE read. A crash mid-pass is converged by the next one: an entry already in the feed is
|
|
149
|
+
* recognised by its unique `pendingId`, and a stale counter is caught by the unique `seq` index.
|
|
150
|
+
*/
|
|
151
|
+
const sequencePending = async () => {
|
|
152
|
+
if (!deferred || !pending) return 0;
|
|
153
|
+
if (!await pending.exists({}).exec()) return 0;
|
|
154
|
+
const token = new Types.ObjectId().toString();
|
|
155
|
+
const unlocked = {
|
|
156
|
+
_id: feed,
|
|
157
|
+
$or: [
|
|
158
|
+
{ lockUntil: { $exists: false } },
|
|
159
|
+
{ lockUntil: null },
|
|
160
|
+
{ lockUntil: { $lt: /* @__PURE__ */ new Date() } }
|
|
161
|
+
]
|
|
162
|
+
};
|
|
163
|
+
const takeLease = () => counter.findOneAndUpdate(unlocked, { $set: {
|
|
164
|
+
lockUntil: new Date(Date.now() + SEQUENCER_LEASE_MS),
|
|
165
|
+
lockBy: token
|
|
166
|
+
} }, {
|
|
167
|
+
returnDocument: "after",
|
|
168
|
+
lean: true
|
|
169
|
+
}).exec();
|
|
170
|
+
let lease = await takeLease();
|
|
171
|
+
if (!lease) {
|
|
172
|
+
if (await counter.exists({ _id: feed }).exec()) return null;
|
|
173
|
+
await counter.create([{
|
|
174
|
+
_id: feed,
|
|
175
|
+
seq: 0
|
|
176
|
+
}]).catch((err) => {
|
|
177
|
+
if (err.code !== 11e3) throw err;
|
|
178
|
+
});
|
|
179
|
+
lease = await takeLease();
|
|
180
|
+
if (!lease) return null;
|
|
181
|
+
}
|
|
182
|
+
let seq = lease.seq ?? 0;
|
|
183
|
+
let numbered = 0;
|
|
184
|
+
try {
|
|
185
|
+
for (;;) {
|
|
186
|
+
const rows = await pending.find({}).sort({ _id: 1 }).limit(SEQUENCER_BATCH).lean().exec();
|
|
187
|
+
if (rows.length === 0) break;
|
|
188
|
+
const build = (from, list) => list.map((r, i) => {
|
|
189
|
+
const { _id, ...rest } = r;
|
|
190
|
+
return {
|
|
191
|
+
...rest,
|
|
192
|
+
seq: from + i + 1,
|
|
193
|
+
pendingId: String(_id)
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
try {
|
|
197
|
+
await entries.insertMany(build(seq, rows), { ordered: true });
|
|
198
|
+
seq += rows.length;
|
|
199
|
+
numbered += rows.length;
|
|
200
|
+
} catch (err) {
|
|
201
|
+
if (err.code !== 11e3) throw err;
|
|
202
|
+
const placed = new Set((await entries.find({ pendingId: { $in: rows.map((r) => String(r._id)) } }).select({ pendingId: 1 }).lean().exec()).map((e) => e.pendingId));
|
|
203
|
+
const fresh = rows.filter((r) => !placed.has(String(r._id)));
|
|
204
|
+
const top = await entries.findOne({}).sort({ seq: -1 }).select({ seq: 1 }).lean().exec();
|
|
205
|
+
seq = Math.max(seq, top?.seq ?? 0);
|
|
206
|
+
if (fresh.length > 0) {
|
|
207
|
+
await entries.insertMany(build(seq, fresh), { ordered: true });
|
|
208
|
+
seq += fresh.length;
|
|
209
|
+
numbered += fresh.length;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
await counter.updateOne({
|
|
213
|
+
_id: feed,
|
|
214
|
+
lockBy: token
|
|
215
|
+
}, { $max: { seq } }).exec();
|
|
216
|
+
await pending.deleteMany({ _id: { $in: rows.map((r) => r._id) } }).exec();
|
|
217
|
+
if (rows.length < SEQUENCER_BATCH) break;
|
|
218
|
+
}
|
|
219
|
+
} finally {
|
|
220
|
+
await counter.updateOne({
|
|
221
|
+
_id: feed,
|
|
222
|
+
lockBy: token
|
|
223
|
+
}, { $set: {
|
|
224
|
+
lockUntil: null,
|
|
225
|
+
lockBy: null
|
|
226
|
+
} }).exec();
|
|
227
|
+
}
|
|
228
|
+
return numbered;
|
|
229
|
+
};
|
|
86
230
|
const sessionOf = (options) => options?.session ? { session: options.session } : {};
|
|
87
231
|
const filterOf = (after, options = {}) => {
|
|
88
232
|
const { tenantId, scopes, sharedScopes } = options;
|
|
@@ -104,8 +248,37 @@ function createChangeLogStore(models) {
|
|
|
104
248
|
cursor: toCursor(row.seq)
|
|
105
249
|
});
|
|
106
250
|
return {
|
|
251
|
+
sequencePending,
|
|
252
|
+
async stage(entry, options) {
|
|
253
|
+
if (!deferred || !pending) {
|
|
254
|
+
await this.append(entry, options);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
await pending.create([stagedRow(entry, /* @__PURE__ */ new Date())], sessionOf(options));
|
|
258
|
+
},
|
|
107
259
|
async append(entry, options) {
|
|
108
260
|
const session = sessionOf(options);
|
|
261
|
+
if (deferred && pending) {
|
|
262
|
+
const at = /* @__PURE__ */ new Date();
|
|
263
|
+
const [staged] = await pending.create([stagedRow(entry, at)], session);
|
|
264
|
+
if (options?.session) return {
|
|
265
|
+
...entry,
|
|
266
|
+
at,
|
|
267
|
+
cursor: ""
|
|
268
|
+
};
|
|
269
|
+
const stagedId = String(staged?._id);
|
|
270
|
+
for (let attempt = 0; attempt < 50; attempt++) {
|
|
271
|
+
await sequencePending();
|
|
272
|
+
const at2 = await entries.findOne({ pendingId: stagedId }).select({ seq: 1 }).lean().exec();
|
|
273
|
+
if (typeof at2?.seq === "number") return {
|
|
274
|
+
...entry,
|
|
275
|
+
at,
|
|
276
|
+
cursor: toCursor(at2.seq)
|
|
277
|
+
};
|
|
278
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
279
|
+
}
|
|
280
|
+
throw new Error(`[mongokit:sync] staged entry ${stagedId} was not sequenced — a sequencer lease is stuck`);
|
|
281
|
+
}
|
|
109
282
|
const seq = (await counter.findOneAndUpdate({ _id: feed }, { $inc: { seq: 1 } }, {
|
|
110
283
|
upsert: true,
|
|
111
284
|
returnDocument: "after",
|
|
@@ -130,6 +303,7 @@ function createChangeLogStore(models) {
|
|
|
130
303
|
};
|
|
131
304
|
},
|
|
132
305
|
async since(cursor, options = {}) {
|
|
306
|
+
if (deferred) await sequencePending();
|
|
133
307
|
const limit = options.limit ?? DEFAULT_LIMIT;
|
|
134
308
|
const rows = await entries.find(filterOf(fromCursor(cursor), options)).sort({ seq: 1 }).limit(limit + 1).lean().exec();
|
|
135
309
|
const page = rows.slice(0, limit).map(toEntry);
|
|
@@ -141,6 +315,7 @@ function createChangeLogStore(models) {
|
|
|
141
315
|
};
|
|
142
316
|
},
|
|
143
317
|
async latestCursor(options = {}) {
|
|
318
|
+
if (deferred) await sequencePending();
|
|
144
319
|
const row = await entries.findOne(filterOf(0, options)).sort({ seq: -1 }).select({ seq: 1 }).lean().exec();
|
|
145
320
|
return row?.seq ? toCursor(row.seq) : "";
|
|
146
321
|
},
|
package/dist/testkit/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as Repository } from "../Repository-
|
|
2
|
-
import { n as CreateRepositoryConfig } from "../create-repository-
|
|
1
|
+
import { r as Repository } from "../Repository-DnL4xk5w.mjs";
|
|
2
|
+
import { n as CreateRepositoryConfig } from "../create-repository-CJtVdwig.mjs";
|
|
3
3
|
import { Connection, Model, Schema } from "mongoose";
|
|
4
4
|
import { MongoMemoryReplSet, MongoMemoryServer } from "mongodb-memory-server";
|
|
5
5
|
//#region src/testkit/query-plan.d.ts
|
package/dist/testkit/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createRepository } from "../create-repository-
|
|
1
|
+
import { t as createRepository } from "../create-repository-UjwPWR1z.mjs";
|
|
2
2
|
import { createConnection } from "mongoose";
|
|
3
3
|
//#region src/testkit/query-plan.ts
|
|
4
4
|
const PLANNABLE = /* @__PURE__ */ new Set([
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as ALL_OPERATIONS, s as OP_REGISTRY, t as HOOK_PRIORITY } from "./Repository-Dj6xqPxJ.mjs";
|
|
2
2
|
import { n as warn } from "./logger-K7dPmu2U.mjs";
|
|
3
3
|
import { n as declareCollectionScope } from "./join-scope-DSAznE8E.mjs";
|
|
4
4
|
import { throwIfAborted, withRetry } from "@classytic/repo-core/repository";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as FieldPreset } from "./plugin-options-
|
|
1
|
+
import { y as UserContext } from "./repository-MqAP409e.mjs";
|
|
2
|
+
import { r as FieldPreset } from "./plugin-options-Cirmb4Kp.mjs";
|
|
3
3
|
import mongoose, { Schema } from "mongoose";
|
|
4
4
|
import { CacheAdapter } from "@classytic/repo-core/cache";
|
|
5
5
|
import { HttpError } from "@classytic/repo-core/errors";
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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-o5tUY2nV.mjs";
|
|
2
2
|
import { ClientSession, Model } from "mongoose";
|
|
3
3
|
//#region src/utils/id-chunks.d.ts
|
|
4
4
|
/**
|
package/dist/{validation-chain.plugin-CTcNJCmV.d.mts → validation-chain.plugin-BAeC5eVT.d.mts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { A as ObjectId, F as SortSpec, N as SelectSpec, j as PopulateSpec } from "./pagination-D6psses0.mjs";
|
|
2
|
-
import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-
|
|
3
|
-
import { c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, o as SoftDeleteOptions, r as FieldPreset, t as CascadeOptions } from "./plugin-options-
|
|
2
|
+
import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-MqAP409e.mjs";
|
|
3
|
+
import { c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, o as SoftDeleteOptions, r as FieldPreset, t as CascadeOptions } from "./plugin-options-Cirmb4Kp.mjs";
|
|
4
4
|
import { BulkWriteResult } from "@classytic/repo-core/repository";
|
|
5
5
|
import { OffsetPaginationResult } from "@classytic/repo-core/pagination";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -719,6 +719,15 @@ interface ObservabilityOptions {
|
|
|
719
719
|
}
|
|
720
720
|
declare function observabilityPlugin(options: ObservabilityOptions): Plugin;
|
|
721
721
|
//#endregion
|
|
722
|
+
//#region src/plugins/search-keys.plugin.d.ts
|
|
723
|
+
interface SearchKeysPluginOptions {
|
|
724
|
+
/** Source fields (dotted paths allowed; string, number, or arrays of them). */
|
|
725
|
+
fields: readonly string[];
|
|
726
|
+
/** Field that stores the keys. Default `'_searchKeys'`. */
|
|
727
|
+
keysField?: string;
|
|
728
|
+
}
|
|
729
|
+
declare function searchKeysPlugin(options: SearchKeysPluginOptions): Plugin;
|
|
730
|
+
//#endregion
|
|
722
731
|
//#region src/plugins/soft-delete.plugin.d.ts
|
|
723
732
|
/**
|
|
724
733
|
* Soft delete plugin
|
|
@@ -964,4 +973,4 @@ declare function immutableField(field: string): ValidatorDefinition;
|
|
|
964
973
|
*/
|
|
965
974
|
declare function uniqueField(field: string, errorMessage?: string): ValidatorDefinition;
|
|
966
975
|
//#endregion
|
|
967
|
-
export {
|
|
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 };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as collectIds, r as idChunks, t as DEFAULT_ID_CHUNK } from "./id-chunks-BmAwsqNk.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { a as ALL_OPERATIONS, s as OP_REGISTRY } from "./Repository-Dj6xqPxJ.mjs";
|
|
3
3
|
import { w as upsert } from "./update-WgeAUJ_I.mjs";
|
|
4
4
|
import { n as warn } from "./logger-K7dPmu2U.mjs";
|
|
5
5
|
import { t as createError } from "./error-BuByZwKU.mjs";
|
|
6
|
-
import { c as tenantContextKeysOf, o as forwardScope } from "./timestamp.plugin-
|
|
6
|
+
import { c as tenantContextKeysOf, o as forwardScope } from "./timestamp.plugin-DpOWavVI.mjs";
|
|
7
7
|
import { r as getFieldsForUser } from "./field-selection-FSQFLpsU.mjs";
|
|
8
8
|
import mongoose from "mongoose";
|
|
9
9
|
import { HOOK_PRIORITY } from "@classytic/repo-core/hooks";
|
|
@@ -1223,6 +1223,7 @@ const MONGOKIT_PLUGIN_NAMES = {
|
|
|
1223
1223
|
mongoOperations: "mongo-operations",
|
|
1224
1224
|
multiTenant: "multi-tenant",
|
|
1225
1225
|
observability: "observability",
|
|
1226
|
+
searchKeys: "search-keys",
|
|
1226
1227
|
softDelete: "softDelete",
|
|
1227
1228
|
subdocument: "subdocument",
|
|
1228
1229
|
timestamp: "timestamp",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/mongokit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.43.0",
|
|
4
4
|
"description": "Production-grade MongoDB repositories - smart pagination, events, and plugins. Built on @classytic/repo-core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -95,6 +95,10 @@
|
|
|
95
95
|
"./kernel-conformance": {
|
|
96
96
|
"types": "./dist/kernel-conformance/index.d.mts",
|
|
97
97
|
"default": "./dist/kernel-conformance/index.mjs"
|
|
98
|
+
},
|
|
99
|
+
"./search": {
|
|
100
|
+
"types": "./dist/search/index.d.mts",
|
|
101
|
+
"default": "./dist/search/index.mjs"
|
|
98
102
|
}
|
|
99
103
|
},
|
|
100
104
|
"files": [
|
|
@@ -199,7 +203,7 @@
|
|
|
199
203
|
"@better-auth/mongo-adapter": "^1.6.29",
|
|
200
204
|
"@biomejs/biome": "^2.5.8",
|
|
201
205
|
"@classytic/dev-tools": "^0.2.0",
|
|
202
|
-
"@classytic/repo-core": "^0.31.
|
|
206
|
+
"@classytic/repo-core": "^0.31.1",
|
|
203
207
|
"@types/node": "^26.2.0",
|
|
204
208
|
"@vitest/coverage-v8": "^4.1.10",
|
|
205
209
|
"ajv": "^8.20.0",
|