@classytic/mongokit 3.11.0 → 3.11.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/README.md CHANGED
@@ -269,6 +269,16 @@ const result = await invoiceRepo.getAll({ filters, sort, page, limit, search });
269
269
 
270
270
  Supports URL operators: `_gt/_gte/_lt/_lte/_ne/_in/_nin/_regex`, geo (`[near]`, `[withinRadius]`, `[geoWithin]`), populate, and schema-aware coercion. ReDoS protection + allowlisted operators for hardening.
271
271
 
272
+ **Nested subdocument filters.** Dotted paths pass through to MongoDB directly — Mongoose's strict-mode casting handles the nested-schema lookup, no special config required:
273
+
274
+ ```
275
+ ?contact.email[contains]=foo → { 'contact.email': { $regex: /foo/i } }
276
+ ?name.given=sadman → { 'name.given': 'sadman' }
277
+ ?name.given[in]=a,b → { 'name.given': { $in: ['a', 'b'] } }
278
+ ```
279
+
280
+ Dot-in-key semantics follow `qs` parsing: `?name.given=x` produces `{ 'name.given': 'x' }` (NOT nested into `{ name: { given: 'x' } }`). For the nested-object form use bracket notation: `?name[given]=x`.
281
+
272
282
  ---
273
283
 
274
284
  ## TypeScript
@@ -1,5 +1,5 @@
1
1
  import { r as warn } from "./logger-DJ7egMnd.mjs";
2
- import { t as createError } from "./error-CzYwrfUP.mjs";
2
+ import { t as createError } from "./error-B00pI7dV.mjs";
3
3
  import { n as encodeCursor, r as resolveCursorFilter } from "./cursor-J84rR6wG.mjs";
4
4
  import { r as validateKeysetSort, t as getPrimaryField } from "./sort-CrZjTK25.mjs";
5
5
  //#region src/pagination/utils/index-hint.ts
@@ -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-C1MzVFsT.mjs";
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-dNTmpgK8.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 };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../chunk-CfYAbeIz.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-CWXfFC6O.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-DEJYcgfV.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 { q as Plugin } from "../types-xOyTec4n.mjs";
1
+ import { q as Plugin } from "../types-Dc2aDVUi.mjs";
2
2
  import { PipelineStage } from "mongoose";
3
3
 
4
4
  //#region src/ai/types.d.ts
@@ -1,19 +1,26 @@
1
1
  //#region src/utils/error.ts
2
2
  /**
3
- * Creates an error with HTTP status code
3
+ * Creates an error with HTTP status code, plus optional stable `code` /
4
+ * `meta` so callers can `catch` on the code instead of regex-matching the
5
+ * message string.
4
6
  *
5
7
  * @param status - HTTP status code
6
8
  * @param message - Error message
9
+ * @param options - Optional `code` / `meta` for structured handling
7
10
  * @returns Error with status property
8
11
  *
9
12
  * @example
10
13
  * throw createError(404, 'Document not found');
11
- * throw createError(400, 'Invalid input');
12
- * throw createError(403, 'Access denied');
14
+ * throw createError(400, 'Invalid input', {
15
+ * code: 'SEARCH_NOT_CONFIGURED',
16
+ * meta: { model: 'Customer', availableModes: ['text', 'regex', 'auto'] },
17
+ * });
13
18
  */
