@classytic/mongokit 3.5.2 → 3.5.4
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 +34 -0
- package/dist/actions/index.d.mts +1 -1
- package/dist/ai/index.d.mts +1 -1
- package/dist/{index-BjXxDBgx.d.mts → index-BNpVzw_-.d.mts} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -2
- package/dist/{mongooseToJsonSchema-B6Qyl8BK.mjs → mongooseToJsonSchema-DpjhFfaO.mjs} +6 -1
- package/dist/{mongooseToJsonSchema-C78rAP7X.d.mts → mongooseToJsonSchema-Dsx3YAAx.d.mts} +1 -1
- package/dist/pagination/PaginationEngine.d.mts +1 -1
- package/dist/plugins/index.d.mts +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/{types-DK6ELT6o.d.mts → types-CkE3mOaW.d.mts} +38 -0
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/index.mjs +1 -1
- package/dist/{validation-chain.plugin-DISOoL9A.d.mts → validation-chain.plugin-BYMZB8dN.d.mts} +1 -1
- package/dist/{validation-chain.plugin-vxvcv1dg.mjs → validation-chain.plugin-KjPV_6_N.mjs} +78 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1172,6 +1172,40 @@ const { crudSchemas } = buildCrudSchemasFromModel(UserModel, {
|
|
|
1172
1172
|
// crudSchemas.listQuery - GET query validation
|
|
1173
1173
|
```
|
|
1174
1174
|
|
|
1175
|
+
#### Soft-required fields (draft-friendly bodies)
|
|
1176
|
+
|
|
1177
|
+
Some resources have fields that must be non-null in the DB but should be
|
|
1178
|
+
**optional in the HTTP body** — draft journal entries, multi-step wizards,
|
|
1179
|
+
or any state-machine resource that's filled out progressively. Marking a
|
|
1180
|
+
path `softRequired: true` keeps the Mongoose `required: true` invariant
|
|
1181
|
+
(null on save is still rejected) while excluding the field from the
|
|
1182
|
+
generated `createBody.required[]` array.
|
|
1183
|
+
|
|
1184
|
+
```typescript
|
|
1185
|
+
// 1. Per-path flag (when you own the Mongoose schema)
|
|
1186
|
+
const JournalEntrySchema = new Schema({
|
|
1187
|
+
label: { type: String, required: true }, // hard required
|
|
1188
|
+
journalType: {
|
|
1189
|
+
type: String,
|
|
1190
|
+
required: true, // DB invariant — null rejected on save
|
|
1191
|
+
softRequired: true, // HTTP body — optional in create/update
|
|
1192
|
+
enum: ['sale', 'purchase', 'adjustment'],
|
|
1193
|
+
},
|
|
1194
|
+
date: { type: Date, required: true, softRequired: true },
|
|
1195
|
+
});
|
|
1196
|
+
|
|
1197
|
+
// 2. Per-build override (when the Mongoose model lives in an upstream package)
|
|
1198
|
+
const { createBody } = buildCrudSchemasFromModel(UpstreamModel, {
|
|
1199
|
+
softRequiredFields: ['journalType', 'date'],
|
|
1200
|
+
});
|
|
1201
|
+
// createBody.required → ['label'] (journalType + date excluded)
|
|
1202
|
+
// createBody.properties → still includes journalType + date (validated when present)
|
|
1203
|
+
```
|
|
1204
|
+
|
|
1205
|
+
The DB-level `required: true` is unaffected — `repo.create()` with `null`
|
|
1206
|
+
for a soft-required field still throws a Mongoose ValidationError. The
|
|
1207
|
+
flag only changes what HTTP clients must send.
|
|
1208
|
+
|
|
1175
1209
|
### Complete Controller Example
|
|
1176
1210
|
|
|
1177
1211
|
```typescript
|
package/dist/actions/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-
|
|
1
|
+
import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-BNpVzw_-.mjs";
|
|
2
2
|
export { aggregate_d_exports as aggregate, create_d_exports as create, delete_d_exports as deleteActions, read_d_exports as read, update_d_exports as update };
|
package/dist/ai/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as ReadPreferenceType, At as LookupOptions, D as GroupResult, V as ObjectId, W as OperationOptions, Z as PopulateSpec, _t as UpdateOptions, a as AnyDocument, b as DeleteResult, g as CreateOptions, gt as UpdateManyResult, pt as SortSpec, st as SelectSpec, vt as UpdateWithValidationResult, z as MinMaxResult } from "./types-
|
|
1
|
+
import { $ as ReadPreferenceType, At as LookupOptions, D as GroupResult, V as ObjectId, W as OperationOptions, Z as PopulateSpec, _t as UpdateOptions, a as AnyDocument, b as DeleteResult, g as CreateOptions, gt as UpdateManyResult, pt as SortSpec, st as SelectSpec, vt as UpdateWithValidationResult, z as MinMaxResult } from "./types-CkE3mOaW.mjs";
|
|
2
2
|
import { ClientSession, Model, PipelineStage } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/actions/aggregate.d.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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-CkE3mOaW.mjs";
|
|
2
|
+
import { t as index_d_exports } from "./index-BNpVzw_-.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 { 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-
|
|
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-BYMZB8dN.mjs";
|
|
5
|
+
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-Dsx3YAAx.mjs";
|
|
6
6
|
import * as _$mongoose from "mongoose";
|
|
7
7
|
import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
|
|
8
8
|
|
package/dist/index.mjs
CHANGED
|
@@ -2,9 +2,9 @@ import { a as warn, n as parseDuplicateKeyError, r as configureLogger, t as crea
|
|
|
2
2
|
import { y as LookupBuilder } from "./update-AVfKWNGt.mjs";
|
|
3
3
|
import { t as actions_exports } from "./actions/index.mjs";
|
|
4
4
|
import { t as PaginationEngine } from "./PaginationEngine-DCs-zKwZ.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-
|
|
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-KjPV_6_N.mjs";
|
|
6
6
|
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-reyDRzXf.mjs";
|
|
7
|
-
import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-
|
|
7
|
+
import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-DpjhFfaO.mjs";
|
|
8
8
|
import mongoose from "mongoose";
|
|
9
9
|
//#region src/query/QueryParser.ts
|
|
10
10
|
/**
|
|
@@ -154,6 +154,11 @@ function buildJsonSchemaFromPaths(mongooseSchema, options) {
|
|
|
154
154
|
const properties = {};
|
|
155
155
|
const required = [];
|
|
156
156
|
const paths = mongooseSchema.paths;
|
|
157
|
+
const softRequiredSet = new Set(options?.softRequiredFields ?? []);
|
|
158
|
+
const isSoftRequired = (name, schemaType) => {
|
|
159
|
+
if (softRequiredSet.has(name)) return true;
|
|
160
|
+
return schemaType?.options?.softRequired === true;
|
|
161
|
+
};
|
|
157
162
|
const rootFields = /* @__PURE__ */ new Map();
|
|
158
163
|
for (const [path, schemaType] of Object.entries(paths)) {
|
|
159
164
|
if (path === "_id" || path === "__v") continue;
|
|
@@ -167,7 +172,7 @@ function buildJsonSchemaFromPaths(mongooseSchema, options) {
|
|
|
167
172
|
for (const [rootField, fieldPaths] of rootFields.entries()) if (fieldPaths.length === 1 && fieldPaths[0].path === rootField) {
|
|
168
173
|
const schemaType = fieldPaths[0].schemaType;
|
|
169
174
|
properties[rootField] = schemaTypeToJsonSchema(schemaType);
|
|
170
|
-
if (schemaType.isRequired) required.push(rootField);
|
|
175
|
+
if (schemaType.isRequired && !isSoftRequired(rootField, schemaType)) required.push(rootField);
|
|
171
176
|
} else {
|
|
172
177
|
const nestedSchema = buildNestedJsonSchema(fieldPaths, rootField);
|
|
173
178
|
properties[rootField] = nestedSchema.schema;
|
|
@@ -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-CkE3mOaW.mjs";
|
|
2
2
|
import mongoose, { Schema } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/error.d.ts
|
|
@@ -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-CkE3mOaW.mjs";
|
|
2
2
|
import { Model } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/pagination/PaginationEngine.d.ts
|
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-BYMZB8dN.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 };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as aggregateHelpersPlugin, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, _ 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, x as cascadePlugin, y as prefixedId } from "../validation-chain.plugin-
|
|
1
|
+
import { A as aggregateHelpersPlugin, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, _ 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, x as cascadePlugin, y as prefixedId } from "../validation-chain.plugin-KjPV_6_N.mjs";
|
|
2
2
|
export { AuditTrailQuery, 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 };
|
|
@@ -457,6 +457,27 @@ interface IResponseFormatter {
|
|
|
457
457
|
}
|
|
458
458
|
//#endregion
|
|
459
459
|
//#region src/types.d.ts
|
|
460
|
+
/**
|
|
461
|
+
* MongoKit Type Definitions
|
|
462
|
+
*
|
|
463
|
+
* Production-grade types for MongoDB repository pattern with TypeScript
|
|
464
|
+
*
|
|
465
|
+
* @module @classytic/mongokit
|
|
466
|
+
*/
|
|
467
|
+
/**
|
|
468
|
+
* Global declaration merge: adds `softRequired` to Mongoose's SchemaTypeOptions
|
|
469
|
+
* so consumers can annotate paths type-safely without importing anything.
|
|
470
|
+
*
|
|
471
|
+
* A path with `softRequired: true` keeps its DB-level `required: true`
|
|
472
|
+
* invariant but is excluded from the auto-generated CRUD body `required[]`
|
|
473
|
+
* array (see buildCrudSchemasFromModel).
|
|
474
|
+
*/
|
|
475
|
+
declare module 'mongoose' {
|
|
476
|
+
interface SchemaTypeOptions<T, EnforcedDocType = any, THydratedDocumentType = HydratedDocument<EnforcedDocType>> {
|
|
477
|
+
/** mongokit: omit from auto-generated CRUD body `required` array. */
|
|
478
|
+
softRequired?: boolean;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
460
481
|
/** Read Preference Type for replica sets */
|
|
461
482
|
type ReadPreferenceType = 'primary' | 'primaryPreferred' | 'secondary' | 'secondaryPreferred' | 'nearest' | (string & {});
|
|
462
483
|
/** Re-export mongoose ObjectId */
|
|
@@ -684,6 +705,10 @@ type PaginationResult<T = unknown> = OffsetPaginationResult<T> | KeysetPaginatio
|
|
|
684
705
|
interface SessionOptions {
|
|
685
706
|
/** MongoDB session for transactions */
|
|
686
707
|
session?: ClientSession;
|
|
708
|
+
/** Organization/tenant ID for multi-tenant plugin scoping */
|
|
709
|
+
organizationId?: string | ObjectId;
|
|
710
|
+
/** Extensible — plugins can read custom fields from options */
|
|
711
|
+
[key: string]: unknown;
|
|
687
712
|
}
|
|
688
713
|
/** Read options — session + readPreference for read-only operations */
|
|
689
714
|
interface ReadOptions extends SessionOptions {
|
|
@@ -994,6 +1019,19 @@ interface SchemaBuilderOptions {
|
|
|
994
1019
|
optionalOverrides?: Record<string, boolean>; /** Schema overrides */
|
|
995
1020
|
schemaOverrides?: Record<string, unknown>;
|
|
996
1021
|
};
|
|
1022
|
+
/**
|
|
1023
|
+
* Field names to mark as soft-required: they remain in the generated body
|
|
1024
|
+
* schema's `properties` (still validated when present) but are excluded
|
|
1025
|
+
* from the `required[]` array so the client may omit them.
|
|
1026
|
+
*
|
|
1027
|
+
* Combines with per-path `softRequired: true` Mongoose schema option.
|
|
1028
|
+
* Use this when the Mongoose model is owned by an upstream package and
|
|
1029
|
+
* you can't annotate the schema directly.
|
|
1030
|
+
*
|
|
1031
|
+
* The DB-level `required: true` invariant is unaffected — Mongoose still
|
|
1032
|
+
* rejects null on save. This flag only affects HTTP body validation.
|
|
1033
|
+
*/
|
|
1034
|
+
softRequiredFields?: string[];
|
|
997
1035
|
/** Update schema options */
|
|
998
1036
|
update?: {
|
|
999
1037
|
/** Fields to omit from update schema */omitFields?: string[]; /** Require at least one field to be provided (default: false) */
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Z as PopulateSpec, pt as SortSpec, st as SelectSpec } from "../types-
|
|
2
|
-
import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "../mongooseToJsonSchema-
|
|
1
|
+
import { Z as PopulateSpec, pt as SortSpec, st as SelectSpec } from "../types-CkE3mOaW.mjs";
|
|
2
|
+
import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "../mongooseToJsonSchema-Dsx3YAAx.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/cache-keys.d.ts
|
|
5
5
|
/**
|
package/dist/utils/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { r as configureLogger, t as createError } from "../error-Bpbi_NKo.mjs";
|
|
2
2
|
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-reyDRzXf.mjs";
|
|
3
|
-
import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-
|
|
3
|
+
import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-DpjhFfaO.mjs";
|
|
4
4
|
export { buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, byIdKey, byQueryKey, configureLogger, createError, createFieldPreset, createMemoryCache, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getSystemManagedFields, isFieldUpdateAllowed, listPattern, listQueryKey, modelPattern, validateUpdateBody, versionKey };
|
package/dist/{validation-chain.plugin-DISOoL9A.d.mts → validation-chain.plugin-BYMZB8dN.d.mts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as Logger, J as Plugin, St as ValidatorDefinition, T as FieldPreset, U as OffsetPaginationResult, V as ObjectId, Z as PopulateSpec, bt as ValidationChainOptions, et as RepositoryContext, f as CascadeOptions, l as CacheOptions, nt as RepositoryInstance, pt as SortSpec, st as SelectSpec, u as CacheStats, ut as SoftDeleteOptions } from "./types-
|
|
1
|
+
import { I as Logger, J as Plugin, St as ValidatorDefinition, T as FieldPreset, U as OffsetPaginationResult, V as ObjectId, Z as PopulateSpec, bt as ValidationChainOptions, et as RepositoryContext, f as CascadeOptions, l as CacheOptions, nt as RepositoryInstance, pt as SortSpec, st as SelectSpec, u as CacheStats, ut as SoftDeleteOptions } from "./types-CkE3mOaW.mjs";
|
|
2
2
|
import mongoose, { ClientSession } from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/plugins/aggregate-helpers.plugin.d.ts
|
|
@@ -2431,6 +2431,34 @@ function cachePlugin(options) {
|
|
|
2431
2431
|
}
|
|
2432
2432
|
}, { priority: HOOK_PRIORITY.CACHE });
|
|
2433
2433
|
/**
|
|
2434
|
+
* before:getOne - Same cache logic as getByQuery (single-doc)
|
|
2435
|
+
*/
|
|
2436
|
+
repo.on("before:getOne", async (context) => {
|
|
2437
|
+
if (context.skipCache) return;
|
|
2438
|
+
try {
|
|
2439
|
+
const collectionVersion = await getVersion();
|
|
2440
|
+
const query = context.query || {};
|
|
2441
|
+
const key = byQueryKey(config.prefix, model, collectionVersion, query, {
|
|
2442
|
+
select: context.select,
|
|
2443
|
+
populate: context.populate
|
|
2444
|
+
});
|
|
2445
|
+
const cached = await config.adapter.get(key);
|
|
2446
|
+
if (cached !== null && cached !== void 0) {
|
|
2447
|
+
log(`Cache HIT for getOne: ${key}`);
|
|
2448
|
+
stats.hits++;
|
|
2449
|
+
context._cacheHit = true;
|
|
2450
|
+
context._cachedResult = cached;
|
|
2451
|
+
} else {
|
|
2452
|
+
log(`Cache MISS for getOne: ${key}`);
|
|
2453
|
+
stats.misses++;
|
|
2454
|
+
context._cacheKey = key;
|
|
2455
|
+
}
|
|
2456
|
+
} catch (e) {
|
|
2457
|
+
log(`Cache error for getOne:`, e);
|
|
2458
|
+
stats.errors++;
|
|
2459
|
+
}
|
|
2460
|
+
}, { priority: HOOK_PRIORITY.CACHE });
|
|
2461
|
+
/**
|
|
2434
2462
|
* before:getAll - Check cache for list query
|
|
2435
2463
|
* Runs at CACHE priority (200) — after policy hooks inject filters
|
|
2436
2464
|
*/
|
|
@@ -2526,6 +2554,25 @@ function cachePlugin(options) {
|
|
|
2526
2554
|
}
|
|
2527
2555
|
});
|
|
2528
2556
|
/**
|
|
2557
|
+
* after:getOne - Cache the result (same as getByQuery)
|
|
2558
|
+
*/
|
|
2559
|
+
repo.on("after:getOne", async (payload) => {
|
|
2560
|
+
const { context, result } = payload;
|
|
2561
|
+
if (context._cacheHit || context.skipCache || result === null) return;
|
|
2562
|
+
const collectionVersion = await getVersion();
|
|
2563
|
+
const query = context.query || {};
|
|
2564
|
+
const key = byQueryKey(config.prefix, model, collectionVersion, query, {
|
|
2565
|
+
select: context.select,
|
|
2566
|
+
populate: context.populate
|
|
2567
|
+
});
|
|
2568
|
+
try {
|
|
2569
|
+
await config.adapter.set(key, result, context.cacheTtl ?? config.queryTtl);
|
|
2570
|
+
stats.sets++;
|
|
2571
|
+
} catch (e) {
|
|
2572
|
+
log(`Failed to cache getOne:`, e);
|
|
2573
|
+
}
|
|
2574
|
+
});
|
|
2575
|
+
/**
|
|
2529
2576
|
* after:getAll - Cache the result
|
|
2530
2577
|
*/
|
|
2531
2578
|
repo.on("after:getAll", async (payload) => {
|
|
@@ -3193,8 +3240,10 @@ function fieldFilterPlugin(fieldPreset) {
|
|
|
3193
3240
|
else context.select = presetSelect;
|
|
3194
3241
|
};
|
|
3195
3242
|
repo.on("before:getAll", applyFieldFiltering);
|
|
3243
|
+
repo.on("before:findAll", applyFieldFiltering);
|
|
3196
3244
|
repo.on("before:getById", applyFieldFiltering);
|
|
3197
3245
|
repo.on("before:getByQuery", applyFieldFiltering);
|
|
3246
|
+
repo.on("before:getOne", applyFieldFiltering);
|
|
3198
3247
|
}
|
|
3199
3248
|
};
|
|
3200
3249
|
}
|
|
@@ -3480,12 +3529,14 @@ function multiTenantPlugin(options = {}) {
|
|
|
3480
3529
|
const { tenantField = "organizationId", contextKey = "organizationId", required = true, skipOperations = [], skipWhen, resolveContext } = options;
|
|
3481
3530
|
const filterOps = [
|
|
3482
3531
|
"getAll",
|
|
3532
|
+
"findAll",
|
|
3483
3533
|
"aggregatePaginate",
|
|
3484
3534
|
"lookupPopulate"
|
|
3485
3535
|
];
|
|
3486
3536
|
const queryReadOps = [
|
|
3487
3537
|
"getById",
|
|
3488
3538
|
"getByQuery",
|
|
3539
|
+
"getOne",
|
|
3489
3540
|
"count",
|
|
3490
3541
|
"exists",
|
|
3491
3542
|
"getOrCreate",
|
|
@@ -3578,7 +3629,14 @@ const DEFAULT_OPS = [
|
|
|
3578
3629
|
"delete",
|
|
3579
3630
|
"getById",
|
|
3580
3631
|
"getByQuery",
|
|
3632
|
+
"getOne",
|
|
3581
3633
|
"getAll",
|
|
3634
|
+
"findAll",
|
|
3635
|
+
"getOrCreate",
|
|
3636
|
+
"count",
|
|
3637
|
+
"exists",
|
|
3638
|
+
"distinct",
|
|
3639
|
+
"aggregate",
|
|
3582
3640
|
"aggregatePaginate",
|
|
3583
3641
|
"lookupPopulate"
|
|
3584
3642
|
];
|
|
@@ -3733,7 +3791,7 @@ function softDeletePlugin(options = {}) {
|
|
|
3733
3791
|
context.softDeleted = true;
|
|
3734
3792
|
}
|
|
3735
3793
|
}, { priority: HOOK_PRIORITY.POLICY });
|
|
3736
|
-
|
|
3794
|
+
const injectDeleteFilterToFilters = (context) => {
|
|
3737
3795
|
if (options.soft !== false) {
|
|
3738
3796
|
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
3739
3797
|
if (Object.keys(deleteFilter).length > 0) context.filters = {
|
|
@@ -3741,53 +3799,8 @@ function softDeletePlugin(options = {}) {
|
|
|
3741
3799
|
...deleteFilter
|
|
3742
3800
|
};
|
|
3743
3801
|
}
|
|
3744
|
-
}
|
|
3745
|
-
|
|
3746
|
-
if (options.soft !== false) {
|
|
3747
|
-
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
3748
|
-
if (Object.keys(deleteFilter).length > 0) context.query = {
|
|
3749
|
-
...context.query || {},
|
|
3750
|
-
...deleteFilter
|
|
3751
|
-
};
|
|
3752
|
-
}
|
|
3753
|
-
}, { priority: HOOK_PRIORITY.POLICY });
|
|
3754
|
-
repo.on("before:getByQuery", (context) => {
|
|
3755
|
-
if (options.soft !== false) {
|
|
3756
|
-
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
3757
|
-
if (Object.keys(deleteFilter).length > 0) context.query = {
|
|
3758
|
-
...context.query || {},
|
|
3759
|
-
...deleteFilter
|
|
3760
|
-
};
|
|
3761
|
-
}
|
|
3762
|
-
}, { priority: HOOK_PRIORITY.POLICY });
|
|
3763
|
-
repo.on("before:count", (context) => {
|
|
3764
|
-
if (options.soft !== false) {
|
|
3765
|
-
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
3766
|
-
if (Object.keys(deleteFilter).length > 0) context.query = {
|
|
3767
|
-
...context.query || {},
|
|
3768
|
-
...deleteFilter
|
|
3769
|
-
};
|
|
3770
|
-
}
|
|
3771
|
-
}, { priority: HOOK_PRIORITY.POLICY });
|
|
3772
|
-
repo.on("before:exists", (context) => {
|
|
3773
|
-
if (options.soft !== false) {
|
|
3774
|
-
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
3775
|
-
if (Object.keys(deleteFilter).length > 0) context.query = {
|
|
3776
|
-
...context.query || {},
|
|
3777
|
-
...deleteFilter
|
|
3778
|
-
};
|
|
3779
|
-
}
|
|
3780
|
-
}, { priority: HOOK_PRIORITY.POLICY });
|
|
3781
|
-
repo.on("before:getOrCreate", (context) => {
|
|
3782
|
-
if (options.soft !== false) {
|
|
3783
|
-
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
3784
|
-
if (Object.keys(deleteFilter).length > 0) context.query = {
|
|
3785
|
-
...context.query || {},
|
|
3786
|
-
...deleteFilter
|
|
3787
|
-
};
|
|
3788
|
-
}
|
|
3789
|
-
}, { priority: HOOK_PRIORITY.POLICY });
|
|
3790
|
-
repo.on("before:distinct", (context) => {
|
|
3802
|
+
};
|
|
3803
|
+
const injectDeleteFilterToQuery = (context) => {
|
|
3791
3804
|
if (options.soft !== false) {
|
|
3792
3805
|
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
|
3793
3806
|
if (Object.keys(deleteFilter).length > 0) context.query = {
|
|
@@ -3795,7 +3808,23 @@ function softDeletePlugin(options = {}) {
|
|
|
3795
3808
|
...deleteFilter
|
|
3796
3809
|
};
|
|
3797
3810
|
}
|
|
3798
|
-
}
|
|
3811
|
+
};
|
|
3812
|
+
for (const op of [
|
|
3813
|
+
"getAll",
|
|
3814
|
+
"findAll",
|
|
3815
|
+
"aggregatePaginate",
|
|
3816
|
+
"lookupPopulate"
|
|
3817
|
+
]) repo.on(`before:${op}`, injectDeleteFilterToFilters, { priority: HOOK_PRIORITY.POLICY });
|
|
3818
|
+
for (const op of [
|
|
3819
|
+
"getById",
|
|
3820
|
+
"getOne",
|
|
3821
|
+
"getByQuery",
|
|
3822
|
+
"count",
|
|
3823
|
+
"exists",
|
|
3824
|
+
"getOrCreate",
|
|
3825
|
+
"distinct",
|
|
3826
|
+
"aggregate"
|
|
3827
|
+
]) repo.on(`before:${op}`, injectDeleteFilterToQuery, { priority: HOOK_PRIORITY.POLICY });
|
|
3799
3828
|
repo.on("before:updateMany", (context) => {
|
|
3800
3829
|
if (options.soft !== false) {
|
|
3801
3830
|
const deleteFilter = buildDeletedFilter(deletedField, filterMode, !!context.includeDeleted);
|
package/package.json
CHANGED