@classytic/mongokit 3.5.4 → 3.5.6
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 +228 -9
- package/dist/{PaginationEngine-DCs-zKwZ.mjs → PaginationEngine-CpsQl471.mjs} +5 -3
- package/dist/actions/index.d.mts +1 -1
- package/dist/ai/index.d.mts +1 -1
- package/dist/coercion-B19MD38s.d.mts +106 -0
- package/dist/id-resolution-LZ-cCwR5.mjs +81 -0
- package/dist/{index-BNpVzw_-.d.mts → index-DmVbUzDL.d.mts} +1 -1
- package/dist/index.d.mts +84 -6
- package/dist/index.mjs +101 -36
- package/dist/indexes-qIBCZ3mY.d.mts +41 -0
- package/dist/{mongooseToJsonSchema-DpjhFfaO.mjs → mongooseToJsonSchema-8Cyu3NFJ.mjs} +50 -45
- package/dist/{mongooseToJsonSchema-Dsx3YAAx.d.mts → mongooseToJsonSchema-DQMU0Dlv.d.mts} +4 -3
- package/dist/pagination/PaginationEngine.d.mts +1 -1
- package/dist/pagination/PaginationEngine.mjs +1 -1
- package/dist/plugins/index.d.mts +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/query/primitives/coercion.d.mts +2 -0
- package/dist/query/primitives/coercion.mjs +148 -0
- package/dist/query/primitives/geo.d.mts +116 -0
- package/dist/query/primitives/geo.mjs +211 -0
- package/dist/query/primitives/indexes.d.mts +2 -0
- package/dist/query/primitives/indexes.mjs +46 -0
- package/dist/{types-CkE3mOaW.d.mts → types-BwO4u3JN.d.mts} +25 -0
- package/dist/utils/index.d.mts +60 -3
- package/dist/utils/index.mjs +4 -3
- package/dist/{validation-chain.plugin-BYMZB8dN.d.mts → validation-chain.plugin-BtmT-FFB.d.mts} +1 -1
- package/dist/{validation-chain.plugin-KjPV_6_N.mjs → validation-chain.plugin-DCYjnPau.mjs} +81 -20
- package/package.json +15 -3
- /package/dist/{field-selection-reyDRzXf.mjs → field-selection-C5o7jyyA.mjs} +0 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { $ as ReadPreferenceType, A as InferDocument, At as LookupOptions, B as NonNullableFields, C as EventPayload, Ct as WithPlugins, D as GroupResult, Dt as IRequestContext, E as FieldRules, Et as IControllerResponse, F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, I as Logger, J as Plugin, K as PaginationResult, L as LookupPopulateOptions, M as JsonSchema, N as KeysOfType, O as HookMode, Ot as IResponseFormatter, P as KeysetPaginationOptions, Q as ReadOptions, R as LookupPopulateResult, S as EventHandlers, St as ValidatorDefinition, T as FieldPreset, Tt as IController, U as OffsetPaginationResult, V as ObjectId, W as OperationOptions, X as PluginType, Y as PluginFunction, Z as PopulateSpec, _ as CrudSchemas, _t as UpdateOptions, a as AnyDocument, at as RequiredBy, b as DeleteResult, bt as ValidationChainOptions, c as CacheOperationOptions, ct as SessionOptions, d as CacheableOptions, dt as SoftDeleteRepository, et as RepositoryContext, f as CascadeOptions, ft as SortDirection, g as CreateOptions, gt as UpdateManyResult, h as CreateInput, ht as UpdateInput, i as AllPluginMethods, it as RepositoryOptions, j as InferRawDoc, k as HttpError, kt as LookupBuilder, l as CacheOptions, lt as SoftDeleteFilterMode, m as CollationOptions, mt as Strict, n as AggregatePaginationOptions, nt as RepositoryInstance, o as AnyModel, ot as SchemaBuilderOptions, p as CascadeRelation, pt as SortSpec, q as PartialBy, r as AggregatePaginationResult, rt as RepositoryOperation, s as CacheAdapter, st as SelectSpec, t as AggregateOptions, tt as RepositoryEvent, u as CacheStats, ut as SoftDeleteOptions, v as DecodedCursor, vt as UpdateWithValidationResult, w as EventPhase, wt as WithTransactionOptions, x as DocField, xt as ValidationResult, y as DeepPartial, yt as UserContext, z as MinMaxResult } from "./types-
|
|
2
|
-
import { t as index_d_exports } from "./index-
|
|
1
|
+
import { $ as ReadPreferenceType, A as InferDocument, At as LookupOptions, B as NonNullableFields, C as EventPayload, Ct as WithPlugins, D as GroupResult, Dt as IRequestContext, E as FieldRules, Et as IControllerResponse, F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, I as Logger, J as Plugin, K as PaginationResult, L as LookupPopulateOptions, M as JsonSchema, N as KeysOfType, O as HookMode, Ot as IResponseFormatter, P as KeysetPaginationOptions, Q as ReadOptions, R as LookupPopulateResult, S as EventHandlers, St as ValidatorDefinition, T as FieldPreset, Tt as IController, U as OffsetPaginationResult, V as ObjectId, W as OperationOptions, X as PluginType, Y as PluginFunction, Z as PopulateSpec, _ as CrudSchemas, _t as UpdateOptions, a as AnyDocument, at as RequiredBy, b as DeleteResult, bt as ValidationChainOptions, c as CacheOperationOptions, ct as SessionOptions, d as CacheableOptions, dt as SoftDeleteRepository, et as RepositoryContext, f as CascadeOptions, ft as SortDirection, g as CreateOptions, gt as UpdateManyResult, h as CreateInput, ht as UpdateInput, i as AllPluginMethods, it as RepositoryOptions, j as InferRawDoc, k as HttpError, kt as LookupBuilder, l as CacheOptions, lt as SoftDeleteFilterMode, m as CollationOptions, mt as Strict, n as AggregatePaginationOptions, nt as RepositoryInstance, o as AnyModel, ot as SchemaBuilderOptions, p as CascadeRelation, pt as SortSpec, q as PartialBy, r as AggregatePaginationResult, rt as RepositoryOperation, s as CacheAdapter, st as SelectSpec, t as AggregateOptions, tt as RepositoryEvent, u as CacheStats, ut as SoftDeleteOptions, v as DecodedCursor, vt as UpdateWithValidationResult, w as EventPhase, wt as WithTransactionOptions, x as DocField, xt as ValidationResult, y as DeepPartial, yt as UserContext, z as MinMaxResult } from "./types-BwO4u3JN.mjs";
|
|
2
|
+
import { t as index_d_exports } from "./index-DmVbUzDL.mjs";
|
|
3
3
|
import { PaginationEngine } from "./pagination/PaginationEngine.mjs";
|
|
4
|
-
import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, R as BulkWriteResult, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, z as batchOperationsPlugin } from "./validation-chain.plugin-
|
|
5
|
-
import {
|
|
4
|
+
import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, R as BulkWriteResult, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, z as batchOperationsPlugin } from "./validation-chain.plugin-BtmT-FFB.mjs";
|
|
5
|
+
import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-B19MD38s.mjs";
|
|
6
|
+
import { n as SchemaIndexes } from "./indexes-qIBCZ3mY.mjs";
|
|
7
|
+
import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, m as parseDuplicateKeyError, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "./mongooseToJsonSchema-DQMU0Dlv.mjs";
|
|
6
8
|
import * as _$mongoose from "mongoose";
|
|
7
9
|
import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
|
|
8
10
|
|
|
@@ -487,6 +489,22 @@ interface ParsedQuery {
|
|
|
487
489
|
}
|
|
488
490
|
/** Search mode for query parser */
|
|
489
491
|
type SearchMode = 'text' | 'regex';
|
|
492
|
+
/**
|
|
493
|
+
* Normalized field type used for schema-aware value coercion. Re-exported
|
|
494
|
+
* from `primitives/coercion` so the public QueryParser API stays unchanged
|
|
495
|
+
* while the actual logic lives in a single, unit-tested primitive module.
|
|
496
|
+
*/
|
|
497
|
+
type FieldType = FieldType$1;
|
|
498
|
+
/**
|
|
499
|
+
* Minimal structural type for a Mongoose schema. We only read `.paths` and
|
|
500
|
+
* (optionally) `.indexes()`, so the parser stays decoupled from a specific
|
|
501
|
+
* Mongoose major version and is easy to mock in tests. Re-exported from the
|
|
502
|
+
* primitives module — the canonical definition lives there.
|
|
503
|
+
*/
|
|
504
|
+
interface SchemaLike extends SchemaPathsLike {
|
|
505
|
+
/** Optional — when present, schema indexes are introspected for geo/text fields */
|
|
506
|
+
indexes?: () => Array<[Record<string, unknown>, Record<string, unknown>?]>;
|
|
507
|
+
}
|
|
490
508
|
interface QueryParserOptions {
|
|
491
509
|
/** Maximum allowed regex pattern length (default: 500) */
|
|
492
510
|
maxRegexLength?: number;
|
|
@@ -534,6 +552,25 @@ interface QueryParserOptions {
|
|
|
534
552
|
* @example ['eq', 'ne', 'gt', 'gte', 'lt', 'lte', 'in']
|
|
535
553
|
*/
|
|
536
554
|
allowedOperators?: string[];
|
|
555
|
+
/**
|
|
556
|
+
* Mongoose schema (or schema-like object exposing `.paths`) used for
|
|
557
|
+
* authoritative, schema-aware value coercion. When provided, filter values
|
|
558
|
+
* are coerced to the declared field type instead of guessed from the
|
|
559
|
+
* string shape — `?stock=50` becomes a number against a `Number` field but
|
|
560
|
+
* `?name=12345` stays a string against a `String` field. Nested paths like
|
|
561
|
+
* `address.zip` are looked up via dot-notation, matching Mongoose's
|
|
562
|
+
* `schema.paths` reflection. Unknown fields fall through to the heuristic.
|
|
563
|
+
*/
|
|
564
|
+
schema?: SchemaLike;
|
|
565
|
+
/**
|
|
566
|
+
* Plain field-type map used for authoritative coercion when no Mongoose
|
|
567
|
+
* schema is available (raw MongoDB, Prisma, computed fields, upstream
|
|
568
|
+
* models you don't own). Takes precedence over `schema` for paths declared
|
|
569
|
+
* in both — useful for runtime overrides. Use dot-notation for nested
|
|
570
|
+
* paths (`'address.zip': 'string'`).
|
|
571
|
+
* @example { stock: 'number', active: 'boolean', releasedAt: 'date' }
|
|
572
|
+
*/
|
|
573
|
+
fieldTypes?: Record<string, FieldType>;
|
|
537
574
|
}
|
|
538
575
|
/**
|
|
539
576
|
* Modern Query Parser
|
|
@@ -543,6 +580,21 @@ declare class QueryParser {
|
|
|
543
580
|
private readonly options;
|
|
544
581
|
private readonly operators;
|
|
545
582
|
private readonly dangerousOperators;
|
|
583
|
+
/**
|
|
584
|
+
* Normalized dot-notation field-type map. Built once at construction from
|
|
585
|
+
* `options.schema` (Mongoose) and `options.fieldTypes` (override map), with
|
|
586
|
+
* `fieldTypes` taking precedence. An empty map means schema-aware coercion
|
|
587
|
+
* is disabled and the heuristic in `_convertValue` runs unchanged — this
|
|
588
|
+
* preserves backwards compatibility for callers that don't opt in.
|
|
589
|
+
*/
|
|
590
|
+
private readonly _fieldTypes;
|
|
591
|
+
/**
|
|
592
|
+
* Structured schema-index info (geo / text / other), built once from
|
|
593
|
+
* `options.schema?.indexes()`. Used by the operator router to validate
|
|
594
|
+
* geo operators against actual geo-indexed fields, and exposed publicly
|
|
595
|
+
* via `parser.schemaIndexes` for downstream tools (Arc MCP, query planners).
|
|
596
|
+
*/
|
|
597
|
+
private readonly _schemaIndexes;
|
|
546
598
|
/**
|
|
547
599
|
* Regex patterns that can cause catastrophic backtracking (ReDoS attacks)
|
|
548
600
|
* Detects:
|
|
@@ -554,6 +606,16 @@ declare class QueryParser {
|
|
|
554
606
|
*/
|
|
555
607
|
private readonly dangerousRegexPatterns;
|
|
556
608
|
constructor(options?: QueryParserOptions);
|
|
609
|
+
/**
|
|
610
|
+
* Structured view of the configured schema's indexes — geo fields, text
|
|
611
|
+
* fields, and other compound indexes. Empty arrays when no schema was
|
|
612
|
+
* provided. Stable across the parser's lifetime; mutating the returned
|
|
613
|
+
* object does not affect parser behavior.
|
|
614
|
+
*
|
|
615
|
+
* Useful for downstream tooling (Arc MCP, query planners, doc generators)
|
|
616
|
+
* that needs to know which fields support which query types.
|
|
617
|
+
*/
|
|
618
|
+
get schemaIndexes(): SchemaIndexes;
|
|
557
619
|
/**
|
|
558
620
|
* Get the configured allowed filter fields.
|
|
559
621
|
* Returns `undefined` if no whitelist is set (all fields allowed).
|
|
@@ -738,7 +800,6 @@ declare class QueryParser {
|
|
|
738
800
|
* // ]
|
|
739
801
|
*/
|
|
740
802
|
private _buildRegexSearch;
|
|
741
|
-
private _convertValue;
|
|
742
803
|
private _parseOr;
|
|
743
804
|
private _enhanceWithBetween;
|
|
744
805
|
private _pluralize;
|
|
@@ -774,6 +835,8 @@ declare class Repository<TDoc = unknown> {
|
|
|
774
835
|
readonly _pagination: PaginationEngine<TDoc>;
|
|
775
836
|
private readonly _hookMode;
|
|
776
837
|
readonly idField: string;
|
|
838
|
+
readonly searchMode: 'text' | 'regex' | 'auto';
|
|
839
|
+
readonly searchFields: string[] | undefined;
|
|
777
840
|
[key: string]: unknown;
|
|
778
841
|
private _hasTextIndex;
|
|
779
842
|
constructor(Model: Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions);
|
|
@@ -1048,6 +1111,21 @@ declare class Repository<TDoc = unknown> {
|
|
|
1048
1111
|
* 4. DEFAULT (500) — user-registered hooks
|
|
1049
1112
|
*/
|
|
1050
1113
|
_buildContext(operation: string, options: Record<string, unknown> | object): Promise<RepositoryContext>;
|
|
1114
|
+
/**
|
|
1115
|
+
* Resolve the effective sort for getAll. Handles $near conflict detection
|
|
1116
|
+
* (warns + drops explicit sort when $near is in filters).
|
|
1117
|
+
*/
|
|
1118
|
+
private _resolveSort;
|
|
1119
|
+
/**
|
|
1120
|
+
* Detect whether to use keyset (cursor) or offset (page) pagination.
|
|
1121
|
+
*/
|
|
1122
|
+
private _detectPaginationMode;
|
|
1123
|
+
/**
|
|
1124
|
+
* Build the MongoDB query filter with search merged in. Handles text
|
|
1125
|
+
* search ($text), regex search ($or of $regex), and the search-resolver
|
|
1126
|
+
* plugin contract (search already cleared by a before:getAll hook).
|
|
1127
|
+
*/
|
|
1128
|
+
private _buildSearchQuery;
|
|
1051
1129
|
/**
|
|
1052
1130
|
* Parse sort string or object
|
|
1053
1131
|
*/
|
|
@@ -1075,4 +1153,4 @@ declare class Repository<TDoc = unknown> {
|
|
|
1075
1153
|
*/
|
|
1076
1154
|
declare function createRepository<TDoc>(Model: _$mongoose.Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions): Repository<TDoc>;
|
|
1077
1155
|
//#endregion
|
|
1078
|
-
export { type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, type FilterQuery, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type JsonSchema, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidationResult, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin };
|
|
1156
|
+
export { type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, type FieldType, type FilterQuery, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type JsonSchema, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidationResult, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { a as warn, n as parseDuplicateKeyError, r as configureLogger, t as createError } from "./error-Bpbi_NKo.mjs";
|
|
2
2
|
import { y as LookupBuilder } from "./update-AVfKWNGt.mjs";
|
|
3
3
|
import { t as actions_exports } from "./actions/index.mjs";
|
|
4
|
-
import { t as PaginationEngine } from "./PaginationEngine-
|
|
5
|
-
import { A as aggregateHelpersPlugin, C as HOOK_PRIORITY, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, T as AggregationBuilder, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, w as Repository, x as cascadePlugin, y as prefixedId } from "./validation-chain.plugin-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
4
|
+
import { t as PaginationEngine } from "./PaginationEngine-CpsQl471.mjs";
|
|
5
|
+
import { A as aggregateHelpersPlugin, C as HOOK_PRIORITY, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, T as AggregationBuilder, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, w as Repository, x as cascadePlugin, y as prefixedId } from "./validation-chain.plugin-DCYjnPau.mjs";
|
|
6
|
+
import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
|
|
7
|
+
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-C5o7jyyA.mjs";
|
|
8
|
+
import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
|
|
9
|
+
import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
|
|
10
|
+
import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-8Cyu3NFJ.mjs";
|
|
9
11
|
//#region src/query/QueryParser.ts
|
|
10
12
|
/**
|
|
11
13
|
* Modern Query Parser
|
|
@@ -31,6 +33,21 @@ var QueryParser = class {
|
|
|
31
33
|
};
|
|
32
34
|
dangerousOperators;
|
|
33
35
|
/**
|
|
36
|
+
* Normalized dot-notation field-type map. Built once at construction from
|
|
37
|
+
* `options.schema` (Mongoose) and `options.fieldTypes` (override map), with
|
|
38
|
+
* `fieldTypes` taking precedence. An empty map means schema-aware coercion
|
|
39
|
+
* is disabled and the heuristic in `_convertValue` runs unchanged — this
|
|
40
|
+
* preserves backwards compatibility for callers that don't opt in.
|
|
41
|
+
*/
|
|
42
|
+
_fieldTypes;
|
|
43
|
+
/**
|
|
44
|
+
* Structured schema-index info (geo / text / other), built once from
|
|
45
|
+
* `options.schema?.indexes()`. Used by the operator router to validate
|
|
46
|
+
* geo operators against actual geo-indexed fields, and exposed publicly
|
|
47
|
+
* via `parser.schemaIndexes` for downstream tools (Arc MCP, query planners).
|
|
48
|
+
*/
|
|
49
|
+
_schemaIndexes;
|
|
50
|
+
/**
|
|
34
51
|
* Regex patterns that can cause catastrophic backtracking (ReDoS attacks)
|
|
35
52
|
* Detects:
|
|
36
53
|
* - Quantifiers: {n,m}
|
|
@@ -67,6 +84,20 @@ var QueryParser = class {
|
|
|
67
84
|
"$expr",
|
|
68
85
|
...this.options.additionalDangerousOperators
|
|
69
86
|
];
|
|
87
|
+
this._fieldTypes = buildFieldTypeMap(options.schema, options.fieldTypes);
|
|
88
|
+
this._schemaIndexes = extractSchemaIndexes(options.schema);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Structured view of the configured schema's indexes — geo fields, text
|
|
92
|
+
* fields, and other compound indexes. Empty arrays when no schema was
|
|
93
|
+
* provided. Stable across the parser's lifetime; mutating the returned
|
|
94
|
+
* object does not affect parser behavior.
|
|
95
|
+
*
|
|
96
|
+
* Useful for downstream tooling (Arc MCP, query planners, doc generators)
|
|
97
|
+
* that needs to know which fields support which query types.
|
|
98
|
+
*/
|
|
99
|
+
get schemaIndexes() {
|
|
100
|
+
return this._schemaIndexes;
|
|
70
101
|
}
|
|
71
102
|
/**
|
|
72
103
|
* Get the configured allowed filter fields.
|
|
@@ -520,7 +551,7 @@ var QueryParser = class {
|
|
|
520
551
|
*/
|
|
521
552
|
_convertPopulateMatch(match) {
|
|
522
553
|
const converted = {};
|
|
523
|
-
for (const [key, value] of Object.entries(match)) converted[key] =
|
|
554
|
+
for (const [key, value] of Object.entries(match)) converted[key] = coerceHeuristic(value);
|
|
524
555
|
return converted;
|
|
525
556
|
}
|
|
526
557
|
/**
|
|
@@ -569,7 +600,7 @@ var QueryParser = class {
|
|
|
569
600
|
continue;
|
|
570
601
|
}
|
|
571
602
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) this._handleBracketSyntax(key, value, parsedFilters, depth + 1);
|
|
572
|
-
else parsedFilters[key] = this.
|
|
603
|
+
else parsedFilters[key] = coerceFieldValue(key, value, this._fieldTypes);
|
|
573
604
|
}
|
|
574
605
|
return parsedFilters;
|
|
575
606
|
}
|
|
@@ -597,12 +628,18 @@ var QueryParser = class {
|
|
|
597
628
|
}
|
|
598
629
|
return;
|
|
599
630
|
}
|
|
631
|
+
if (isGeoOperator(operator)) {
|
|
632
|
+
const geoFilter = parseGeoFilter(operator, value);
|
|
633
|
+
if (geoFilter) filters[field] = geoFilter;
|
|
634
|
+
else warn(`[mongokit] Invalid geo operator value for ${field}[${operator}]; dropping filter`);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
600
637
|
const mongoOperator = this._toMongoOperator(operator);
|
|
601
638
|
if (this.dangerousOperators.includes(mongoOperator)) {
|
|
602
639
|
warn(`[mongokit] Blocked dangerous operator: ${mongoOperator}`);
|
|
603
640
|
return;
|
|
604
641
|
}
|
|
605
|
-
if (mongoOperator === "$eq") filters[field] = value;
|
|
642
|
+
if (mongoOperator === "$eq") filters[field] = coerceFieldValue(field, value, this._fieldTypes);
|
|
606
643
|
else if (mongoOperator === "$regex") {
|
|
607
644
|
const safeRegex = this._createSafeRegex(value);
|
|
608
645
|
if (safeRegex) {
|
|
@@ -612,17 +649,23 @@ var QueryParser = class {
|
|
|
612
649
|
} else {
|
|
613
650
|
let processedValue;
|
|
614
651
|
const op = operator.toLowerCase();
|
|
615
|
-
if (
|
|
652
|
+
if (op === "size") {
|
|
653
|
+
processedValue = parseFloat(String(value));
|
|
654
|
+
if (Number.isNaN(processedValue)) return;
|
|
655
|
+
} else if ([
|
|
616
656
|
"gt",
|
|
617
657
|
"gte",
|
|
618
658
|
"lt",
|
|
619
|
-
"lte"
|
|
620
|
-
|
|
621
|
-
|
|
659
|
+
"lte"
|
|
660
|
+
].includes(op)) if (this._fieldTypes.has(field)) {
|
|
661
|
+
processedValue = coerceFieldValue(field, value, this._fieldTypes);
|
|
662
|
+
if (typeof processedValue === "number" && Number.isNaN(processedValue)) return;
|
|
663
|
+
} else {
|
|
622
664
|
processedValue = parseFloat(String(value));
|
|
623
665
|
if (Number.isNaN(processedValue)) return;
|
|
624
|
-
}
|
|
625
|
-
else processedValue =
|
|
666
|
+
}
|
|
667
|
+
else if (op === "in" || op === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, this._fieldTypes));
|
|
668
|
+
else processedValue = coerceFieldValue(field, value, this._fieldTypes);
|
|
626
669
|
if (typeof filters[field] !== "object" || filters[field] === null || Array.isArray(filters[field])) filters[field] = {};
|
|
627
670
|
filters[field][mongoOperator] = processedValue;
|
|
628
671
|
}
|
|
@@ -642,6 +685,15 @@ var QueryParser = class {
|
|
|
642
685
|
parsedFilters[field].between = value;
|
|
643
686
|
continue;
|
|
644
687
|
}
|
|
688
|
+
if (isGeoOperator(operator)) {
|
|
689
|
+
const geoFilter = parseGeoFilter(operator, value);
|
|
690
|
+
if (geoFilter) parsedFilters[field] = geoFilter;
|
|
691
|
+
else {
|
|
692
|
+
warn(`[mongokit] Invalid geo operator value for ${field}[${operator}]; dropping filter`);
|
|
693
|
+
delete parsedFilters[field];
|
|
694
|
+
}
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
645
697
|
if (this.options.allowedOperators && !this.options.allowedOperators.includes(operator)) {
|
|
646
698
|
warn(`[mongokit] Operator not in allowlist: ${operator}`);
|
|
647
699
|
continue;
|
|
@@ -649,21 +701,27 @@ var QueryParser = class {
|
|
|
649
701
|
if (this.operators[operator]) {
|
|
650
702
|
const mongoOperator = this.operators[operator];
|
|
651
703
|
let processedValue;
|
|
652
|
-
if (
|
|
704
|
+
if (operator === "size") {
|
|
705
|
+
processedValue = parseFloat(String(value));
|
|
706
|
+
if (Number.isNaN(processedValue)) continue;
|
|
707
|
+
} else if ([
|
|
653
708
|
"gt",
|
|
654
709
|
"gte",
|
|
655
710
|
"lt",
|
|
656
|
-
"lte"
|
|
657
|
-
|
|
658
|
-
|
|
711
|
+
"lte"
|
|
712
|
+
].includes(operator)) if (this._fieldTypes.has(field)) {
|
|
713
|
+
processedValue = coerceFieldValue(field, value, this._fieldTypes);
|
|
714
|
+
if (typeof processedValue === "number" && Number.isNaN(processedValue)) continue;
|
|
715
|
+
} else {
|
|
659
716
|
processedValue = parseFloat(String(value));
|
|
660
717
|
if (Number.isNaN(processedValue)) continue;
|
|
661
|
-
}
|
|
718
|
+
}
|
|
719
|
+
else if (operator === "in" || operator === "nin") processedValue = (Array.isArray(value) ? value : String(value).split(",").map((v) => v.trim())).map((elem) => coerceFieldValue(field, elem, this._fieldTypes));
|
|
662
720
|
else if (operator === "like" || operator === "contains" || operator === "regex") {
|
|
663
721
|
const safeRegex = this._createSafeRegex(value);
|
|
664
722
|
if (!safeRegex) continue;
|
|
665
723
|
processedValue = safeRegex;
|
|
666
|
-
} else processedValue = this.
|
|
724
|
+
} else processedValue = coerceFieldValue(field, value, this._fieldTypes);
|
|
667
725
|
parsedFilters[field][mongoOperator] = processedValue;
|
|
668
726
|
}
|
|
669
727
|
}
|
|
@@ -727,17 +785,31 @@ var QueryParser = class {
|
|
|
727
785
|
*/
|
|
728
786
|
_sanitizeMatchConfig(config) {
|
|
729
787
|
const sanitized = {};
|
|
788
|
+
const logicalArrayOps = new Set([
|
|
789
|
+
"$or",
|
|
790
|
+
"$and",
|
|
791
|
+
"$nor"
|
|
792
|
+
]);
|
|
730
793
|
for (const [key, value] of Object.entries(config)) {
|
|
731
794
|
if (this.dangerousOperators.includes(key)) {
|
|
732
795
|
warn(`[mongokit] Blocked dangerous operator in aggregation: ${key}`);
|
|
733
796
|
continue;
|
|
734
797
|
}
|
|
735
798
|
if (value && typeof value === "object" && !Array.isArray(value)) sanitized[key] = this._sanitizeMatchConfig(value);
|
|
736
|
-
else if (Array.isArray(value))
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
799
|
+
else if (Array.isArray(value)) {
|
|
800
|
+
const sanitizedArray = value.map((item) => {
|
|
801
|
+
if (item && typeof item === "object" && !Array.isArray(item)) return this._sanitizeMatchConfig(item);
|
|
802
|
+
return item;
|
|
803
|
+
});
|
|
804
|
+
if (logicalArrayOps.has(key)) {
|
|
805
|
+
const filtered = sanitizedArray.filter((item) => !(item && typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0));
|
|
806
|
+
if (filtered.length === 0) {
|
|
807
|
+
warn(`[mongokit] All branches of ${key} were blocked by sanitization; dropping the operator`);
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
sanitized[key] = filtered;
|
|
811
|
+
} else sanitized[key] = sanitizedArray;
|
|
812
|
+
} else sanitized[key] = value;
|
|
741
813
|
}
|
|
742
814
|
return sanitized;
|
|
743
815
|
}
|
|
@@ -822,22 +894,15 @@ var QueryParser = class {
|
|
|
822
894
|
for (const field of this.options.searchFields) orConditions.push({ [field]: { $regex: safeRegex } });
|
|
823
895
|
return orConditions.length > 0 ? orConditions : null;
|
|
824
896
|
}
|
|
825
|
-
_convertValue(value) {
|
|
826
|
-
if (value === null || value === void 0) return value;
|
|
827
|
-
if (Array.isArray(value)) return value.map((v) => this._convertValue(v));
|
|
828
|
-
if (typeof value === "object") return value;
|
|
829
|
-
const stringValue = String(value);
|
|
830
|
-
if (stringValue === "true") return true;
|
|
831
|
-
if (stringValue === "false") return false;
|
|
832
|
-
if (mongoose.Types.ObjectId.isValid(stringValue) && stringValue.length === 24) return stringValue;
|
|
833
|
-
return stringValue;
|
|
834
|
-
}
|
|
835
897
|
_parseOr(query) {
|
|
836
898
|
const orArray = [];
|
|
837
899
|
const raw = query?.or || query?.OR || query?.$or;
|
|
838
900
|
if (!raw) return void 0;
|
|
839
901
|
const items = Array.isArray(raw) ? raw : typeof raw === "object" ? Object.values(raw) : [];
|
|
840
|
-
for (const item of items) if (typeof item === "object" && item)
|
|
902
|
+
for (const item of items) if (typeof item === "object" && item) {
|
|
903
|
+
const parsedBranch = this._parseFilters(item, 1);
|
|
904
|
+
if (Object.keys(parsedBranch).length > 0) orArray.push(parsedBranch);
|
|
905
|
+
}
|
|
841
906
|
return orArray.length ? orArray : void 0;
|
|
842
907
|
}
|
|
843
908
|
_enhanceWithBetween(filters) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/query/primitives/indexes.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Schema index introspection
|
|
4
|
+
*
|
|
5
|
+
* Pure functions that read a Mongoose-like schema's `.indexes()` output and
|
|
6
|
+
* extract structured information about which fields are indexed how. Used by
|
|
7
|
+
* QueryParser to:
|
|
8
|
+
*
|
|
9
|
+
* - Detect 2dsphere/2d-indexed fields → enable geo operator routing.
|
|
10
|
+
* - Detect text-indexed fields → expose to repositories that need it.
|
|
11
|
+
* - Surface compound index hints → useful for query planners and Arc MCP
|
|
12
|
+
* auto-generation.
|
|
13
|
+
*
|
|
14
|
+
* Stays decoupled from a specific Mongoose major version: only depends on
|
|
15
|
+
* `.indexes()` returning a list of `[indexSpec, options?]` tuples, which has
|
|
16
|
+
* been stable since Mongoose 4.x.
|
|
17
|
+
*/
|
|
18
|
+
/** Minimal structural type for a Mongoose-like schema. */
|
|
19
|
+
interface IndexableSchema {
|
|
20
|
+
indexes(): Array<[Record<string, unknown>, Record<string, unknown>?]>;
|
|
21
|
+
}
|
|
22
|
+
/** Structured view of a schema's indexes, indexed by purpose. */
|
|
23
|
+
interface SchemaIndexes {
|
|
24
|
+
/** Field paths with a 2dsphere or 2d index — eligible for geo operators */
|
|
25
|
+
geoFields: string[];
|
|
26
|
+
/** Field paths with a text index — eligible for $text queries */
|
|
27
|
+
textFields: string[];
|
|
28
|
+
/** All other indexes as raw spec/options pairs (for hints, plan analysis) */
|
|
29
|
+
other: Array<{
|
|
30
|
+
spec: Record<string, unknown>;
|
|
31
|
+
options?: Record<string, unknown>;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extract structured index information from a Mongoose schema. Returns an
|
|
36
|
+
* empty `SchemaIndexes` shape (not null) when no schema is provided so callers
|
|
37
|
+
* can read `.geoFields`/`.textFields` unconditionally without null checks.
|
|
38
|
+
*/
|
|
39
|
+
declare function extractSchemaIndexes(schema?: IndexableSchema | null): SchemaIndexes;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { SchemaIndexes as n, extractSchemaIndexes as r, IndexableSchema as t };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { n as isObjectIdInstance } from "./id-resolution-LZ-cCwR5.mjs";
|
|
1
2
|
import "mongoose";
|
|
2
3
|
//#region src/utils/memory-cache.ts
|
|
3
4
|
/**
|
|
@@ -93,28 +94,56 @@ function buildCrudSchemasFromModel(mongooseModel, options = {}) {
|
|
|
93
94
|
return buildCrudSchemasFromMongooseSchema(mongooseModel.schema, options);
|
|
94
95
|
}
|
|
95
96
|
/**
|
|
96
|
-
*
|
|
97
|
+
* Collect fields to omit from a generated schema based on field rules and
|
|
98
|
+
* explicit omit lists. This is the single source of truth for "which fields
|
|
99
|
+
* should NOT appear in the create/update body" — called by both the
|
|
100
|
+
* path-based and tree-based schema builders.
|
|
101
|
+
*/
|
|
102
|
+
function collectFieldsToOmit(options, purpose) {
|
|
103
|
+
const result = new Set([
|
|
104
|
+
"createdAt",
|
|
105
|
+
"updatedAt",
|
|
106
|
+
"__v"
|
|
107
|
+
]);
|
|
108
|
+
const rules = options?.fieldRules || {};
|
|
109
|
+
for (const [field, rule] of Object.entries(rules)) {
|
|
110
|
+
if (rule.systemManaged) result.add(field);
|
|
111
|
+
if (purpose === "update" && (rule.immutable || rule.immutableAfterCreate)) result.add(field);
|
|
112
|
+
}
|
|
113
|
+
const explicit = purpose === "create" ? options?.create?.omitFields : options?.update?.omitFields;
|
|
114
|
+
if (explicit) for (const f of explicit) result.add(f);
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Apply omissions + optional-overrides to a built JSON schema in-place.
|
|
119
|
+
* Removes properties and adjusts the `required` array.
|
|
120
|
+
*/
|
|
121
|
+
function applyFieldRules(schema, fieldsToOmit, options) {
|
|
122
|
+
for (const field of fieldsToOmit) {
|
|
123
|
+
if (schema.properties?.[field]) delete schema.properties[field];
|
|
124
|
+
if (schema.required) schema.required = schema.required.filter((k) => k !== field);
|
|
125
|
+
}
|
|
126
|
+
const rules = options?.fieldRules || {};
|
|
127
|
+
for (const [field, rule] of Object.entries(rules)) if (rule.optional && schema.required) schema.required = schema.required.filter((k) => k !== field);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get fields that are immutable (cannot be updated).
|
|
131
|
+
* Delegates to `collectFieldsToOmit` internally.
|
|
97
132
|
*/
|
|
98
133
|
function getImmutableFields(options = {}) {
|
|
99
134
|
const immutable = [];
|
|
100
|
-
const
|
|
101
|
-
Object.entries(
|
|
102
|
-
|
|
103
|
-
});
|
|
104
|
-
(options?.update?.omitFields || []).forEach((f) => {
|
|
105
|
-
if (!immutable.includes(f)) immutable.push(f);
|
|
106
|
-
});
|
|
135
|
+
const rules = options?.fieldRules || {};
|
|
136
|
+
for (const [field, rule] of Object.entries(rules)) if (rule.immutable || rule.immutableAfterCreate) immutable.push(field);
|
|
137
|
+
for (const f of options?.update?.omitFields || []) if (!immutable.includes(f)) immutable.push(f);
|
|
107
138
|
return immutable;
|
|
108
139
|
}
|
|
109
140
|
/**
|
|
110
|
-
* Get fields that are system-managed (cannot be set by users)
|
|
141
|
+
* Get fields that are system-managed (cannot be set by users).
|
|
111
142
|
*/
|
|
112
143
|
function getSystemManagedFields(options = {}) {
|
|
113
144
|
const systemManaged = [];
|
|
114
|
-
const
|
|
115
|
-
Object.entries(
|
|
116
|
-
if (rules.systemManaged) systemManaged.push(field);
|
|
117
|
-
});
|
|
145
|
+
const rules = options?.fieldRules || {};
|
|
146
|
+
for (const [field, rule] of Object.entries(rules)) if (rule.systemManaged) systemManaged.push(field);
|
|
118
147
|
return systemManaged;
|
|
119
148
|
}
|
|
120
149
|
/**
|
|
@@ -161,7 +190,11 @@ function buildJsonSchemaFromPaths(mongooseSchema, options) {
|
|
|
161
190
|
};
|
|
162
191
|
const rootFields = /* @__PURE__ */ new Map();
|
|
163
192
|
for (const [path, schemaType] of Object.entries(paths)) {
|
|
164
|
-
if (path === "
|
|
193
|
+
if (path === "__v") continue;
|
|
194
|
+
if (path === "_id") {
|
|
195
|
+
const instance = schemaType.instance;
|
|
196
|
+
if (!instance || isObjectIdInstance(instance)) continue;
|
|
197
|
+
}
|
|
165
198
|
const rootField = path.split(".")[0];
|
|
166
199
|
if (!rootFields.has(rootField)) rootFields.set(rootField, []);
|
|
167
200
|
rootFields.get(rootField)?.push({
|
|
@@ -183,30 +216,12 @@ function buildJsonSchemaFromPaths(mongooseSchema, options) {
|
|
|
183
216
|
properties
|
|
184
217
|
};
|
|
185
218
|
if (required.length) schema.required = required;
|
|
186
|
-
|
|
187
|
-
"createdAt",
|
|
188
|
-
"updatedAt",
|
|
189
|
-
"__v"
|
|
190
|
-
]);
|
|
191
|
-
(options?.create?.omitFields || []).forEach((f) => {
|
|
192
|
-
fieldsToOmit.add(f);
|
|
193
|
-
});
|
|
194
|
-
const fieldRules = options?.fieldRules || {};
|
|
195
|
-
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
196
|
-
if (rules.systemManaged) fieldsToOmit.add(field);
|
|
197
|
-
});
|
|
198
|
-
fieldsToOmit.forEach((field) => {
|
|
199
|
-
if (schema.properties?.[field]) delete schema.properties[field];
|
|
200
|
-
if (schema.required) schema.required = schema.required.filter((k) => k !== field);
|
|
201
|
-
});
|
|
219
|
+
applyFieldRules(schema, collectFieldsToOmit(options, "create"), options);
|
|
202
220
|
const reqOv = options?.create?.requiredOverrides || {};
|
|
203
221
|
const optOv = options?.create?.optionalOverrides || {};
|
|
204
222
|
schema.required = schema.required || [];
|
|
205
223
|
for (const [k, v] of Object.entries(reqOv)) if (v && !schema.required.includes(k)) schema.required.push(k);
|
|
206
224
|
for (const [k, v] of Object.entries(optOv)) if (v && schema.required) schema.required = schema.required.filter((x) => x !== k);
|
|
207
|
-
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
208
|
-
if (rules.optional && schema.required) schema.required = schema.required.filter((x) => x !== field);
|
|
209
|
-
});
|
|
210
225
|
const schemaOverrides = options?.create?.schemaOverrides || {};
|
|
211
226
|
for (const [k, override] of Object.entries(schemaOverrides)) if (schema.properties?.[k]) schema.properties[k] = override;
|
|
212
227
|
if (options?.strictAdditionalProperties === true) schema.additionalProperties = false;
|
|
@@ -270,7 +285,7 @@ function schemaTypeToJsonSchema(schemaType) {
|
|
|
270
285
|
else if (instance === "Date") {
|
|
271
286
|
result.type = "string";
|
|
272
287
|
result.format = "date-time";
|
|
273
|
-
} else if (instance
|
|
288
|
+
} else if (isObjectIdInstance(instance)) {
|
|
274
289
|
result.type = "string";
|
|
275
290
|
result.pattern = "^[0-9a-fA-F]{24}$";
|
|
276
291
|
} else if (instance === "Array") {
|
|
@@ -285,17 +300,7 @@ function schemaTypeToJsonSchema(schemaType) {
|
|
|
285
300
|
function buildJsonSchemaForUpdate(createJson, options) {
|
|
286
301
|
const clone = JSON.parse(JSON.stringify(createJson));
|
|
287
302
|
delete clone.required;
|
|
288
|
-
|
|
289
|
-
(options?.update?.omitFields || []).forEach((f) => {
|
|
290
|
-
fieldsToOmit.add(f);
|
|
291
|
-
});
|
|
292
|
-
const fieldRules = options?.fieldRules || {};
|
|
293
|
-
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
294
|
-
if (rules.immutable || rules.immutableAfterCreate) fieldsToOmit.add(field);
|
|
295
|
-
});
|
|
296
|
-
fieldsToOmit.forEach((field) => {
|
|
297
|
-
if (clone.properties?.[field]) delete clone.properties[field];
|
|
298
|
-
});
|
|
303
|
+
applyFieldRules(clone, collectFieldsToOmit(options, "update"), options);
|
|
299
304
|
if (options?.strictAdditionalProperties === true) clone.additionalProperties = false;
|
|
300
305
|
if (options?.update?.requireAtLeastOne === true) clone.minProperties = 1;
|
|
301
306
|
return clone;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as FieldPreset, _ as CrudSchemas, k as HttpError, ot as SchemaBuilderOptions, s as CacheAdapter, xt as ValidationResult, yt as UserContext } from "./types-
|
|
1
|
+
import { T as FieldPreset, _ as CrudSchemas, k as HttpError, ot as SchemaBuilderOptions, s as CacheAdapter, xt as ValidationResult, yt as UserContext } from "./types-BwO4u3JN.mjs";
|
|
2
2
|
import mongoose, { Schema } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/error.d.ts
|
|
@@ -146,11 +146,12 @@ declare function buildCrudSchemasFromMongooseSchema(mongooseSchema: Schema, opti
|
|
|
146
146
|
*/
|
|
147
147
|
declare function buildCrudSchemasFromModel(mongooseModel: mongoose.Model<unknown>, options?: SchemaBuilderOptions): CrudSchemas;
|
|
148
148
|
/**
|
|
149
|
-
* Get fields that are immutable (cannot be updated)
|
|
149
|
+
* Get fields that are immutable (cannot be updated).
|
|
150
|
+
* Delegates to `collectFieldsToOmit` internally.
|
|
150
151
|
*/
|
|
151
152
|
declare function getImmutableFields(options?: SchemaBuilderOptions): string[];
|
|
152
153
|
/**
|
|
153
|
-
* Get fields that are system-managed (cannot be set by users)
|
|
154
|
+
* Get fields that are system-managed (cannot be set by users).
|
|
154
155
|
*/
|
|
155
156
|
declare function getSystemManagedFields(options?: SchemaBuilderOptions): string[];
|
|
156
157
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, P as KeysetPaginationOptions, U as OffsetPaginationResult, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-
|
|
1
|
+
import { F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, P as KeysetPaginationOptions, U as OffsetPaginationResult, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-BwO4u3JN.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-
|
|
1
|
+
import { t as PaginationEngine } from "../PaginationEngine-CpsQl471.mjs";
|
|
2
2
|
export { PaginationEngine };
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, y as MethodRegistryRepository, z as batchOperationsPlugin } from "../validation-chain.plugin-
|
|
1
|
+
import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, y as MethodRegistryRepository, z as batchOperationsPlugin } from "../validation-chain.plugin-BtmT-FFB.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, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
|