@classytic/mongokit 3.30.0 → 3.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PaginationEngine-CczbvCAq.mjs → PaginationEngine-CuONvwCM.mjs} +21 -1
- package/dist/{Repository-BXHkUtLk.d.mts → Repository-BAzymuOz.d.mts} +1 -1
- package/dist/{Repository-X7U2d0kU.mjs → Repository-Cx7BwvDA.mjs} +57 -15
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.mjs +1 -1
- package/dist/better-auth/index.mjs +1 -1
- package/dist/{create-repository-DYe5YEie.mjs → create-repository-EWKzpsyM.mjs} +2 -2
- package/dist/{create-repository-CvD4wzuN.d.mts → create-repository-mEdfH9sz.d.mts} +1 -1
- package/dist/{index-DceInCTX.d.mts → index-Beyr1r4d.d.mts} +1 -1
- package/dist/index.d.mts +32 -4
- package/dist/index.mjs +43 -9
- package/dist/{operations-C8IcCHF9.d.mts → operations-CuzX9m2Z.d.mts} +42 -3
- package/dist/outbox/index.d.mts +1 -1
- package/dist/outbox/index.mjs +1 -1
- package/dist/pagination/PaginationEngine.mjs +1 -1
- package/dist/plugins/index.mjs +2 -2
- package/dist/testkit/index.d.mts +2 -2
- package/dist/testkit/index.mjs +1 -1
- package/dist/{timestamp.plugin-ChFRcLRJ.mjs → timestamp.plugin-CX_kw6TN.mjs} +1 -1
- package/dist/{update-DHdXdOk_.mjs → update-w5i-pa_c.mjs} +48 -5
- package/dist/{validation-chain.plugin-BxTl_dYR.mjs → validation-chain.plugin-DbcBOWi3.mjs} +2 -2
- package/package.json +193 -193
|
@@ -636,7 +636,27 @@ var PaginationEngine = class {
|
|
|
636
636
|
hasNext = data.length > sanitizedLimit;
|
|
637
637
|
if (hasNext) data.pop();
|
|
638
638
|
} else hasNext = sanitizedPage < totalPages;
|
|
639
|
-
|
|
639
|
+
/**
|
|
640
|
+
* A CLAMPED limit is reported, not swallowed.
|
|
641
|
+
*
|
|
642
|
+
* `validateLimit` caps silently by design — an over-ask is benign and rejecting it
|
|
643
|
+
* would be worse (that contradiction cost a day: the querystring schema's `maximum`
|
|
644
|
+
* made the parser's documented clamp unreachable, so `?limit=200` 400'd and two UI
|
|
645
|
+
* callers rendered the failure as an empty list).
|
|
646
|
+
*
|
|
647
|
+
* But clamping quietly has its own cost. A caller asking for 1000 and receiving 100
|
|
648
|
+
* gets an arbitrary slice with no signal — which is exactly how a bank-account
|
|
649
|
+
* picker rendered "No accounts found" against 696 accounts, because the rows it
|
|
650
|
+
* wanted were outside the first page. `limit` in the response already carries the
|
|
651
|
+
* effective value; nobody compares it. A warning is the channel that is actually
|
|
652
|
+
* read.
|
|
653
|
+
*
|
|
654
|
+
* Deep-pagination takes precedence when both apply: it is the more actionable of
|
|
655
|
+
* the two, and stacking warnings turns a signal into noise.
|
|
656
|
+
*/
|
|
657
|
+
const requestedLimit = Number(limit);
|
|
658
|
+
const wasClamped = Number.isFinite(requestedLimit) && requestedLimit > sanitizedLimit;
|
|
659
|
+
const warning = shouldWarnDeepPagination(sanitizedPage, this.config.deepPageThreshold) ? `Deep pagination (page ${sanitizedPage}). Consider getAll({ after, sort, limit }) for better performance.` : wasClamped ? `Requested limit ${Math.floor(requestedLimit)} exceeds this repository's cap; returning ${sanitizedLimit}. Filter server-side or sort deterministically — the returned page is otherwise an arbitrary slice.` : void 0;
|
|
640
660
|
return {
|
|
641
661
|
method: "offset",
|
|
642
662
|
data,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as WithTransactionOptions, a as DeleteManyResult, f as OperationOptions, g as UpdateOptions, h as UpdateManyResult, i as CreateOptions, l as LookupPopulateOptions, m as SessionOptions, o as DeleteResult, p as ReadOptions, r as CacheableOptions, s as FindOneAndUpdateOptions, t as AggregateOptions, u as LookupPopulateResult, v as LookupBuilder, y as LookupOptions } from "./operations-
|
|
1
|
+
import { _ as WithTransactionOptions, a as DeleteManyResult, f as OperationOptions, g as UpdateOptions, h as UpdateManyResult, i as CreateOptions, l as LookupPopulateOptions, m as SessionOptions, o as DeleteResult, p as ReadOptions, r as CacheableOptions, s as FindOneAndUpdateOptions, t as AggregateOptions, u as LookupPopulateResult, v as LookupBuilder, y as LookupOptions } from "./operations-CuzX9m2Z.mjs";
|
|
2
2
|
import { a as PopulateSpec, i as ObjectId, l as SortSpec$1, o as ReadPreferenceType, s as SelectSpec } from "./core-62oo3N1C.mjs";
|
|
3
3
|
import { c as PaginationConfig, r as CollationOptions, t as AggregatePaginationOptions } from "./pagination-jSUdrACK.mjs";
|
|
4
4
|
import { _ as RepositoryOptions, d as PluginType, f as PrioritizedHook, o as Middleware, p as RepositoryContext } from "./repository-Q16ErTu8.mjs";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { i as isValidIdForType, t as getSchemaIdType } from "./id-resolution-BqDrk0S2.mjs";
|
|
2
|
-
import { a as count, b as LookupBuilder, c as getByQuery, d as deleteById, f as deleteByQuery, h as createMany, l as getOrCreate, m as create, n as update, o as exists, r as updateByQuery, s as getById, t as findOneAndUpdate, x as compileFilterToMongo, y as distinct } from "./update-
|
|
2
|
+
import { a as count, b as LookupBuilder, c as getByQuery, d as deleteById, f as deleteByQuery, h as createMany, l as getOrCreate, m as create, n as update, o as exists, r as updateByQuery, s as getById, t as findOneAndUpdate, x as compileFilterToMongo, y as distinct } from "./update-w5i-pa_c.mjs";
|
|
3
3
|
import { n as warn } from "./logger-K7dPmu2U.mjs";
|
|
4
4
|
import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-BuByZwKU.mjs";
|
|
5
|
-
import { t as PaginationEngine } from "./PaginationEngine-
|
|
5
|
+
import { t as PaginationEngine } from "./PaginationEngine-CuONvwCM.mjs";
|
|
6
6
|
import { hasNearOperator, rewriteNearForCount } from "./query/primitives/geo.mjs";
|
|
7
7
|
import { RepositoryBase, runChunkedArchive, runChunkedPurge, throwIfAborted, validatePluginOrder, withRetry } from "@classytic/repo-core/repository";
|
|
8
8
|
import mongoose from "mongoose";
|
|
@@ -159,6 +159,7 @@ const MONGOKIT_CAPABILITIES = Object.freeze({
|
|
|
159
159
|
percentile: true,
|
|
160
160
|
stddev: true,
|
|
161
161
|
topN: true,
|
|
162
|
+
dateBucketTimezone: true,
|
|
162
163
|
customDateBuckets: true,
|
|
163
164
|
dateBucketSubMinute: true,
|
|
164
165
|
cache: true
|
|
@@ -173,6 +174,7 @@ const MONGOKIT_CAPABILITIES = Object.freeze({
|
|
|
173
174
|
changeStreams: true,
|
|
174
175
|
lean: true,
|
|
175
176
|
lookupPopulate: true,
|
|
177
|
+
lookupCoerce: true,
|
|
176
178
|
streaming: true
|
|
177
179
|
});
|
|
178
180
|
/**
|
|
@@ -666,8 +668,48 @@ function validateMeasures$1(measures) {
|
|
|
666
668
|
* 2. Inside `$project` to flatten `_id.<alias>` into a top-level
|
|
667
669
|
* column on the output row — matches the cross-kit shape.
|
|
668
670
|
*/
|
|
671
|
+
/**
|
|
672
|
+
* Reject an unknown IANA zone HERE, not at the server.
|
|
673
|
+
*
|
|
674
|
+
* `@classytic/primitives` owns the canonical `isValidTimeZone`, but this is a
|
|
675
|
+
* storage kit and must not take a domain dependency for one validator — so it
|
|
676
|
+
* mirrors the primitive's implementation exactly: construct an `Intl` formatter
|
|
677
|
+
* for the zone and treat the `RangeError` as the answer. ICU is the same source
|
|
678
|
+
* of truth either way, so the two cannot disagree about which zones exist.
|
|
679
|
+
*
|
|
680
|
+
* Without this, a typo (`Asia/Dahka`) travels all the way to Mongo and comes
|
|
681
|
+
* back as a server-side "unrecognized time zone identifier" attached to whatever
|
|
682
|
+
* query happened to run — at request time, far from the aggregation that set
|
|
683
|
+
* it. Failing at compile time names the field and the value.
|
|
684
|
+
*/
|
|
685
|
+
const validatedZones = /* @__PURE__ */ new Set(["UTC"]);
|
|
686
|
+
function assertValidTimeZone(zone) {
|
|
687
|
+
if (validatedZones.has(zone)) return;
|
|
688
|
+
try {
|
|
689
|
+
new Intl.DateTimeFormat("en-US", { timeZone: zone });
|
|
690
|
+
} catch {
|
|
691
|
+
throw new Error(`mongokit/aggregate: dateBucket.timezone is not a valid IANA zone — got ${JSON.stringify(zone)}. Use a name like "Asia/Dhaka" or "America/New_York"; omit the field for UTC.`);
|
|
692
|
+
}
|
|
693
|
+
validatedZones.add(zone);
|
|
694
|
+
}
|
|
669
695
|
function compileDateBucket(bucket) {
|
|
670
696
|
const dateExpr = { $toDate: `$${bucket.field}` };
|
|
697
|
+
/**
|
|
698
|
+
* Bucket boundaries are drawn in `bucket.timezone`, defaulting to UTC.
|
|
699
|
+
*
|
|
700
|
+
* Every branch below used to hardcode `'UTC'`, which made the portable IR
|
|
701
|
+
* unusable for any business-day rollup: in a UTC+6 deployment the 18:00–
|
|
702
|
+
* midnight rows land on the previous day and, at month-end, in the previous
|
|
703
|
+
* month — silently. Consumers therefore abandoned the IR and hand-rolled
|
|
704
|
+
* `$dateToString` pipelines, where the zone became optional and was
|
|
705
|
+
* forgotten (see the daily profit rollup that bucketed on UTC days).
|
|
706
|
+
*
|
|
707
|
+
* Mongo takes an IANA zone natively on both operators, so honouring it here
|
|
708
|
+
* costs nothing and makes the correct thing expressible. Gated by the
|
|
709
|
+
* `dateBucketTimezone` capability for kits that cannot do it.
|
|
710
|
+
*/
|
|
711
|
+
const timezone = bucket.timezone ?? "UTC";
|
|
712
|
+
assertValidTimeZone(timezone);
|
|
671
713
|
if (typeof bucket.interval === "object") {
|
|
672
714
|
const { every, unit } = bucket.interval;
|
|
673
715
|
if (!Number.isInteger(every) || every <= 0) throw new Error(`mongokit/aggregate: dateBucket.interval.every must be a positive integer — got ${String(every)}`);
|
|
@@ -675,56 +717,56 @@ function compileDateBucket(bucket) {
|
|
|
675
717
|
date: dateExpr,
|
|
676
718
|
unit,
|
|
677
719
|
binSize: every,
|
|
678
|
-
timezone
|
|
720
|
+
timezone
|
|
679
721
|
} };
|
|
680
722
|
return { $dateToString: {
|
|
681
723
|
format: formatForUnit(unit),
|
|
682
724
|
date: truncated,
|
|
683
|
-
timezone
|
|
725
|
+
timezone
|
|
684
726
|
} };
|
|
685
727
|
}
|
|
686
728
|
switch (bucket.interval) {
|
|
687
729
|
case "minute": return { $dateToString: {
|
|
688
730
|
format: "%Y-%m-%dT%H:%M",
|
|
689
731
|
date: dateExpr,
|
|
690
|
-
timezone
|
|
732
|
+
timezone
|
|
691
733
|
} };
|
|
692
734
|
case "hour": return { $dateToString: {
|
|
693
735
|
format: "%Y-%m-%dT%H:00",
|
|
694
736
|
date: dateExpr,
|
|
695
|
-
timezone
|
|
737
|
+
timezone
|
|
696
738
|
} };
|
|
697
739
|
case "day": return { $dateToString: {
|
|
698
740
|
format: "%Y-%m-%d",
|
|
699
741
|
date: dateExpr,
|
|
700
|
-
timezone
|
|
742
|
+
timezone
|
|
701
743
|
} };
|
|
702
744
|
case "week": return { $dateToString: {
|
|
703
745
|
format: "%G-W%V",
|
|
704
746
|
date: dateExpr,
|
|
705
|
-
timezone
|
|
747
|
+
timezone
|
|
706
748
|
} };
|
|
707
749
|
case "month": return { $dateToString: {
|
|
708
750
|
format: "%Y-%m",
|
|
709
751
|
date: dateExpr,
|
|
710
|
-
timezone
|
|
752
|
+
timezone
|
|
711
753
|
} };
|
|
712
754
|
case "quarter": return { $concat: [
|
|
713
755
|
{ $dateToString: {
|
|
714
756
|
format: "%Y",
|
|
715
757
|
date: dateExpr,
|
|
716
|
-
timezone
|
|
758
|
+
timezone
|
|
717
759
|
} },
|
|
718
760
|
"-Q",
|
|
719
761
|
{ $toString: { $ceil: { $divide: [{ $month: {
|
|
720
762
|
date: dateExpr,
|
|
721
|
-
timezone
|
|
763
|
+
timezone
|
|
722
764
|
} }, 3] } } }
|
|
723
765
|
] };
|
|
724
766
|
case "year": return { $dateToString: {
|
|
725
767
|
format: "%Y",
|
|
726
768
|
date: dateExpr,
|
|
727
|
-
timezone
|
|
769
|
+
timezone
|
|
728
770
|
} };
|
|
729
771
|
}
|
|
730
772
|
}
|
|
@@ -4268,9 +4310,9 @@ var Repository = class extends RepositoryBase {
|
|
|
4268
4310
|
const appendLookupStages$2 = (pipeline) => appendLookupStages(pipeline, lookups, projection, isKeyset && sort ? this._parseSort(sort) : void 0);
|
|
4269
4311
|
if (isKeyset && sort) {
|
|
4270
4312
|
const parsedSort = this._parseSort(sort);
|
|
4271
|
-
const { validateKeysetSort } = await import("./PaginationEngine-
|
|
4272
|
-
const { encodeCursor, resolveCursorFilter } = await import("./PaginationEngine-
|
|
4273
|
-
const { getPrimaryField } = await import("./PaginationEngine-
|
|
4313
|
+
const { validateKeysetSort } = await import("./PaginationEngine-CuONvwCM.mjs").then((n) => n.n);
|
|
4314
|
+
const { encodeCursor, resolveCursorFilter } = await import("./PaginationEngine-CuONvwCM.mjs").then((n) => n.r);
|
|
4315
|
+
const { getPrimaryField } = await import("./PaginationEngine-CuONvwCM.mjs").then((n) => n.n);
|
|
4274
4316
|
const normalizedSort = validateKeysetSort(parsedSort, this._pagination.config.strictKeysetSortFields);
|
|
4275
4317
|
const cursorVersion = this._pagination.config.cursorVersion ?? 1;
|
|
4276
4318
|
const minCursorVersion = this._pagination.config.minCursorVersion ?? 1;
|
package/dist/actions/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-
|
|
1
|
+
import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-Beyr1r4d.mjs";
|
|
2
2
|
export { aggregate_d_exports as aggregate, create_d_exports as create, delete_d_exports as deleteActions, read_d_exports as read, update_d_exports as update };
|
package/dist/actions/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { g as create_exports, i as update_exports, p as delete_exports, u as read_exports, v as aggregate_exports } from "../update-
|
|
2
|
+
import { g as create_exports, i as update_exports, p as delete_exports, u as read_exports, v as aggregate_exports } from "../update-w5i-pa_c.mjs";
|
|
3
3
|
//#region src/actions/index.ts
|
|
4
4
|
var actions_exports = /* @__PURE__ */ __exportAll({
|
|
5
5
|
aggregate: () => aggregate_exports,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as Repository } from "../Repository-
|
|
1
|
+
import { n as Repository } from "../Repository-Cx7BwvDA.mjs";
|
|
2
2
|
import { n as createMongooseAdapter } from "../adapter-BitHg-CN.mjs";
|
|
3
3
|
import { pluralizeBetterAuthCollection, resolveBetterAuthCollections } from "@classytic/repo-core/better-auth";
|
|
4
4
|
//#region src/better-auth/index.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as Repository } from "./Repository-
|
|
2
|
-
import { a as customIdPlugin, f as auditTrailPlugin, i as multiTenantPlugin, m as auditLogPlugin, n as softDeletePlugin, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-
|
|
1
|
+
import { n as Repository } from "./Repository-Cx7BwvDA.mjs";
|
|
2
|
+
import { a as customIdPlugin, f as auditTrailPlugin, i as multiTenantPlugin, m as auditLogPlugin, n as softDeletePlugin, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-CX_kw6TN.mjs";
|
|
3
3
|
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-DblM7V6j.mjs";
|
|
4
4
|
//#region src/create-repository.ts
|
|
5
5
|
function isLoggerAudit(value) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as PaginationConfig } from "./pagination-jSUdrACK.mjs";
|
|
2
2
|
import { _ as RepositoryOptions, d as PluginType } from "./repository-Q16ErTu8.mjs";
|
|
3
3
|
import { T as AuditTrailOptions, _ as RepositoryCachePluginOptions, i as CustomIdOptions, t as MultiTenantOptions } from "./multi-tenant.plugin-2VtSSm1Y.mjs";
|
|
4
|
-
import { n as Repository } from "./Repository-
|
|
4
|
+
import { n as Repository } from "./Repository-BAzymuOz.mjs";
|
|
5
5
|
import { i as Logger, o as SoftDeleteOptions } from "./plugin-options-BsFH0sTi.mjs";
|
|
6
6
|
import { Model } from "mongoose";
|
|
7
7
|
//#region src/create-repository.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as GroupResult, d as MinMaxResult, f as OperationOptions, g as UpdateOptions, h as UpdateManyResult, i as CreateOptions, o as DeleteResult, s as FindOneAndUpdateOptions, y as LookupOptions } from "./operations-
|
|
1
|
+
import { c as GroupResult, d as MinMaxResult, f as OperationOptions, g as UpdateOptions, h as UpdateManyResult, i as CreateOptions, o as DeleteResult, s as FindOneAndUpdateOptions, y as LookupOptions } from "./operations-CuzX9m2Z.mjs";
|
|
2
2
|
import { a as PopulateSpec, i as ObjectId, l as SortSpec, o as ReadPreferenceType, s as SelectSpec, t as AnyDocument } from "./core-62oo3N1C.mjs";
|
|
3
3
|
import { p as UpdateWithValidationResult } from "./type-utils-CLzRFtIA.mjs";
|
|
4
4
|
import { Model, PipelineStage } from "mongoose";
|
package/dist/index.d.mts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { _ as WithTransactionOptions, c as GroupResult, d as MinMaxResult, f as OperationOptions, g as UpdateOptions, h as UpdateManyResult, i as CreateOptions, l as LookupPopulateOptions, m as SessionOptions, n as CacheOperationOptions, o as DeleteResult, p as ReadOptions, r as CacheableOptions, s as FindOneAndUpdateOptions, t as AggregateOptions, u as LookupPopulateResult, v as LookupBuilder, y as LookupOptions } from "./operations-
|
|
1
|
+
import { _ as WithTransactionOptions, c as GroupResult, d as MinMaxResult, f as OperationOptions, g as UpdateOptions, h as UpdateManyResult, i as CreateOptions, l as LookupPopulateOptions, m as SessionOptions, n as CacheOperationOptions, o as DeleteResult, p as ReadOptions, r as CacheableOptions, s as FindOneAndUpdateOptions, t as AggregateOptions, u as LookupPopulateResult, v as LookupBuilder, y as LookupOptions } from "./operations-CuzX9m2Z.mjs";
|
|
2
2
|
import { a as PopulateSpec, c as SortDirection, i as ObjectId, l as SortSpec$1, n as AnyModel, o as ReadPreferenceType, s as SelectSpec, t as AnyDocument } from "./core-62oo3N1C.mjs";
|
|
3
3
|
import { a as DecodedCursor, c as PaginationConfig, i as CursorPayload, l as ValueType, n as BasePaginationOptions, o as KeysetPaginationOptions, r as CollationOptions, s as OffsetPaginationOptions, t as AggregatePaginationOptions } from "./pagination-jSUdrACK.mjs";
|
|
4
|
-
import { t as index_d_exports } from "./index-
|
|
4
|
+
import { t as index_d_exports } from "./index-Beyr1r4d.mjs";
|
|
5
5
|
import { a as InferRawDoc, c as NonNullableFields, d as Strict, f as UpdatePatch, i as InferDocument, l as PartialBy, n as DeepPartial, o as KeysOfType, p as UpdateWithValidationResult, r as DocField, s as MongoOperatorUpdate, t as CreateInput, u as RequiredBy } from "./type-utils-CLzRFtIA.mjs";
|
|
6
6
|
import { S as RepositoryPluginName, _ as RepositoryOptions, a as HookMode, b as MONGOKIT_PLUGIN_NAMES, c as MinimalRepoView, d as PluginType, f as PrioritizedHook, g as RepositoryOperation, h as RepositoryInstance, i as EventPhase, l as Plugin, m as RepositoryEvent, n as EventHandlers, o as Middleware, p as RepositoryContext, r as EventPayload, s as MiddlewareContext, t as AllPluginMethods, u as PluginFunction, v as UserContext, x as MongoKitPluginName, y as WithPlugins } from "./repository-Q16ErTu8.mjs";
|
|
7
7
|
import { A as ensureAuditTrailReady, C as AuditTrailMethods, D as AuditTrailQueryOptions, E as AuditTrailQuery, O as EnsureAuditTrailReadyOptions, S as AuditQueryResult, T as AuditTrailOptions, _ as RepositoryCachePluginOptions, a as DateSequentialIdOptions, b as AuditOperation, c as SequentialIdOptions, d as getNextSequence, f as prefixedId, g as RepositoryCacheHandle, h as CacheOptions, i as CustomIdOptions, k as auditTrailPlugin, l as customIdPlugin, m as CacheAdapter, n as adminBypass, o as IdGenerator, p as sequentialId, r as multiTenantPlugin, s as PrefixedIdOptions, t as MultiTenantOptions, u as dateSequentialId, v as cachePlugin, w as AuditTrailMode, x as AuditQueryOptions, y as AuditEntry } from "./multi-tenant.plugin-2VtSSm1Y.mjs";
|
|
8
8
|
import { t as PaginationEngine } from "./PaginationEngine-CBS1XGzp.mjs";
|
|
9
|
-
import { a as AggregationPlan, c as SortOrder, i as AggregationBuilder, l as SortSpec, n as Repository, o as GroupSpec, r as TransitionMachine, s as ProjectionSpec, t as HOOK_PRIORITY, u as VectorSearchOptions } from "./Repository-
|
|
9
|
+
import { a as AggregationPlan, c as SortOrder, i as AggregationBuilder, l as SortSpec, n as Repository, o as GroupSpec, r as TransitionMachine, s as ProjectionSpec, t as HOOK_PRIORITY, u as VectorSearchOptions } from "./Repository-BAzymuOz.mjs";
|
|
10
10
|
import { a as SoftDeleteFilterMode, c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, n as CascadeRelation, o as SoftDeleteOptions, r as FieldPreset, s as SoftDeleteRepository, t as CascadeOptions } from "./plugin-options-BsFH0sTi.mjs";
|
|
11
|
-
import { n as CreateRepositoryConfig, r as createRepository, t as AuditConfig } from "./create-repository-
|
|
11
|
+
import { n as CreateRepositoryConfig, r as createRepository, t as AuditConfig } from "./create-repository-mEdfH9sz.mjs";
|
|
12
12
|
import { A as IdempotencyStoreMethods, B as auditLogPlugin, C as LeaseMethods, D as ImmutableStatesPluginOptions, E as ImmutableClaimView, F as elasticSearchPlugin, H as appendOnlyPlugin, I as cascadePlugin, L as BatchOperationsMethods, M as idempotencyStorePlugin, N as fieldFilterPlugin, O as immutableStatesPlugin, P as ElasticSearchOptions, R as BulkWriteResult, S as methodRegistryPlugin, T as leasePlugin, U as AggregateHelpersMethods, V as AppendOnlyPluginOptions, W as aggregateHelpersPlugin, _ as OperationMetric, a as requireField, b as mongoOperationsPlugin, c as timestampPlugin, d as createTenantContext, f as SubdocumentMethods, g as ObservabilityOptions, h as softDeletePlugin, i as immutableField, j as IdempotencyStorePluginOptions, k as IdempotencyClaim, l as TenantContext, m as SoftDeleteMethods, n as autoInject, o as uniqueField, p as subdocumentPlugin, r as blockIf, s as validationChainPlugin, t as OperationType, u as TenantStore, v as observabilityPlugin, w as LeasePluginOptions, y as MongoOperationsMethods, z as batchOperationsPlugin } from "./validation-chain.plugin-BSshLJTA.mjs";
|
|
13
13
|
import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-BjdPX3YF.mjs";
|
|
14
14
|
import { n as SchemaIndexes } from "./indexes-DIjMpYES.mjs";
|
|
@@ -118,6 +118,21 @@ type CapabilityResolution = 'declared' | 'observed' | 'unknown';
|
|
|
118
118
|
*/
|
|
119
119
|
interface MongoRepoCapabilities extends RepoCapabilities {
|
|
120
120
|
readonly transactionsResolution: CapabilityResolution;
|
|
121
|
+
/**
|
|
122
|
+
* `LookupOptions.coerce` — join a STRING reference against an `ObjectId` key.
|
|
123
|
+
*
|
|
124
|
+
* Declared HERE and not on repo-core's portable `RepoCapabilities` on
|
|
125
|
+
* purpose: `coerce` is a mongokit-only `LookupOptions` field with no
|
|
126
|
+
* counterpart on repo-core's `LookupSpec`, so a cross-kit caller cannot
|
|
127
|
+
* express it. A portable capability flag for a non-portable option would be
|
|
128
|
+
* decoration — and it would force a repo-core release plus a peer-floor bump
|
|
129
|
+
* on every kit for a field only one of them can honour.
|
|
130
|
+
*
|
|
131
|
+
* It is worth declaring at all because the unsupported case is INVISIBLE: a
|
|
132
|
+
* `$lookup` comparing `string` to `ObjectId` matches nothing and raises no
|
|
133
|
+
* error, so a host cannot tell "not supported here" from "no matches".
|
|
134
|
+
*/
|
|
135
|
+
readonly lookupCoerce: boolean;
|
|
121
136
|
}
|
|
122
137
|
/**
|
|
123
138
|
* Read the provenance of a capability descriptor's `transactions` flag.
|
|
@@ -585,6 +600,19 @@ declare class QueryParser {
|
|
|
585
600
|
* Returns `undefined` if no whitelist is set (all fields allowed).
|
|
586
601
|
*/
|
|
587
602
|
get allowedSortFields(): string[] | undefined;
|
|
603
|
+
/**
|
|
604
|
+
* The configured page-size cap — EXPOSED so a caller does not apply a second one.
|
|
605
|
+
*
|
|
606
|
+
* A resource that constructs `new QueryParser({ maxLimit: 1000 })` has answered the
|
|
607
|
+
* question "how large may a page be?". Without a way to read it back, every layer
|
|
608
|
+
* downstream applies its own default and the LOWEST silently wins — which is exactly
|
|
609
|
+
* what happened: a resource asked for 1000, a repository was configured for 1000, and
|
|
610
|
+
* arc's `QueryResolver` capped at its own default of 100. Three caps, one winner, no
|
|
611
|
+
* signal, and an account picker that showed 100 of 696 rows.
|
|
612
|
+
*
|
|
613
|
+
* Read this instead of defaulting when a parser is supplied.
|
|
614
|
+
*/
|
|
615
|
+
get maxLimit(): number;
|
|
588
616
|
/**
|
|
589
617
|
* Get the configured allowed operators.
|
|
590
618
|
* Returns `undefined` if no whitelist is set (all built-in operators allowed).
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { n as idVariants } from "./id-resolution-BqDrk0S2.mjs";
|
|
2
|
-
import { _ as resetCapabilityProbeCache, a as supportsTransactions, b as transactionResolutionOf, c as ALL_OPERATIONS, d as READ_OPERATIONS, f as operationsByPolicyKey, g as probeMongoCapabilities, h as classifyHelloReply, i as isTransactionUnsupported, l as MUTATING_OPERATIONS, m as capabilitiesForSupport, n as Repository, o as withTransaction, p as MONGOKIT_CAPABILITIES, r as batchTransaction, s as AggregationBuilder, t as HOOK_PRIORITY, u as OP_REGISTRY, v as resolveMongoCapabilities, x as createMongoPurgePort, y as resolveTransactionSupport } from "./Repository-
|
|
3
|
-
import { b as LookupBuilder, x as compileFilterToMongo } from "./update-
|
|
2
|
+
import { _ as resetCapabilityProbeCache, a as supportsTransactions, b as transactionResolutionOf, c as ALL_OPERATIONS, d as READ_OPERATIONS, f as operationsByPolicyKey, g as probeMongoCapabilities, h as classifyHelloReply, i as isTransactionUnsupported, l as MUTATING_OPERATIONS, m as capabilitiesForSupport, n as Repository, o as withTransaction, p as MONGOKIT_CAPABILITIES, r as batchTransaction, s as AggregationBuilder, t as HOOK_PRIORITY, u as OP_REGISTRY, v as resolveMongoCapabilities, x as createMongoPurgePort, y as resolveTransactionSupport } from "./Repository-Cx7BwvDA.mjs";
|
|
3
|
+
import { b as LookupBuilder, x as compileFilterToMongo } from "./update-w5i-pa_c.mjs";
|
|
4
4
|
import { n as warn, t as configureLogger } from "./logger-K7dPmu2U.mjs";
|
|
5
5
|
import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-BuByZwKU.mjs";
|
|
6
6
|
import { t as actions_exports } from "./actions/index.mjs";
|
|
7
|
-
import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, r as adminBypass, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-
|
|
7
|
+
import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, r as adminBypass, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-CX_kw6TN.mjs";
|
|
8
8
|
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-DblM7V6j.mjs";
|
|
9
|
-
import { t as PaginationEngine } from "./PaginationEngine-
|
|
9
|
+
import { t as PaginationEngine } from "./PaginationEngine-CuONvwCM.mjs";
|
|
10
10
|
import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
|
|
11
|
-
import { t as createRepository } from "./create-repository-
|
|
11
|
+
import { t as createRepository } from "./create-repository-EWKzpsyM.mjs";
|
|
12
12
|
import { n as defineModel, r as isModelRegistered, t as ModelCollisionError } from "./model-registry-ClKtWiHa.mjs";
|
|
13
|
-
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-
|
|
13
|
+
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-DbcBOWi3.mjs";
|
|
14
14
|
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-FSQFLpsU.mjs";
|
|
15
15
|
import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
|
|
16
16
|
import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
|
|
@@ -1109,10 +1109,29 @@ function buildQuerySchema(rt) {
|
|
|
1109
1109
|
},
|
|
1110
1110
|
limit: {
|
|
1111
1111
|
type: "integer",
|
|
1112
|
-
|
|
1112
|
+
/**
|
|
1113
|
+
* The cap is DOCUMENTED, not enforced here — deliberately.
|
|
1114
|
+
*
|
|
1115
|
+
* `QueryParser.parse` clamps an over-large limit to `maxLimit` and says so in
|
|
1116
|
+
* its own comment: "Exceeding maxLimit is CLAMPED, not rejected — capping is not
|
|
1117
|
+
* invalid." Emitting `maximum` into the JSON Schema contradicted that: Fastify
|
|
1118
|
+
* validates the querystring BEFORE the parser runs, so the clamp was unreachable
|
|
1119
|
+
* and `?limit=200` became a hard 400.
|
|
1120
|
+
*
|
|
1121
|
+
* That combination is worse than either policy alone. A caller asking for more
|
|
1122
|
+
* rows than allowed is a benign over-ask with an obvious correct answer (give
|
|
1123
|
+
* them the maximum); turning it into a validation failure meant a UI that passed
|
|
1124
|
+
* a generous page size got NOTHING, and — because the two components doing so
|
|
1125
|
+
* never read the query error — rendered it as an empty list rather than a
|
|
1126
|
+
* failure. A 400 disguised as "no results" is the hardest kind to find.
|
|
1127
|
+
*
|
|
1128
|
+
* If a deployment genuinely wants rejection rather than clamping, that belongs
|
|
1129
|
+
* in the parser's fail-closed policy where both halves can agree, not in a schema
|
|
1130
|
+
* that silently outranks it.
|
|
1131
|
+
*/
|
|
1132
|
+
description: `Number of items per page (values above ${rt.options.maxLimit} are capped to ${rt.options.maxLimit})`,
|
|
1113
1133
|
default: 20,
|
|
1114
|
-
minimum: 1
|
|
1115
|
-
maximum: rt.options.maxLimit
|
|
1134
|
+
minimum: 1
|
|
1116
1135
|
},
|
|
1117
1136
|
sort: {
|
|
1118
1137
|
type: "string",
|
|
@@ -1338,6 +1357,21 @@ var QueryParser = class {
|
|
|
1338
1357
|
return this.rt.options.allowedSortFields;
|
|
1339
1358
|
}
|
|
1340
1359
|
/**
|
|
1360
|
+
* The configured page-size cap — EXPOSED so a caller does not apply a second one.
|
|
1361
|
+
*
|
|
1362
|
+
* A resource that constructs `new QueryParser({ maxLimit: 1000 })` has answered the
|
|
1363
|
+
* question "how large may a page be?". Without a way to read it back, every layer
|
|
1364
|
+
* downstream applies its own default and the LOWEST silently wins — which is exactly
|
|
1365
|
+
* what happened: a resource asked for 1000, a repository was configured for 1000, and
|
|
1366
|
+
* arc's `QueryResolver` capped at its own default of 100. Three caps, one winner, no
|
|
1367
|
+
* signal, and an account picker that showed 100 of 696 rows.
|
|
1368
|
+
*
|
|
1369
|
+
* Read this instead of defaulting when a parser is supplied.
|
|
1370
|
+
*/
|
|
1371
|
+
get maxLimit() {
|
|
1372
|
+
return this.rt.options.maxLimit;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1341
1375
|
* Get the configured allowed operators.
|
|
1342
1376
|
* Returns `undefined` if no whitelist is set (all built-in operators allowed).
|
|
1343
1377
|
*/
|
|
@@ -26,8 +26,39 @@ interface LookupOptions {
|
|
|
26
26
|
select?: string | readonly string[] | Record<string, 0 | 1>;
|
|
27
27
|
/** Additional pipeline to run on the joined collection */
|
|
28
28
|
pipeline?: PipelineStage[];
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Let variables for the pipeline form.
|
|
31
|
+
*
|
|
32
|
+
* Values are aggregation EXPRESSIONS, not just field paths — `'$skuRef'` and
|
|
33
|
+
* `{ $toObjectId: '$skuRef' }` are both valid. This was typed
|
|
34
|
+
* `Record<string, string>`, which made every cross-type correlation
|
|
35
|
+
* inexpressible through the typed API and pushed callers to hand-write raw
|
|
36
|
+
* pipelines or give up on the join entirely.
|
|
37
|
+
*/
|
|
38
|
+
let?: Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Coerce `localField` before comparing it to `foreignField`.
|
|
41
|
+
*
|
|
42
|
+
* ## Why this exists
|
|
43
|
+
*
|
|
44
|
+
* A `$lookup` compares values with STRICT BSON type equality. A `string`
|
|
45
|
+
* holding `"6a43c8fd…"` never equals an `ObjectId("6a43c8fd…")`, so the join
|
|
46
|
+
* matches nothing — and a `$lookup` that matches nothing is not an error, it
|
|
47
|
+
* is an empty array. The row renders without its joined data and every count
|
|
48
|
+
* downstream is plausibly, silently wrong.
|
|
49
|
+
*
|
|
50
|
+
* That is not hypothetical: flow stores `skuRef` as an opaque `string` (it
|
|
51
|
+
* must also admit non-ObjectId SKU codes) while `catalog_products._id` is an
|
|
52
|
+
* `ObjectId`. The naive form returned 0 matches for every row; the coerced
|
|
53
|
+
* form returned all of them. The workaround was a second round-trip resolver
|
|
54
|
+
* per request.
|
|
55
|
+
*
|
|
56
|
+
* `'objectId'` compiles to a `$convert` with `onError: null` — NOT
|
|
57
|
+
* `$toObjectId`, which THROWS on the first unconvertible value and would take
|
|
58
|
+
* down the whole query for one legacy SKU code. A row whose ref cannot be an
|
|
59
|
+
* ObjectId simply does not join, which is the same outcome as a genuine miss.
|
|
60
|
+
*/
|
|
61
|
+
coerce?: 'objectId';
|
|
31
62
|
/** Query filter to apply before join (legacy, for aggregate.ts compatibility) */
|
|
32
63
|
query?: Record<string, unknown>;
|
|
33
64
|
/** Query options (legacy, for aggregate.ts compatibility) */
|
|
@@ -75,6 +106,14 @@ declare class LookupBuilder {
|
|
|
75
106
|
* Defaults to the collection name if not specified
|
|
76
107
|
*/
|
|
77
108
|
as(fieldName: string): this;
|
|
109
|
+
/**
|
|
110
|
+
* Coerce the local field before comparing it to the foreign field.
|
|
111
|
+
*
|
|
112
|
+
* Use when the two sides are stored as different BSON types — most commonly a
|
|
113
|
+
* `string` reference against an `ObjectId` `_id`. Without it the join matches
|
|
114
|
+
* nothing and reports no error. See {@link LookupOptions.coerce}.
|
|
115
|
+
*/
|
|
116
|
+
coerce(kind: NonNullable<LookupOptions['coerce']>): this;
|
|
78
117
|
/**
|
|
79
118
|
* Mark this lookup as returning a single document
|
|
80
119
|
* Automatically unwraps the array result to a single object or null
|
|
@@ -98,7 +137,7 @@ declare class LookupBuilder {
|
|
|
98
137
|
* Set let variables for use in pipeline
|
|
99
138
|
* Allows referencing local document fields in the pipeline
|
|
100
139
|
*/
|
|
101
|
-
let(variables: Record<string,
|
|
140
|
+
let(variables: Record<string, unknown>): this;
|
|
102
141
|
/**
|
|
103
142
|
* Control pipeline sanitization (default: true)
|
|
104
143
|
* Set to false for auto-generated pipelines that are known safe
|
package/dist/outbox/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as Repository } from "../Repository-
|
|
1
|
+
import { n as Repository } from "../Repository-BAzymuOz.mjs";
|
|
2
2
|
import { Connection, Model } from "mongoose";
|
|
3
3
|
//#region src/outbox/index.d.ts
|
|
4
4
|
/** Delivery states. `dead_letter` is terminal and operator-visible. */
|
package/dist/outbox/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as Repository } from "../Repository-
|
|
1
|
+
import { n as Repository } from "../Repository-Cx7BwvDA.mjs";
|
|
2
2
|
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-DblM7V6j.mjs";
|
|
3
3
|
import { Schema } from "mongoose";
|
|
4
4
|
//#region src/outbox/index.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as PaginationEngine } from "../PaginationEngine-
|
|
1
|
+
import { t as PaginationEngine } from "../PaginationEngine-CuONvwCM.mjs";
|
|
2
2
|
export { PaginationEngine };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "../timestamp.plugin-
|
|
1
|
+
import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "../timestamp.plugin-CX_kw6TN.mjs";
|
|
2
2
|
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "../method-registry.plugin-DblM7V6j.mjs";
|
|
3
|
-
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-
|
|
3
|
+
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-DbcBOWi3.mjs";
|
|
4
4
|
//#region src/plugins/change-log.plugin.ts
|
|
5
5
|
const PLUGIN_NAME = "changeLog";
|
|
6
6
|
function isSkipped(context) {
|
package/dist/testkit/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as Repository } from "../Repository-
|
|
2
|
-
import { n as CreateRepositoryConfig } from "../create-repository-
|
|
1
|
+
import { n as Repository } from "../Repository-BAzymuOz.mjs";
|
|
2
|
+
import { n as CreateRepositoryConfig } from "../create-repository-mEdfH9sz.mjs";
|
|
3
3
|
import { Connection, Model, Schema } from "mongoose";
|
|
4
4
|
import { MongoMemoryReplSet, MongoMemoryServer } from "mongodb-memory-server";
|
|
5
5
|
//#region src/testkit/index.d.ts
|
package/dist/testkit/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as ALL_OPERATIONS, t as HOOK_PRIORITY, u as OP_REGISTRY } from "./Repository-
|
|
1
|
+
import { c as ALL_OPERATIONS, t as HOOK_PRIORITY, u as OP_REGISTRY } from "./Repository-Cx7BwvDA.mjs";
|
|
2
2
|
import { n as warn } from "./logger-K7dPmu2U.mjs";
|
|
3
3
|
import { throwIfAborted, withRetry } from "@classytic/repo-core/repository";
|
|
4
4
|
import mongoose from "mongoose";
|
|
@@ -201,6 +201,25 @@ const DANGEROUS_OPERATORS = [
|
|
|
201
201
|
"$accumulator"
|
|
202
202
|
];
|
|
203
203
|
/**
|
|
204
|
+
* The local side of a join correlation, coerced when the two sides are stored
|
|
205
|
+
* as different BSON types.
|
|
206
|
+
*
|
|
207
|
+
* `$convert` with `onError`/`onNull` rather than `$toObjectId`: the latter
|
|
208
|
+
* throws on the first unconvertible value, which would fail the entire
|
|
209
|
+
* aggregation because ONE row held a legacy non-ObjectId reference. Returning
|
|
210
|
+
* null makes that row miss the join, exactly as a genuine non-match would.
|
|
211
|
+
*/
|
|
212
|
+
function localCorrelation(localField, coerce) {
|
|
213
|
+
const path = `$${localField}`;
|
|
214
|
+
if (coerce !== "objectId") return path;
|
|
215
|
+
return { $convert: {
|
|
216
|
+
input: path,
|
|
217
|
+
to: "objectId",
|
|
218
|
+
onError: null,
|
|
219
|
+
onNull: null
|
|
220
|
+
} };
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
204
223
|
* Fluent builder for MongoDB $lookup aggregation stage
|
|
205
224
|
* Optimized for custom field joins at scale
|
|
206
225
|
*/
|
|
@@ -241,6 +260,17 @@ var LookupBuilder = class LookupBuilder {
|
|
|
241
260
|
return this;
|
|
242
261
|
}
|
|
243
262
|
/**
|
|
263
|
+
* Coerce the local field before comparing it to the foreign field.
|
|
264
|
+
*
|
|
265
|
+
* Use when the two sides are stored as different BSON types — most commonly a
|
|
266
|
+
* `string` reference against an `ObjectId` `_id`. Without it the join matches
|
|
267
|
+
* nothing and reports no error. See {@link LookupOptions.coerce}.
|
|
268
|
+
*/
|
|
269
|
+
coerce(kind) {
|
|
270
|
+
this.options.coerce = kind;
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
244
274
|
* Mark this lookup as returning a single document
|
|
245
275
|
* Automatically unwraps the array result to a single object or null
|
|
246
276
|
*/
|
|
@@ -293,11 +323,12 @@ var LookupBuilder = class LookupBuilder {
|
|
|
293
323
|
* Otherwise, we use the simpler localField/foreignField form.
|
|
294
324
|
*/
|
|
295
325
|
build() {
|
|
296
|
-
const { from, localField, foreignField, as, single, pipeline, let: letVars } = this.options;
|
|
326
|
+
const { from, localField, foreignField, as, single, pipeline, let: letVars, coerce } = this.options;
|
|
297
327
|
if (!from) throw new Error("LookupBuilder: \"from\" collection is required");
|
|
328
|
+
if (coerce && (!localField || !foreignField)) throw new Error("LookupBuilder: \"coerce\" needs both localField and foreignField — it describes how to compare them. Without both there is no comparison to coerce.");
|
|
298
329
|
const outputField = as || from;
|
|
299
330
|
const stages = [];
|
|
300
|
-
const usePipelineForm = pipeline || letVars;
|
|
331
|
+
const usePipelineForm = pipeline || letVars || coerce;
|
|
301
332
|
let lookupStage;
|
|
302
333
|
if (usePipelineForm) if (!pipeline || pipeline.length === 0) {
|
|
303
334
|
if (!localField || !foreignField) throw new Error("LookupBuilder: When using pipeline form without a custom pipeline, both localField and foreignField are required to auto-generate the pipeline");
|
|
@@ -305,7 +336,7 @@ var LookupBuilder = class LookupBuilder {
|
|
|
305
336
|
lookupStage = { $lookup: {
|
|
306
337
|
from,
|
|
307
338
|
let: {
|
|
308
|
-
[localField]:
|
|
339
|
+
[localField]: localCorrelation(localField, coerce),
|
|
309
340
|
...letVars || {}
|
|
310
341
|
},
|
|
311
342
|
pipeline: autoPipeline,
|
|
@@ -316,7 +347,7 @@ var LookupBuilder = class LookupBuilder {
|
|
|
316
347
|
let effectiveLet = letVars;
|
|
317
348
|
let effectivePipeline = safePipeline;
|
|
318
349
|
if (localField && foreignField && !letVars) {
|
|
319
|
-
effectiveLet = { lookupJoinVal:
|
|
350
|
+
effectiveLet = { lookupJoinVal: localCorrelation(localField, coerce) };
|
|
320
351
|
effectivePipeline = [{ $match: { $expr: { $eq: [`$${foreignField}`, "$$lookupJoinVal"] } } }, ...safePipeline];
|
|
321
352
|
}
|
|
322
353
|
lookupStage = { $lookup: {
|
|
@@ -371,6 +402,17 @@ var LookupBuilder = class LookupBuilder {
|
|
|
371
402
|
const builder = new LookupBuilder(lookup.from).localField(lookup.localField).foreignField(lookup.foreignField);
|
|
372
403
|
if (lookup.as) builder.as(lookup.as);
|
|
373
404
|
if (lookup.single) builder.single(lookup.single);
|
|
405
|
+
/**
|
|
406
|
+
* Coercion, for the SIMPLE branch below (no select / pipeline / where):
|
|
407
|
+
* there `build()` auto-generates the correlation and reads this flag.
|
|
408
|
+
*
|
|
409
|
+
* The pipeline branch sets its own `let` explicitly and therefore coerces
|
|
410
|
+
* at THAT assignment instead — see `lookupJoinVal` further down. Both
|
|
411
|
+
* exist because `multiple()` hand-assembles stages rather than deferring
|
|
412
|
+
* to `build()`, so each of its two paths must be covered separately; a
|
|
413
|
+
* fix to one silently leaves the other matching nothing.
|
|
414
|
+
*/
|
|
415
|
+
if (lookup.coerce) builder.coerce(lookup.coerce);
|
|
374
416
|
const stages = [];
|
|
375
417
|
const appendCallerStages = (raw) => {
|
|
376
418
|
if (raw.length === 0) return;
|
|
@@ -385,7 +427,7 @@ var LookupBuilder = class LookupBuilder {
|
|
|
385
427
|
if (lookup.select) stages.push({ $project: compileSelectToProjection(lookup.select) });
|
|
386
428
|
builder.pipeline(stages);
|
|
387
429
|
builder.let({
|
|
388
|
-
lookupJoinVal:
|
|
430
|
+
lookupJoinVal: localCorrelation(lookup.localField, lookup.coerce),
|
|
389
431
|
...lookup.let || {}
|
|
390
432
|
});
|
|
391
433
|
builder.sanitize(false);
|
|
@@ -413,6 +455,7 @@ var LookupBuilder = class LookupBuilder {
|
|
|
413
455
|
if (lookup.single !== void 0) builder.single(lookup.single);
|
|
414
456
|
if (lookup.pipeline) builder.pipeline(lookup.pipeline);
|
|
415
457
|
if (lookup.let) builder.let(lookup.let);
|
|
458
|
+
if (lookup.coerce) builder.coerce(lookup.coerce);
|
|
416
459
|
return builder.build();
|
|
417
460
|
});
|
|
418
461
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as ALL_OPERATIONS, u as OP_REGISTRY } from "./Repository-
|
|
2
|
-
import { _ as upsert } from "./update-
|
|
1
|
+
import { c as ALL_OPERATIONS, u as OP_REGISTRY } from "./Repository-Cx7BwvDA.mjs";
|
|
2
|
+
import { _ as upsert } from "./update-w5i-pa_c.mjs";
|
|
3
3
|
import { n as warn } from "./logger-K7dPmu2U.mjs";
|
|
4
4
|
import { t as createError } from "./error-BuByZwKU.mjs";
|
|
5
5
|
import { r as getFieldsForUser } from "./field-selection-FSQFLpsU.mjs";
|
package/package.json
CHANGED
|
@@ -1,193 +1,193 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@classytic/mongokit",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Production-grade MongoDB repositories - smart pagination, events, and plugins. Built on @classytic/repo-core.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"sideEffects": false,
|
|
7
|
-
"main": "./dist/index.mjs",
|
|
8
|
-
"module": "./dist/index.mjs",
|
|
9
|
-
"types": "./dist/index.d.mts",
|
|
10
|
-
"exports": {
|
|
11
|
-
".": {
|
|
12
|
-
"types": "./dist/index.d.mts",
|
|
13
|
-
"default": "./dist/index.mjs"
|
|
14
|
-
},
|
|
15
|
-
"./pagination": {
|
|
16
|
-
"types": "./dist/pagination/PaginationEngine.d.mts",
|
|
17
|
-
"default": "./dist/pagination/PaginationEngine.mjs"
|
|
18
|
-
},
|
|
19
|
-
"./plugins": {
|
|
20
|
-
"types": "./dist/plugins/index.d.mts",
|
|
21
|
-
"default": "./dist/plugins/index.mjs"
|
|
22
|
-
},
|
|
23
|
-
"./utils": {
|
|
24
|
-
"types": "./dist/utils/index.d.mts",
|
|
25
|
-
"default": "./dist/utils/index.mjs"
|
|
26
|
-
},
|
|
27
|
-
"./actions": {
|
|
28
|
-
"types": "./dist/actions/index.d.mts",
|
|
29
|
-
"default": "./dist/actions/index.mjs"
|
|
30
|
-
},
|
|
31
|
-
"./ai": {
|
|
32
|
-
"types": "./dist/ai/index.d.mts",
|
|
33
|
-
"default": "./dist/ai/index.mjs"
|
|
34
|
-
},
|
|
35
|
-
"./adapter": {
|
|
36
|
-
"types": "./dist/adapter/index.d.mts",
|
|
37
|
-
"default": "./dist/adapter/index.mjs"
|
|
38
|
-
},
|
|
39
|
-
"./better-auth": {
|
|
40
|
-
"types": "./dist/better-auth/index.d.mts",
|
|
41
|
-
"default": "./dist/better-auth/index.mjs"
|
|
42
|
-
},
|
|
43
|
-
"./outbox": {
|
|
44
|
-
"types": "./dist/outbox/index.d.mts",
|
|
45
|
-
"default": "./dist/outbox/index.mjs"
|
|
46
|
-
},
|
|
47
|
-
"./lock": {
|
|
48
|
-
"types": "./dist/lock/index.d.mts",
|
|
49
|
-
"default": "./dist/lock/index.mjs"
|
|
50
|
-
},
|
|
51
|
-
"./usage": {
|
|
52
|
-
"types": "./dist/usage/index.d.mts",
|
|
53
|
-
"default": "./dist/usage/index.mjs"
|
|
54
|
-
},
|
|
55
|
-
"./query/primitives/geo": {
|
|
56
|
-
"types": "./dist/query/primitives/geo.d.mts",
|
|
57
|
-
"default": "./dist/query/primitives/geo.mjs"
|
|
58
|
-
},
|
|
59
|
-
"./query/primitives/coercion": {
|
|
60
|
-
"types": "./dist/query/primitives/coercion.d.mts",
|
|
61
|
-
"default": "./dist/query/primitives/coercion.mjs"
|
|
62
|
-
},
|
|
63
|
-
"./query/primitives/indexes": {
|
|
64
|
-
"types": "./dist/query/primitives/indexes.d.mts",
|
|
65
|
-
"default": "./dist/query/primitives/indexes.mjs"
|
|
66
|
-
},
|
|
67
|
-
"./testkit": {
|
|
68
|
-
"types": "./dist/testkit/index.d.mts",
|
|
69
|
-
"default": "./dist/testkit/index.mjs"
|
|
70
|
-
},
|
|
71
|
-
"./kernel-conformance": {
|
|
72
|
-
"types": "./dist/kernel-conformance/index.d.mts",
|
|
73
|
-
"default": "./dist/kernel-conformance/index.mjs"
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
"files": [
|
|
77
|
-
"dist",
|
|
78
|
-
"README.md",
|
|
79
|
-
"LICENSE",
|
|
80
|
-
"TRADEMARK.md"
|
|
81
|
-
],
|
|
82
|
-
"keywords": [
|
|
83
|
-
"mongodb",
|
|
84
|
-
"mongoose",
|
|
85
|
-
"repository",
|
|
86
|
-
"repository-pattern",
|
|
87
|
-
"data-access",
|
|
88
|
-
"pagination",
|
|
89
|
-
"cursor-pagination",
|
|
90
|
-
"infinite-scroll",
|
|
91
|
-
"offset-pagination",
|
|
92
|
-
"keyset-pagination",
|
|
93
|
-
"caching",
|
|
94
|
-
"redis",
|
|
95
|
-
"cache",
|
|
96
|
-
"multi-tenant",
|
|
97
|
-
"multi-tenancy",
|
|
98
|
-
"vector-search",
|
|
99
|
-
"embeddings",
|
|
100
|
-
"atlas-search",
|
|
101
|
-
"observability",
|
|
102
|
-
"event-driven",
|
|
103
|
-
"plugin-based",
|
|
104
|
-
"zero-dependencies",
|
|
105
|
-
"express",
|
|
106
|
-
"fastify",
|
|
107
|
-
"nestjs",
|
|
108
|
-
"nextjs",
|
|
109
|
-
"typescript"
|
|
110
|
-
],
|
|
111
|
-
"author": "Classytic <classytic.dev@gmail.com> (https://github.com/classytic)",
|
|
112
|
-
"contributors": [
|
|
113
|
-
"Sadman Chowdhury (https://github.com/siam923)"
|
|
114
|
-
],
|
|
115
|
-
"license": "MIT",
|
|
116
|
-
"repository": {
|
|
117
|
-
"type": "git",
|
|
118
|
-
"url": "git+https://github.com/classytic/mongokit.git"
|
|
119
|
-
},
|
|
120
|
-
"bugs": {
|
|
121
|
-
"url": "https://github.com/classytic/mongokit/issues"
|
|
122
|
-
},
|
|
123
|
-
"homepage": "https://github.com/classytic/mongokit#readme",
|
|
124
|
-
"peerDependencies": {
|
|
125
|
-
"@classytic/repo-core": ">=0.20.0",
|
|
126
|
-
"mongodb-memory-server": ">=10.4.3",
|
|
127
|
-
"mongoose": ">=9.4.1"
|
|
128
|
-
},
|
|
129
|
-
"peerDependenciesMeta": {
|
|
130
|
-
"mongodb-memory-server": {
|
|
131
|
-
"optional": true
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
"engines": {
|
|
135
|
-
"node": ">=22"
|
|
136
|
-
},
|
|
137
|
-
"publishConfig": {
|
|
138
|
-
"access": "public"
|
|
139
|
-
},
|
|
140
|
-
"scripts": {
|
|
141
|
-
"build": "tsdown",
|
|
142
|
-
"dev": "tsdown --watch",
|
|
143
|
-
"test": "vitest run --project unit --project integration",
|
|
144
|
-
"test:unit": "vitest run --project unit",
|
|
145
|
-
"test:integration": "vitest run --project integration",
|
|
146
|
-
"test:e2e": "vitest run --project e2e",
|
|
147
|
-
"test:all": "vitest run --project unit --project integration --project e2e",
|
|
148
|
-
"test:watch": "vitest --project unit --project integration",
|
|
149
|
-
"test:coverage": "vitest run --coverage",
|
|
150
|
-
"typecheck": "tsc --noEmit",
|
|
151
|
-
"typecheck:tests": "tsc --noEmit -p tsconfig.tests.json",
|
|
152
|
-
"lint": "biome check src/",
|
|
153
|
-
"lint:fix": "biome check src/ --write",
|
|
154
|
-
"check:exports": "node scripts/check-exports.mjs",
|
|
155
|
-
"lint:package": "npm run check:exports && publint && attw --pack . --profile esm-only",
|
|
156
|
-
"format": "biome format src/ --write",
|
|
157
|
-
"check": "biome ci src/ --diagnostic-level=error",
|
|
158
|
-
"check:dead-code": "knip",
|
|
159
|
-
"ci": "npm run check && npm run typecheck && npm run typecheck:tests && npm run build && npm run lint:package && npm run check:dead-code && npm run check:forgotten-exports && npm test",
|
|
160
|
-
"push": "classytic-push",
|
|
161
|
-
"prepublishOnly": "npm run ci",
|
|
162
|
-
"publish:dry": "npm publish --dry-run --access public",
|
|
163
|
-
"publish:npm": "npm publish --access public",
|
|
164
|
-
"release:tag": "node -e \"require('child_process').execSync('npm run push -- v'+require('./package.json').version,{stdio:'inherit'})\"",
|
|
165
|
-
"release": "npm run push -- main && npm run release:tag && npm publish --access public",
|
|
166
|
-
"release:patch": "npm version patch && npm run release",
|
|
167
|
-
"release:minor": "npm version minor && npm run release",
|
|
168
|
-
"release:major": "npm version major && npm run release",
|
|
169
|
-
"check:forgotten-exports": "node scripts/check-forgotten-exports.mjs"
|
|
170
|
-
},
|
|
171
|
-
"devDependencies": {
|
|
172
|
-
"@arethetypeswrong/cli": "^0.18.2",
|
|
173
|
-
"@better-auth/api-key": "^1.6.22",
|
|
174
|
-
"@better-auth/mongo-adapter": "^1.6.22",
|
|
175
|
-
"@biomejs/biome": "^2.4.10",
|
|
176
|
-
"@classytic/dev-tools": "^0.2.0",
|
|
177
|
-
"@classytic/repo-core": "^0.
|
|
178
|
-
"@types/node": "^22.0.0",
|
|
179
|
-
"@vitest/coverage-v8": "^4.1.4",
|
|
180
|
-
"ajv": "^8.18.0",
|
|
181
|
-
"ajv-formats": "^3.0.1",
|
|
182
|
-
"better-auth": "^1.6.23",
|
|
183
|
-
"dotenv": "^17.4.2",
|
|
184
|
-
"knip": "^6.31.0",
|
|
185
|
-
"mongodb": "^7.5.0",
|
|
186
|
-
"mongodb-memory-server": "^10.4.3",
|
|
187
|
-
"mongoose": "^9.9.1",
|
|
188
|
-
"publint": "^0.3.18",
|
|
189
|
-
"tsdown": "^0.22.14",
|
|
190
|
-
"typescript": "~5.9.0",
|
|
191
|
-
"vitest": "^4.1.4"
|
|
192
|
-
}
|
|
193
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@classytic/mongokit",
|
|
3
|
+
"version": "3.31.1",
|
|
4
|
+
"description": "Production-grade MongoDB repositories - smart pagination, events, and plugins. Built on @classytic/repo-core.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.mjs",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.mts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.mts",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./pagination": {
|
|
16
|
+
"types": "./dist/pagination/PaginationEngine.d.mts",
|
|
17
|
+
"default": "./dist/pagination/PaginationEngine.mjs"
|
|
18
|
+
},
|
|
19
|
+
"./plugins": {
|
|
20
|
+
"types": "./dist/plugins/index.d.mts",
|
|
21
|
+
"default": "./dist/plugins/index.mjs"
|
|
22
|
+
},
|
|
23
|
+
"./utils": {
|
|
24
|
+
"types": "./dist/utils/index.d.mts",
|
|
25
|
+
"default": "./dist/utils/index.mjs"
|
|
26
|
+
},
|
|
27
|
+
"./actions": {
|
|
28
|
+
"types": "./dist/actions/index.d.mts",
|
|
29
|
+
"default": "./dist/actions/index.mjs"
|
|
30
|
+
},
|
|
31
|
+
"./ai": {
|
|
32
|
+
"types": "./dist/ai/index.d.mts",
|
|
33
|
+
"default": "./dist/ai/index.mjs"
|
|
34
|
+
},
|
|
35
|
+
"./adapter": {
|
|
36
|
+
"types": "./dist/adapter/index.d.mts",
|
|
37
|
+
"default": "./dist/adapter/index.mjs"
|
|
38
|
+
},
|
|
39
|
+
"./better-auth": {
|
|
40
|
+
"types": "./dist/better-auth/index.d.mts",
|
|
41
|
+
"default": "./dist/better-auth/index.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./outbox": {
|
|
44
|
+
"types": "./dist/outbox/index.d.mts",
|
|
45
|
+
"default": "./dist/outbox/index.mjs"
|
|
46
|
+
},
|
|
47
|
+
"./lock": {
|
|
48
|
+
"types": "./dist/lock/index.d.mts",
|
|
49
|
+
"default": "./dist/lock/index.mjs"
|
|
50
|
+
},
|
|
51
|
+
"./usage": {
|
|
52
|
+
"types": "./dist/usage/index.d.mts",
|
|
53
|
+
"default": "./dist/usage/index.mjs"
|
|
54
|
+
},
|
|
55
|
+
"./query/primitives/geo": {
|
|
56
|
+
"types": "./dist/query/primitives/geo.d.mts",
|
|
57
|
+
"default": "./dist/query/primitives/geo.mjs"
|
|
58
|
+
},
|
|
59
|
+
"./query/primitives/coercion": {
|
|
60
|
+
"types": "./dist/query/primitives/coercion.d.mts",
|
|
61
|
+
"default": "./dist/query/primitives/coercion.mjs"
|
|
62
|
+
},
|
|
63
|
+
"./query/primitives/indexes": {
|
|
64
|
+
"types": "./dist/query/primitives/indexes.d.mts",
|
|
65
|
+
"default": "./dist/query/primitives/indexes.mjs"
|
|
66
|
+
},
|
|
67
|
+
"./testkit": {
|
|
68
|
+
"types": "./dist/testkit/index.d.mts",
|
|
69
|
+
"default": "./dist/testkit/index.mjs"
|
|
70
|
+
},
|
|
71
|
+
"./kernel-conformance": {
|
|
72
|
+
"types": "./dist/kernel-conformance/index.d.mts",
|
|
73
|
+
"default": "./dist/kernel-conformance/index.mjs"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"files": [
|
|
77
|
+
"dist",
|
|
78
|
+
"README.md",
|
|
79
|
+
"LICENSE",
|
|
80
|
+
"TRADEMARK.md"
|
|
81
|
+
],
|
|
82
|
+
"keywords": [
|
|
83
|
+
"mongodb",
|
|
84
|
+
"mongoose",
|
|
85
|
+
"repository",
|
|
86
|
+
"repository-pattern",
|
|
87
|
+
"data-access",
|
|
88
|
+
"pagination",
|
|
89
|
+
"cursor-pagination",
|
|
90
|
+
"infinite-scroll",
|
|
91
|
+
"offset-pagination",
|
|
92
|
+
"keyset-pagination",
|
|
93
|
+
"caching",
|
|
94
|
+
"redis",
|
|
95
|
+
"cache",
|
|
96
|
+
"multi-tenant",
|
|
97
|
+
"multi-tenancy",
|
|
98
|
+
"vector-search",
|
|
99
|
+
"embeddings",
|
|
100
|
+
"atlas-search",
|
|
101
|
+
"observability",
|
|
102
|
+
"event-driven",
|
|
103
|
+
"plugin-based",
|
|
104
|
+
"zero-dependencies",
|
|
105
|
+
"express",
|
|
106
|
+
"fastify",
|
|
107
|
+
"nestjs",
|
|
108
|
+
"nextjs",
|
|
109
|
+
"typescript"
|
|
110
|
+
],
|
|
111
|
+
"author": "Classytic <classytic.dev@gmail.com> (https://github.com/classytic)",
|
|
112
|
+
"contributors": [
|
|
113
|
+
"Sadman Chowdhury (https://github.com/siam923)"
|
|
114
|
+
],
|
|
115
|
+
"license": "MIT",
|
|
116
|
+
"repository": {
|
|
117
|
+
"type": "git",
|
|
118
|
+
"url": "git+https://github.com/classytic/mongokit.git"
|
|
119
|
+
},
|
|
120
|
+
"bugs": {
|
|
121
|
+
"url": "https://github.com/classytic/mongokit/issues"
|
|
122
|
+
},
|
|
123
|
+
"homepage": "https://github.com/classytic/mongokit#readme",
|
|
124
|
+
"peerDependencies": {
|
|
125
|
+
"@classytic/repo-core": ">=0.20.0",
|
|
126
|
+
"mongodb-memory-server": ">=10.4.3",
|
|
127
|
+
"mongoose": ">=9.4.1"
|
|
128
|
+
},
|
|
129
|
+
"peerDependenciesMeta": {
|
|
130
|
+
"mongodb-memory-server": {
|
|
131
|
+
"optional": true
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"engines": {
|
|
135
|
+
"node": ">=22"
|
|
136
|
+
},
|
|
137
|
+
"publishConfig": {
|
|
138
|
+
"access": "public"
|
|
139
|
+
},
|
|
140
|
+
"scripts": {
|
|
141
|
+
"build": "tsdown",
|
|
142
|
+
"dev": "tsdown --watch",
|
|
143
|
+
"test": "vitest run --project unit --project integration",
|
|
144
|
+
"test:unit": "vitest run --project unit",
|
|
145
|
+
"test:integration": "vitest run --project integration",
|
|
146
|
+
"test:e2e": "vitest run --project e2e",
|
|
147
|
+
"test:all": "vitest run --project unit --project integration --project e2e",
|
|
148
|
+
"test:watch": "vitest --project unit --project integration",
|
|
149
|
+
"test:coverage": "vitest run --coverage",
|
|
150
|
+
"typecheck": "tsc --noEmit",
|
|
151
|
+
"typecheck:tests": "tsc --noEmit -p tsconfig.tests.json",
|
|
152
|
+
"lint": "biome check src/",
|
|
153
|
+
"lint:fix": "biome check src/ --write",
|
|
154
|
+
"check:exports": "node scripts/check-exports.mjs",
|
|
155
|
+
"lint:package": "npm run check:exports && publint && attw --pack . --profile esm-only",
|
|
156
|
+
"format": "biome format src/ --write",
|
|
157
|
+
"check": "biome ci src/ --diagnostic-level=error",
|
|
158
|
+
"check:dead-code": "knip",
|
|
159
|
+
"ci": "npm run check && npm run typecheck && npm run typecheck:tests && npm run build && npm run lint:package && npm run check:dead-code && npm run check:forgotten-exports && npm test",
|
|
160
|
+
"push": "classytic-push",
|
|
161
|
+
"prepublishOnly": "npm run ci",
|
|
162
|
+
"publish:dry": "npm publish --dry-run --access public",
|
|
163
|
+
"publish:npm": "npm publish --access public",
|
|
164
|
+
"release:tag": "node -e \"require('child_process').execSync('npm run push -- v'+require('./package.json').version,{stdio:'inherit'})\"",
|
|
165
|
+
"release": "npm run push -- main && npm run release:tag && npm publish --access public",
|
|
166
|
+
"release:patch": "npm version patch && npm run release",
|
|
167
|
+
"release:minor": "npm version minor && npm run release",
|
|
168
|
+
"release:major": "npm version major && npm run release",
|
|
169
|
+
"check:forgotten-exports": "node scripts/check-forgotten-exports.mjs"
|
|
170
|
+
},
|
|
171
|
+
"devDependencies": {
|
|
172
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
173
|
+
"@better-auth/api-key": "^1.6.22",
|
|
174
|
+
"@better-auth/mongo-adapter": "^1.6.22",
|
|
175
|
+
"@biomejs/biome": "^2.4.10",
|
|
176
|
+
"@classytic/dev-tools": "^0.2.0",
|
|
177
|
+
"@classytic/repo-core": "^0.21.0",
|
|
178
|
+
"@types/node": "^22.0.0",
|
|
179
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
180
|
+
"ajv": "^8.18.0",
|
|
181
|
+
"ajv-formats": "^3.0.1",
|
|
182
|
+
"better-auth": "^1.6.23",
|
|
183
|
+
"dotenv": "^17.4.2",
|
|
184
|
+
"knip": "^6.31.0",
|
|
185
|
+
"mongodb": "^7.5.0",
|
|
186
|
+
"mongodb-memory-server": "^10.4.3",
|
|
187
|
+
"mongoose": "^9.9.1",
|
|
188
|
+
"publint": "^0.3.18",
|
|
189
|
+
"tsdown": "^0.22.14",
|
|
190
|
+
"typescript": "~5.9.0",
|
|
191
|
+
"vitest": "^4.1.4"
|
|
192
|
+
}
|
|
193
|
+
}
|