14
- function createError(status, message) {
19
+ function createError(status, message, options) {
15
20
  const error = new Error(message);
16
21
  error.status = status;
22
+ if (options?.code !== void 0) error.code = options.code;
23
+ if (options?.meta !== void 0) error.meta = options.meta;
17
24
  return error;
18
25
  }
19
26
  /**
@@ -1,4 +1,4 @@
1
- import { $ as ReadPreferenceType, B as ObjectId, D as GroupResult, E as FindOneAndUpdateOptions, R as MinMaxResult, U as OperationOptions, X as PopulateSpec, a as AnyDocument, b as DeleteResult, ft as SortSpec, g as CreateOptions, gt as UpdateOptions, ht as UpdateManyResult, kt as LookupOptions, ot as SelectSpec, vt as UpdateWithValidationResult } from "./types-xOyTec4n.mjs";
1
+ import { $ as ReadPreferenceType, B as ObjectId, D as GroupResult, E as FindOneAndUpdateOptions, R as MinMaxResult, U as OperationOptions, X as PopulateSpec, a as AnyDocument, b as DeleteResult, ft as SortSpec, g as CreateOptions, gt as UpdateOptions, ht as UpdateManyResult, kt as LookupOptions, ot as SelectSpec, vt as UpdateWithValidationResult } from "./types-Dc2aDVUi.mjs";
2
2
  import { Model, PipelineStage } from "mongoose";
3
3
 
4
4
  //#region src/actions/aggregate.d.ts
package/dist/index.d.mts CHANGED
@@ -1,10 +1,10 @@
1
- import { $ as ReadPreferenceType, A as InferDocument, B as ObjectId, C as EventPayload, Ct as WithTransactionOptions, D as GroupResult, Dt as IResponseFormatter, E as FindOneAndUpdateOptions, Et as IRequestContext, F as Logger, G as PaginationResult, H as OffsetPaginationResult, I as LookupPopulateOptions, J as PluginFunction, K as PartialBy, L as LookupPopulateResult, M as KeysOfType, N as KeysetPaginationOptions, O as HookMode, Ot as LookupBuilder, P as KeysetPaginationResult, Q as ReadOptions, R as MinMaxResult, S as EventHandlers, St as WithPlugins, T as FieldPreset, Tt as IControllerResponse, U as OperationOptions, V as OffsetPaginationOptions, W as PaginationConfig, X as PopulateSpec, Y as PluginType, Z as PrioritizedHook, _ as DecodedCursor, _t as UpdatePatch, a as AnyDocument, at as RequiredBy, b as DeleteResult, bt as ValidationChainOptions, c as CacheOperationOptions, ct as SoftDeleteFilterMode, d as CacheableOptions, dt as SortDirection, et as RepositoryContext, f as CascadeOptions, ft as SortSpec, g as CreateOptions, gt as UpdateOptions, h as CreateInput, ht as UpdateManyResult, i as AllPluginMethods, it as RepositoryOptions, j as InferRawDoc, k as HttpError, kt as LookupOptions, l as CacheOptions, lt as SoftDeleteOptions, m as CollationOptions, mt as UpdateInput, n as AggregatePaginationOptions, nt as RepositoryInstance, o as AnyModel, ot as SelectSpec, p as CascadeRelation, pt as Strict, q as Plugin, r as AggregatePaginationResult, rt as RepositoryOperation, s as CacheAdapter, st as SessionOptions, t as AggregateOptions, tt as RepositoryEvent, u as CacheStats, ut as SoftDeleteRepository, v as DeepPartial, vt as UpdateWithValidationResult, w as EventPhase, wt as IController, x as DocField, xt as ValidatorDefinition, y as DeleteManyResult, yt as UserContext, z as NonNullableFields } from "./types-xOyTec4n.mjs";
2
- import { t as index_d_exports } from "./index-C1MzVFsT.mjs";
1
+ import { $ as ReadPreferenceType, A as InferDocument, B as ObjectId, C as EventPayload, Ct as WithTransactionOptions, D as GroupResult, Dt as IResponseFormatter, E as FindOneAndUpdateOptions, Et as IRequestContext, F as Logger, G as PaginationResult, H as OffsetPaginationResult, I as LookupPopulateOptions, J as PluginFunction, K as PartialBy, L as LookupPopulateResult, M as KeysOfType, N as KeysetPaginationOptions, O as HookMode, Ot as LookupBuilder, P as KeysetPaginationResult, Q as ReadOptions, R as MinMaxResult, S as EventHandlers, St as WithPlugins, T as FieldPreset, Tt as IControllerResponse, U as OperationOptions, V as OffsetPaginationOptions, W as PaginationConfig, X as PopulateSpec, Y as PluginType, Z as PrioritizedHook, _ as DecodedCursor, _t as UpdatePatch, a as AnyDocument, at as RequiredBy, b as DeleteResult, bt as ValidationChainOptions, c as CacheOperationOptions, ct as SoftDeleteFilterMode, d as CacheableOptions, dt as SortDirection, et as RepositoryContext, f as CascadeOptions, ft as SortSpec, g as CreateOptions, gt as UpdateOptions, h as CreateInput, ht as UpdateManyResult, i as AllPluginMethods, it as RepositoryOptions, j as InferRawDoc, k as HttpError, kt as LookupOptions, l as CacheOptions, lt as SoftDeleteOptions, m as CollationOptions, mt as UpdateInput, n as AggregatePaginationOptions, nt as RepositoryInstance, o as AnyModel, ot as SelectSpec, p as CascadeRelation, pt as Strict, q as Plugin, r as AggregatePaginationResult, rt as RepositoryOperation, s as CacheAdapter, st as SessionOptions, t as AggregateOptions, tt as RepositoryEvent, u as CacheStats, ut as SoftDeleteRepository, v as DeepPartial, vt as UpdateWithValidationResult, w as EventPhase, wt as IController, x as DocField, xt as ValidatorDefinition, y as DeleteManyResult, yt as UserContext, z as NonNullableFields } from "./types-Dc2aDVUi.mjs";
2
+ import { t as index_d_exports } from "./index-dNTmpgK8.mjs";
3
3
  import { PaginationEngine } from "./pagination/PaginationEngine.mjs";
4
- import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, T as ElasticSearchOptions, U as AuditEntry, V as BulkWriteResult, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "./validation-chain.plugin-BGdr5KRw.mjs";
4
+ import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, T as ElasticSearchOptions, U as AuditEntry, V as BulkWriteResult, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "./validation-chain.plugin-B0VSdcwa.mjs";
5
5
  import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-oM8G4b6m.mjs";
6
6
  import { n as SchemaIndexes } from "./indexes-C26GNZRU.mjs";
7
- import { a as createFieldPreset, c as getMongooseProjection, d as parseDuplicateKeyError, i as configureLogger, l as createError, n as buildCrudSchemasFromMongooseSchema, o as filterResponseData, r as createMemoryCache, s as getFieldsForUser, t as buildCrudSchemasFromModel, u as isDuplicateKeyError } from "./mongooseToJsonSchema-BH6OFec5.mjs";
7
+ import { a as createFieldPreset, c as getMongooseProjection, d as parseDuplicateKeyError, i as configureLogger, l as createError, n as buildCrudSchemasFromMongooseSchema, o as filterResponseData, r as createMemoryCache, s as getFieldsForUser, t as buildCrudSchemasFromModel, u as isDuplicateKeyError } from "./mongooseToJsonSchema-DXxjFkLB.mjs";
8
8
  import * as _$mongoose from "mongoose";
9
9
  import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
10
10
  import { AggPaginationRequest, AggRequest, AggResult, RepositoryBase } from "@classytic/repo-core/repository";
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { r as warn, t as configureLogger } from "./logger-DJ7egMnd.mjs";
2
- import { b as LookupBuilder } from "./update-CWXfFC6O.mjs";
3
- import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-CzYwrfUP.mjs";
2
+ import { b as LookupBuilder } from "./update-DEJYcgfV.mjs";
3
+ import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-B00pI7dV.mjs";
4
4
  import { t as actions_exports } from "./actions/index.mjs";
5
- import { A as AuditTrailQuery, C as cachePlugin, D as withTransaction, E as isTransactionUnsupported, F as MUTATING_OPERATIONS, I as OP_REGISTRY, L as READ_OPERATIONS, M as auditLogPlugin, N as aggregateHelpersPlugin, O as AggregationBuilder, P as ALL_OPERATIONS, R as operationsByPolicyKey, S as cascadePlugin, T as Repository, _ as customIdPlugin, a as uniqueField, b as prefixedId, c as createTenantContext, d as observabilityPlugin, f as multiTenantPlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, j as auditTrailPlugin, k as batchOperationsPlugin, l as subdocumentPlugin, m as methodRegistryPlugin, n as blockIf, o as validationChainPlugin, p as mongoOperationsPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as softDeletePlugin, v as dateSequentialId, w as HOOK_PRIORITY, x as sequentialId, y as getNextSequence } from "./validation-chain.plugin-CLjEFr0c.mjs";
6
- import { t as PaginationEngine } from "./PaginationEngine-B93fLCcO.mjs";
5
+ import { A as AuditTrailQuery, C as cachePlugin, D as withTransaction, E as isTransactionUnsupported, F as MUTATING_OPERATIONS, I as OP_REGISTRY, L as READ_OPERATIONS, M as auditLogPlugin, N as aggregateHelpersPlugin, O as AggregationBuilder, P as ALL_OPERATIONS, R as operationsByPolicyKey, S as cascadePlugin, T as Repository, _ as customIdPlugin, a as uniqueField, b as prefixedId, c as createTenantContext, d as observabilityPlugin, f as multiTenantPlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, j as auditTrailPlugin, k as batchOperationsPlugin, l as subdocumentPlugin, m as methodRegistryPlugin, n as blockIf, o as validationChainPlugin, p as mongoOperationsPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as softDeletePlugin, v as dateSequentialId, w as HOOK_PRIORITY, x as sequentialId, y as getNextSequence } from "./validation-chain.plugin-Dllv-cml.mjs";
6
+ import { t as PaginationEngine } from "./PaginationEngine-CvDFfVXT.mjs";
7
7
  import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
8
8
  import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-dI0m4RBs.mjs";
9
9
  import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
@@ -11,6 +11,20 @@ import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
11
11
  import { n as buildCrudSchemasFromMongooseSchema, r as createMemoryCache, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-D1sdCOmj.mjs";
12
12
  //#region src/query/QueryParser.ts
13
13
  /**
14
+ * Top-level query parameters that mongokit handles outside the filter
15
+ * pipeline. Used by `_handleBracketSyntax` to detect a common typo where a
16
+ * caller wrote `?filters[limit]=5` instead of `?limit=5` and the qs parser
17
+ * nested the key under a filter object — the value is silently dropped
18
+ * without this guard. Kept as a Set for O(1) lookup; values mirror the
19
+ * reserved-key list at the top of `_parseFilters`.
20
+ */
21
+ const RESERVED_PAGINATION_KEYS = new Set([
22
+ "page",
23
+ "limit",
24
+ "sort",
25
+ "select"
26
+ ]);
27
+ /**
14
28
  * Modern Query Parser
15
29
  * Converts URL parameters to MongoDB queries with $lookup support
16
30
  */
@@ -711,6 +725,7 @@ var QueryParser = class {
711
725
  warn(`[mongokit] Nested filter depth exceeds maximum, skipping field: ${field}`);
712
726
  return;
713
727
  }
728
+ for (const op of Object.keys(operators)) if (RESERVED_PAGINATION_KEYS.has(op)) warn(`[mongokit] Nested filter contains reserved key '${op}' at '${field}.${op}' — did you mean ?${op}=... at the top level? The nested value is ignored.`);
714
729
  if (!parsedFilters[field]) parsedFilters[field] = {};
715
730
  for (const [operator, value] of Object.entries(operators)) {
716
731
  if (value === "" || value === null || value === void 0) continue;
@@ -1,21 +1,33 @@
1
- import { T as FieldPreset, k as HttpError, s as CacheAdapter, yt as UserContext } from "./types-xOyTec4n.mjs";
1
+ import { T as FieldPreset, k as HttpError, s as CacheAdapter, yt as UserContext } from "./types-Dc2aDVUi.mjs";
2
2
  import mongoose, { Schema } from "mongoose";
3
3
  import { CrudSchemas, SchemaBuilderOptions } from "@classytic/repo-core/schema";
4
4
 
5
5
  //#region src/utils/error.d.ts
6
+ /** Optional structured fields for createError. */
7
+ interface CreateErrorOptions {
8
+ /** Stable machine-readable code (e.g. `SEARCH_NOT_CONFIGURED`). */
9
+ code?: string;
10
+ /** Diagnostic context — model name, configured modes, doc URL, etc. */
11
+ meta?: Record<string, unknown>;
12
+ }
6
13
  /**
7
- * Creates an error with HTTP status code
14
+ * Creates an error with HTTP status code, plus optional stable `code` /
15
+ * `meta` so callers can `catch` on the code instead of regex-matching the
16
+ * message string.
8
17
  *
9
18
  * @param status - HTTP status code
10
19
  * @param message - Error message
20
+ * @param options - Optional `code` / `meta` for structured handling
11
21
  * @returns Error with status property
12
22
  *
13
23
  * @example
14
24
  * throw createError(404, 'Document not found');
15
- * throw createError(400, 'Invalid input');
16
- * throw createError(403, 'Access denied');
25
+ * throw createError(400, 'Invalid input', {
26
+ * code: 'SEARCH_NOT_CONFIGURED',
27
+ * meta: { model: 'Customer', availableModes: ['text', 'regex', 'auto'] },
28
+ * });
17
29
  */
18
- declare function createError(status: number, message: string): HttpError;
30
+ declare function createError(status: number, message: string, options?: CreateErrorOptions): HttpError;
19
31
  /**
20
32
  * Boolean classifier: true when `err` is an authoritative MongoDB duplicate
21
33
  * key error — and ONLY then. Used by arc's outbox / idempotency adapters to
@@ -171,13 +183,30 @@ declare function configureLogger(config: Partial<LoggerConfig> | false): void;
171
183
  declare function createMemoryCache(maxEntries?: number): CacheAdapter;
172
184
  //#endregion
173
185
  //#region src/utils/mongooseToJsonSchema.d.ts
186
+ /**
187
+ * Return shape for the schema builders. Structurally a `CrudSchemas` plus
188
+ * an `[key: string]: unknown` index signature so the function reference
189
+ * plugs directly into HTTP-framework adapter callbacks typed as
190
+ * `OpenApiSchemas | Record<string, unknown>` (e.g. arc's
191
+ * `MongooseAdapterOptions.schemaGenerator`).
192
+ *
193
+ * `CrudSchemas` itself is intentionally a closed 4-field shape in
194
+ * `@classytic/repo-core/schema` — widening at the kit boundary keeps that
195
+ * contract intact while removing the `as unknown as Record<string, unknown>`
196
+ * cast every arc + mongokit host previously needed at the wiring site.
197
+ *
198
+ * The intersection has zero runtime cost: every `CrudSchemas` value
199
+ * already satisfies `Record<string, unknown>` structurally; TypeScript
200
+ * just refuses the assignment without an explicit declaration.
201
+ */
202
+ type CrudSchemasFramework = CrudSchemas & Record<string, unknown>;
174
203
  /**
175
204
  * Build CRUD schemas from Mongoose schema
176
205
  */
177
- declare function buildCrudSchemasFromMongooseSchema(mongooseSchema: Schema, options?: SchemaBuilderOptions): CrudSchemas;
206
+ declare function buildCrudSchemasFromMongooseSchema(mongooseSchema: Schema, options?: SchemaBuilderOptions): CrudSchemasFramework;
178
207
  /**
179
208
  * Build CRUD schemas from Mongoose model
180
209
  */
181
- declare function buildCrudSchemasFromModel(mongooseModel: mongoose.Model<unknown>, options?: SchemaBuilderOptions): CrudSchemas;
210
+ declare function buildCrudSchemasFromModel(mongooseModel: mongoose.Model<unknown>, options?: SchemaBuilderOptions): CrudSchemasFramework;
182
211
  //#endregion
183
212
  export { createFieldPreset as a, getMongooseProjection as c, parseDuplicateKeyError as d, configureLogger as i, createError as l, buildCrudSchemasFromMongooseSchema as n, filterResponseData as o, createMemoryCache as r, getFieldsForUser as s, buildCrudSchemasFromModel as t, isDuplicateKeyError as u };
@@ -1,4 +1,4 @@
1
- import { H as OffsetPaginationResult, N as KeysetPaginationOptions, P as KeysetPaginationResult, V as OffsetPaginationOptions, W as PaginationConfig, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-xOyTec4n.mjs";
1
+ import { H as OffsetPaginationResult, N as KeysetPaginationOptions, P as KeysetPaginationResult, V as OffsetPaginationOptions, W as PaginationConfig, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-Dc2aDVUi.mjs";
2
2
  import { Model } from "mongoose";
3
3
 
4
4
  //#region src/pagination/PaginationEngine.d.ts
@@ -1,2 +1,2 @@
1
- import { t as PaginationEngine } from "../PaginationEngine-B93fLCcO.mjs";
1
+ import { t as PaginationEngine } from "../PaginationEngine-CvDFfVXT.mjs";
2
2
  export { PaginationEngine };
@@ -1,2 +1,2 @@
1
- import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, S as MethodRegistryRepository, T as ElasticSearchOptions, U as AuditEntry, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "../validation-chain.plugin-BGdr5KRw.mjs";
1
+ import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, S as MethodRegistryRepository, T as ElasticSearchOptions, U as AuditEntry, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "../validation-chain.plugin-B0VSdcwa.mjs";
2
2
  export { type AggregateHelpersMethods, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type CacheMethods, type CustomIdOptions, type DateSequentialIdOptions, type ElasticSearchOptions, type IdGenerator, type MethodRegistryRepository, type MongoOperationsMethods, type MultiTenantOptions, type ObservabilityOptions, type OperationMetric, type PrefixedIdOptions, type SequentialIdOptions, type SoftDeleteMethods, type SubdocumentMethods, type TenantContext, type TenantStore, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
@@ -1,2 +1,2 @@
1
- import { A as AuditTrailQuery, C as cachePlugin, M as auditLogPlugin, N as aggregateHelpersPlugin, S as cascadePlugin, _ as customIdPlugin, a as uniqueField, b as prefixedId, c as createTenantContext, d as observabilityPlugin, f as multiTenantPlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, j as auditTrailPlugin, k as batchOperationsPlugin, l as subdocumentPlugin, m as methodRegistryPlugin, n as blockIf, o as validationChainPlugin, p as mongoOperationsPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as softDeletePlugin, v as dateSequentialId, x as sequentialId, y as getNextSequence } from "../validation-chain.plugin-CLjEFr0c.mjs";
1
+ import { A as AuditTrailQuery, C as cachePlugin, M as auditLogPlugin, N as aggregateHelpersPlugin, S as cascadePlugin, _ as customIdPlugin, a as uniqueField, b as prefixedId, c as createTenantContext, d as observabilityPlugin, f as multiTenantPlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, j as auditTrailPlugin, k as batchOperationsPlugin, l as subdocumentPlugin, m as methodRegistryPlugin, n as blockIf, o as validationChainPlugin, p as mongoOperationsPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as softDeletePlugin, v as dateSequentialId, x as sequentialId, y as getNextSequence } from "../validation-chain.plugin-Dllv-cml.mjs";
2
2
  export { AuditTrailQuery, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
@@ -1352,6 +1352,19 @@ interface CascadeOptions {
1352
1352
  /** HTTP Error with status code */
1353
1353
  interface HttpError extends Error {
1354
1354
  status: number;
1355
+ /**
1356
+ * Stable machine-readable error code. Hosts can switch on this in catch
1357
+ * blocks instead of grepping the message string. Currently emitted for:
1358
+ * - `SEARCH_NOT_CONFIGURED` — search requested on a repo with no text
1359
+ * index AND no `searchMode: 'regex' | 'auto'` + `searchFields` config.
1360
+ */
1361
+ code?: string;
1362
+ /**
1363
+ * Free-form structured metadata for diagnostics. Pairs with `code` so
1364
+ * hosts can render a clearer message in their own UI without parsing
1365
+ * the human-readable `message` string. Safe for logs.
1366
+ */
1367
+ meta?: Record<string, unknown>;
1355
1368
  validationErrors?: Array<{
1356
1369
  validator: string;
1357
1370
  error: string;
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
2
  import { r as warn } from "./logger-DJ7egMnd.mjs";
3
- import { t as createError } from "./error-CzYwrfUP.mjs";
3
+ import { t as createError } from "./error-B00pI7dV.mjs";
4
4
  //#region src/query/LookupBuilder.ts
5
5
  /** Stages that are never valid inside a $lookup pipeline */
6
6
  const BLOCKED_PIPELINE_STAGES = [
@@ -1,5 +1,5 @@
1
- import { X as PopulateSpec, ft as SortSpec, ot as SelectSpec } from "../types-xOyTec4n.mjs";
2
- import { a as createFieldPreset, c as getMongooseProjection, i as configureLogger, l as createError, n as buildCrudSchemasFromMongooseSchema, o as filterResponseData, r as createMemoryCache, s as getFieldsForUser, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-BH6OFec5.mjs";
1
+ import { X as PopulateSpec, ft as SortSpec, ot as SelectSpec } from "../types-Dc2aDVUi.mjs";
2
+ import { a as createFieldPreset, c as getMongooseProjection, i as configureLogger, l as createError, n as buildCrudSchemasFromMongooseSchema, o as filterResponseData, r as createMemoryCache, s as getFieldsForUser, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-DXxjFkLB.mjs";
3
3
 
4
4
  //#region src/utils/cache-keys.d.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { t as configureLogger } from "../logger-DJ7egMnd.mjs";
2
- import { t as createError } from "../error-CzYwrfUP.mjs";
2
+ import { t as createError } from "../error-B00pI7dV.mjs";
3
3
  import { n as isObjectIdInstance, r as isValidIdForType, t as getSchemaIdType } from "../id-resolution-e4BT9zAV.mjs";
4
4
  import { a as byIdKey, c as listQueryKey, i as getMongooseProjection, l as modelPattern, n as filterResponseData, o as byQueryKey, r as getFieldsForUser, s as listPattern, t as createFieldPreset, u as versionKey } from "../field-selection-dI0m4RBs.mjs";
5
5
  import { n as buildCrudSchemasFromMongooseSchema, r as createMemoryCache, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-D1sdCOmj.mjs";
@@ -1,4 +1,4 @@
1
- import { B as ObjectId, F as Logger, H as OffsetPaginationResult, T as FieldPreset, X as PopulateSpec, bt as ValidationChainOptions, et as RepositoryContext, f as CascadeOptions, ft as SortSpec, l as CacheOptions, lt as SoftDeleteOptions, nt as RepositoryInstance, ot as SelectSpec, q as Plugin, u as CacheStats, xt as ValidatorDefinition } from "./types-xOyTec4n.mjs";
1
+ import { B as ObjectId, F as Logger, H as OffsetPaginationResult, T as FieldPreset, X as PopulateSpec, bt as ValidationChainOptions, et as RepositoryContext, f as CascadeOptions, ft as SortSpec, l as CacheOptions, lt as SoftDeleteOptions, nt as RepositoryInstance, ot as SelectSpec, q as Plugin, u as CacheStats, xt as ValidatorDefinition } from "./types-Dc2aDVUi.mjs";
2
2
  import mongoose from "mongoose";
3
3
  import { BulkWriteResult } from "@classytic/repo-core/repository";
4
4
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -1,7 +1,7 @@
1
1
  import { n as debug, r as warn } from "./logger-DJ7egMnd.mjs";
2
- import { _ as upsert, 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, y as distinct } from "./update-CWXfFC6O.mjs";
3
- import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-CzYwrfUP.mjs";
4
- import { t as PaginationEngine } from "./PaginationEngine-B93fLCcO.mjs";
2
+ import { _ as upsert, 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, y as distinct } from "./update-DEJYcgfV.mjs";
3
+ import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-B00pI7dV.mjs";
4
+ import { t as PaginationEngine } from "./PaginationEngine-CvDFfVXT.mjs";
5
5
  import { hasNearOperator, rewriteNearForCount } from "./query/primitives/geo.mjs";
6
6
  import { r as isValidIdForType, t as getSchemaIdType } from "./id-resolution-e4BT9zAV.mjs";
7
7
  import { a as byIdKey, c as listQueryKey, l as modelPattern, o as byQueryKey, r as getFieldsForUser, u as versionKey } from "./field-selection-dI0m4RBs.mjs";
@@ -2892,7 +2892,22 @@ var Repository = class extends RepositoryBase {
2892
2892
  ];
2893
2893
  } else query.$or = orConds;
2894
2894
  } else if (this._hasTextIndex) query.$text = { $search: search };
2895
- else throw createError(400, `No text index found for ${this.model}. Cannot perform text search. Configure Repository with searchMode: 'regex' (and searchFields) or 'auto' to enable index-free search.`);
2895
+ else {
2896
+ const modelName = String(this.model);
2897
+ throw createError(400, `No text index found for ${modelName}. Cannot perform text search. Configure ${modelName}'s Repository with { searchMode: 'regex', searchFields: [...] } to enable index-free search, or create a text index on the collection for searchMode: 'text'. See https://github.com/classytic/mongokit/blob/main/docs/README.md#queryparser-url--filter`, {
2898
+ code: "SEARCH_NOT_CONFIGURED",
2899
+ meta: {
2900
+ model: modelName,
2901
+ configuredMode: this.searchMode,
2902
+ availableModes: [
2903
+ "text",
2904
+ "regex",
2905
+ "auto"
2906
+ ],
2907
+ docs: "https://github.com/classytic/mongokit/blob/main/docs/README.md#queryparser-url--filter"
2908
+ }
2909
+ });
2910
+ }
2896
2911
  return query;
2897
2912
  }
2898
2913
  /**
package/package.json CHANGED
@@ -1,143 +1,143 @@
1
- {
2
- "name": "@classytic/mongokit",
3
- "version": "3.11.0",
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
- "./query/primitives/geo": {
36
- "types": "./dist/query/primitives/geo.d.mts",
37
- "default": "./dist/query/primitives/geo.mjs"
38
- },
39
- "./query/primitives/coercion": {
40
- "types": "./dist/query/primitives/coercion.d.mts",
41
- "default": "./dist/query/primitives/coercion.mjs"
42
- },
43
- "./query/primitives/indexes": {
44
- "types": "./dist/query/primitives/indexes.d.mts",
45
- "default": "./dist/query/primitives/indexes.mjs"
46
- }
47
- },
48
- "files": [
49
- "dist",
50
- "README.md",
51
- "LICENSE"
52
- ],
53
- "keywords": [
54
- "mongodb",
55
- "mongoose",
56
- "repository",
57
- "repository-pattern",
58
- "data-access",
59
- "pagination",
60
- "cursor-pagination",
61
- "infinite-scroll",
62
- "offset-pagination",
63
- "keyset-pagination",
64
- "caching",
65
- "redis",
66
- "cache",
67
- "multi-tenant",
68
- "multi-tenancy",
69
- "vector-search",
70
- "embeddings",
71
- "atlas-search",
72
- "observability",
73
- "event-driven",
74
- "plugin-based",
75
- "zero-dependencies",
76
- "express",
77
- "fastify",
78
- "nestjs",
79
- "nextjs",
80
- "typescript"
81
- ],
82
- "author": "Classytic <classytic.dev@gmail.com> (https://github.com/classytic)",
83
- "contributors": [
84
- "Sadman Chowdhury (https://github.com/siam923)"
85
- ],
86
- "license": "MIT",
87
- "repository": {
88
- "type": "git",
89
- "url": "git+https://github.com/classytic/mongokit.git"
90
- },
91
- "bugs": {
92
- "url": "https://github.com/classytic/mongokit/issues"
93
- },
94
- "homepage": "https://github.com/classytic/mongokit#readme",
95
- "peerDependencies": {
96
- "mongoose": ">=9.4.1",
97
- "@classytic/repo-core": ">=0.2.0"
98
- },
99
- "engines": {
100
- "node": ">=22"
101
- },
102
- "scripts": {
103
- "build": "tsdown",
104
- "dev": "tsdown --watch",
105
- "test": "vitest run --project unit --project integration",
106
- "test:unit": "vitest run --project unit",
107
- "test:integration": "vitest run --project integration",
108
- "test:e2e": "vitest run --project e2e",
109
- "test:all": "vitest run --project unit --project integration --project e2e",
110
- "test:watch": "vitest --project unit --project integration",
111
- "test:coverage": "vitest run --coverage",
112
- "typecheck": "tsc --noEmit",
113
- "typecheck:tests": "tsc --noEmit -p tsconfig.tests.json",
114
- "lint": "biome check src/",
115
- "lint:fix": "biome check src/ --write",
116
- "format": "biome format src/ --write",
117
- "check": "biome ci src/ --diagnostic-level=error",
118
- "prepublishOnly": "npm run check && npm run build && npm run typecheck && npm run typecheck:tests && npm test",
119
- "publish:dry": "npm publish --dry-run --access public",
120
- "publish:npm": "npm publish --access public",
121
- "release": "npm run check && npm run build && npm run typecheck && npm run typecheck:tests && npm test && npm publish --access public",
122
- "release:patch": "npm version patch && npm run release",
123
- "release:minor": "npm version minor && npm run release",
124
- "release:major": "npm version major && npm run release"
125
- },
126
- "devDependencies": {
127
- "@arethetypeswrong/cli": "^0.18.2",
128
- "@biomejs/biome": "^2.4.10",
129
- "@classytic/repo-core": ">=0.1.0",
130
- "@types/node": "^22.0.0",
131
- "@vitest/coverage-v8": "^3.2.4",
132
- "ajv": "^8.18.0",
133
- "ajv-formats": "^3.0.1",
134
- "dotenv": "^17.4.2",
135
- "knip": "^6.3.0",
136
- "mongodb-memory-server": "^10.4.3",
137
- "mongoose": "^9.4.1",
138
- "publint": "^0.3.18",
139
- "tsdown": "^0.21.8",
140
- "typescript": "^5.7.0",
141
- "vitest": "^3.2.4"
142
- }
143
- }
1
+ {
2
+ "name": "@classytic/mongokit",
3
+ "version": "3.11.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
+ "./query/primitives/geo": {
36
+ "types": "./dist/query/primitives/geo.d.mts",
37
+ "default": "./dist/query/primitives/geo.mjs"
38
+ },
39
+ "./query/primitives/coercion": {
40
+ "types": "./dist/query/primitives/coercion.d.mts",
41
+ "default": "./dist/query/primitives/coercion.mjs"
42
+ },
43
+ "./query/primitives/indexes": {
44
+ "types": "./dist/query/primitives/indexes.d.mts",
45
+ "default": "./dist/query/primitives/indexes.mjs"
46
+ }
47
+ },
48
+ "files": [
49
+ "dist",
50
+ "README.md",
51
+ "LICENSE"
52
+ ],
53
+ "keywords": [
54
+ "mongodb",
55
+ "mongoose",
56
+ "repository",
57
+ "repository-pattern",
58
+ "data-access",
59
+ "pagination",
60
+ "cursor-pagination",
61
+ "infinite-scroll",
62
+ "offset-pagination",
63
+ "keyset-pagination",
64
+ "caching",
65
+ "redis",
66
+ "cache",
67
+ "multi-tenant",
68
+ "multi-tenancy",
69
+ "vector-search",
70
+ "embeddings",
71
+ "atlas-search",
72
+ "observability",
73
+ "event-driven",
74
+ "plugin-based",
75
+ "zero-dependencies",
76
+ "express",
77
+ "fastify",
78
+ "nestjs",
79
+ "nextjs",
80
+ "typescript"
81
+ ],
82
+ "author": "Classytic <classytic.dev@gmail.com> (https://github.com/classytic)",
83
+ "contributors": [
84
+ "Sadman Chowdhury (https://github.com/siam923)"
85
+ ],
86
+ "license": "MIT",
87
+ "repository": {
88
+ "type": "git",
89
+ "url": "git+https://github.com/classytic/mongokit.git"
90
+ },
91
+ "bugs": {
92
+ "url": "https://github.com/classytic/mongokit/issues"
93
+ },
94
+ "homepage": "https://github.com/classytic/mongokit#readme",
95
+ "peerDependencies": {
96
+ "mongoose": ">=9.4.1",
97
+ "@classytic/repo-core": ">=0.2.0"
98
+ },
99
+ "engines": {
100
+ "node": ">=22"
101
+ },
102
+ "scripts": {
103
+ "build": "tsdown",
104
+ "dev": "tsdown --watch",
105
+ "test": "vitest run --project unit --project integration",
106
+ "test:unit": "vitest run --project unit",
107
+ "test:integration": "vitest run --project integration",
108
+ "test:e2e": "vitest run --project e2e",
109
+ "test:all": "vitest run --project unit --project integration --project e2e",
110
+ "test:watch": "vitest --project unit --project integration",
111
+ "test:coverage": "vitest run --coverage",
112
+ "typecheck": "tsc --noEmit",
113
+ "typecheck:tests": "tsc --noEmit -p tsconfig.tests.json",
114
+ "lint": "biome check src/",
115
+ "lint:fix": "biome check src/ --write",
116
+ "format": "biome format src/ --write",
117
+ "check": "biome ci src/ --diagnostic-level=error",
118
+ "prepublishOnly": "npm run check && npm run build && npm run typecheck && npm run typecheck:tests && npm test",
119
+ "publish:dry": "npm publish --dry-run --access public",
120
+ "publish:npm": "npm publish --access public",
121
+ "release": "npm run check && npm run build && npm run typecheck && npm run typecheck:tests && npm test && npm publish --access public",
122
+ "release:patch": "npm version patch && npm run release",
123
+ "release:minor": "npm version minor && npm run release",
124
+ "release:major": "npm version major && npm run release"
125
+ },
126
+ "devDependencies": {
127
+ "@arethetypeswrong/cli": "^0.18.2",
128
+ "@biomejs/biome": "^2.4.10",
129
+ "@classytic/repo-core": ">=0.2.0",
130
+ "@types/node": "^22.0.0",
131
+ "@vitest/coverage-v8": "^3.2.4",
132
+ "ajv": "^8.18.0",
133
+ "ajv-formats": "^3.0.1",
134
+ "dotenv": "^17.4.2",
135
+ "knip": "^6.3.0",
136
+ "mongodb-memory-server": "^10.4.3",
137
+ "mongoose": "^9.4.1",
138
+ "publint": "^0.3.18",
139
+ "tsdown": "^0.21.8",
140
+ "typescript": "^5.7.0",
141
+ "vitest": "^3.2.4"
142
+ }
143
+ }