@classytic/mongokit 3.0.4 → 3.0.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/dist/actions/index.d.ts +2 -2
- package/dist/{index-wXrOSYWG.d.ts → index-CkwbNdpJ.d.ts} +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +274 -15
- package/dist/pagination/PaginationEngine.d.ts +1 -1
- package/dist/plugins/index.d.ts +1 -1
- package/dist/{queryParser-Bek4yy3x.d.ts → queryParser-Do3SgsyJ.d.ts} +55 -2
- package/dist/{types-DAl69QgM.d.ts → types-DDDYo18H.d.ts} +13 -20
- package/dist/utils/index.d.ts +4 -56
- package/dist/utils/index.js +1 -8
- package/package.json +1 -1
package/dist/actions/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as aggregate, c as create, _ as deleteActions, r as read, u as update } from '../index-
|
|
1
|
+
export { a as aggregate, c as create, _ as deleteActions, r as read, u as update } from '../index-CkwbNdpJ.js';
|
|
2
2
|
import 'mongoose';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-DDDYo18H.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Model, ClientSession, PipelineStage } from 'mongoose';
|
|
2
|
-
import { A as AnyDocument, C as CreateOptions,
|
|
2
|
+
import { A as AnyDocument, C as CreateOptions, h as ObjectId, n as OperationOptions, S as SelectSpec, e as PopulateSpec, f as SortSpec, U as UpdateOptions, p as UpdateWithValidationResult, o as UpdateManyResult, D as DeleteResult, X as GroupResult, T as LookupOptions, Y as MinMaxResult } from './types-DDDYo18H.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Create Actions
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { A as AnyDocument,
|
|
2
|
-
export { c as AggregatePaginationOptions, j as AnyModel,
|
|
1
|
+
import { A as AnyDocument, g as PluginType, P as PaginationConfig, R as RepositoryOptions, h as ObjectId, S as SelectSpec, e as PopulateSpec, f as SortSpec, a as OffsetPaginationResult, b as KeysetPaginationResult, U as UpdateOptions, d as AggregatePaginationResult, W as WithTransactionOptions, i as RepositoryContext, H as HttpError } from './types-DDDYo18H.js';
|
|
2
|
+
export { c as AggregatePaginationOptions, j as AnyModel, Z as CacheAdapter, $ as CacheOperationOptions, _ as CacheOptions, a0 as CacheStats, a2 as CascadeOptions, a1 as CascadeRelation, C as CreateOptions, z as CrudSchemas, B as DecodedCursor, D as DeleteResult, E as EventPayload, F as FieldPreset, x as FieldRules, w as FilterQuery, X as GroupResult, l as HookMode, J as JsonSchema, K as KeysetPaginationOptions, L as Logger, T as LookupOptions, Y as MinMaxResult, O as OffsetPaginationOptions, n as OperationOptions, m as PaginationResult, v as ParsedQuery, r as Plugin, s as PluginFunction, u as RepositoryEvent, t as RepositoryInstance, y as SchemaBuilderOptions, N as SoftDeleteFilterMode, M as SoftDeleteOptions, Q as SoftDeleteRepository, k as SortDirection, o as UpdateManyResult, p as UpdateWithValidationResult, q as UserContext, I as ValidationChainOptions, V as ValidationResult, G as ValidatorDefinition } from './types-DDDYo18H.js';
|
|
3
3
|
import * as mongoose from 'mongoose';
|
|
4
4
|
import { Model, ClientSession, PipelineStage, PopulateOptions } from 'mongoose';
|
|
5
5
|
import { PaginationEngine } from './pagination/PaginationEngine.js';
|
|
6
6
|
export { aggregateHelpersPlugin, auditLogPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, fieldFilterPlugin, immutableField, methodRegistryPlugin, mongoOperationsPlugin, requireField, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin } from './plugins/index.js';
|
|
7
|
-
export { F as FilterValue, O as OperatorMap, Q as QueryParser,
|
|
8
|
-
export { i as actions } from './index-
|
|
7
|
+
export { F as FilterValue, O as OperatorMap, Q as QueryParser, b as QueryParserOptions, h as buildCrudSchemasFromModel, e as buildCrudSchemasFromMongooseSchema, l as createError, c as createFieldPreset, m as createMemoryCache, f as filterResponseData, g as getFieldsForUser, i as getImmutableFields, a as getMongooseProjection, j as getSystemManagedFields, k as isFieldUpdateAllowed, d as queryParser, v as validateUpdateBody } from './queryParser-Do3SgsyJ.js';
|
|
8
|
+
export { i as actions } from './index-CkwbNdpJ.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Repository Pattern - Data Access Layer
|
|
@@ -203,7 +203,8 @@ declare class Repository<TDoc = AnyDocument> {
|
|
|
203
203
|
/**
|
|
204
204
|
* Execute callback within a transaction
|
|
205
205
|
*/
|
|
206
|
-
withTransaction<T>(callback: (session: ClientSession) => Promise<T
|
|
206
|
+
withTransaction<T>(callback: (session: ClientSession | null) => Promise<T>, options?: WithTransactionOptions): Promise<T>;
|
|
207
|
+
private _isTransactionUnsupported;
|
|
207
208
|
/**
|
|
208
209
|
* Execute custom query with event emission
|
|
209
210
|
*/
|
|
@@ -238,4 +239,4 @@ declare class Repository<TDoc = AnyDocument> {
|
|
|
238
239
|
*/
|
|
239
240
|
declare function createRepository<TDoc>(Model: mongoose.Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions): Repository<TDoc>;
|
|
240
241
|
|
|
241
|
-
export { AggregatePaginationResult, AnyDocument, HttpError, KeysetPaginationResult, ObjectId, OffsetPaginationResult, PaginationConfig, PaginationEngine, PluginType, PopulateSpec, Repository, RepositoryContext, RepositoryOptions, SelectSpec, SortSpec, UpdateOptions, createRepository, Repository as default };
|
|
242
|
+
export { AggregatePaginationResult, AnyDocument, HttpError, KeysetPaginationResult, ObjectId, OffsetPaginationResult, PaginationConfig, PaginationEngine, PluginType, PopulateSpec, Repository, RepositoryContext, RepositoryOptions, SelectSpec, SortSpec, UpdateOptions, WithTransactionOptions, createRepository, Repository as default };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import mongoose4 from 'mongoose';
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __export = (target, all) => {
|
|
@@ -521,12 +521,12 @@ function validateCursorVersion(cursorVersion, expectedVersion) {
|
|
|
521
521
|
}
|
|
522
522
|
function serializeValue(value) {
|
|
523
523
|
if (value instanceof Date) return value.toISOString();
|
|
524
|
-
if (value instanceof
|
|
524
|
+
if (value instanceof mongoose4.Types.ObjectId) return value.toString();
|
|
525
525
|
return value;
|
|
526
526
|
}
|
|
527
527
|
function getValueType(value) {
|
|
528
528
|
if (value instanceof Date) return "date";
|
|
529
|
-
if (value instanceof
|
|
529
|
+
if (value instanceof mongoose4.Types.ObjectId) return "objectid";
|
|
530
530
|
if (typeof value === "boolean") return "boolean";
|
|
531
531
|
if (typeof value === "number") return "number";
|
|
532
532
|
if (typeof value === "string") return "string";
|
|
@@ -537,7 +537,7 @@ function rehydrateValue(serialized, type) {
|
|
|
537
537
|
case "date":
|
|
538
538
|
return new Date(serialized);
|
|
539
539
|
case "objectid":
|
|
540
|
-
return new
|
|
540
|
+
return new mongoose4.Types.ObjectId(serialized);
|
|
541
541
|
case "boolean":
|
|
542
542
|
return Boolean(serialized);
|
|
543
543
|
case "number":
|
|
@@ -1108,20 +1108,41 @@ var Repository = class {
|
|
|
1108
1108
|
/**
|
|
1109
1109
|
* Execute callback within a transaction
|
|
1110
1110
|
*/
|
|
1111
|
-
async withTransaction(callback) {
|
|
1112
|
-
const session = await
|
|
1113
|
-
|
|
1111
|
+
async withTransaction(callback, options = {}) {
|
|
1112
|
+
const session = await mongoose4.startSession();
|
|
1113
|
+
let started = false;
|
|
1114
1114
|
try {
|
|
1115
|
+
session.startTransaction();
|
|
1116
|
+
started = true;
|
|
1115
1117
|
const result = await callback(session);
|
|
1116
1118
|
await session.commitTransaction();
|
|
1117
1119
|
return result;
|
|
1118
1120
|
} catch (error) {
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
+
const err = error;
|
|
1122
|
+
if (options.allowFallback && this._isTransactionUnsupported(err)) {
|
|
1123
|
+
if (typeof options.onFallback === "function") {
|
|
1124
|
+
options.onFallback(err);
|
|
1125
|
+
}
|
|
1126
|
+
if (started && session.inTransaction()) {
|
|
1127
|
+
try {
|
|
1128
|
+
await session.abortTransaction();
|
|
1129
|
+
} catch {
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return await callback(null);
|
|
1133
|
+
}
|
|
1134
|
+
if (started && session.inTransaction()) {
|
|
1135
|
+
await session.abortTransaction();
|
|
1136
|
+
}
|
|
1137
|
+
throw err;
|
|
1121
1138
|
} finally {
|
|
1122
1139
|
session.endSession();
|
|
1123
1140
|
}
|
|
1124
1141
|
}
|
|
1142
|
+
_isTransactionUnsupported(error) {
|
|
1143
|
+
const message = (error.message || "").toLowerCase();
|
|
1144
|
+
return message.includes("transaction numbers are only allowed on a replica set member") || message.includes("replica set") || message.includes("mongos");
|
|
1145
|
+
}
|
|
1125
1146
|
/**
|
|
1126
1147
|
* Execute custom query with event emission
|
|
1127
1148
|
*/
|
|
@@ -1172,11 +1193,11 @@ var Repository = class {
|
|
|
1172
1193
|
* Handle errors with proper HTTP status codes
|
|
1173
1194
|
*/
|
|
1174
1195
|
_handleError(error) {
|
|
1175
|
-
if (error instanceof
|
|
1196
|
+
if (error instanceof mongoose4.Error.ValidationError) {
|
|
1176
1197
|
const messages = Object.values(error.errors).map((err) => err.message);
|
|
1177
1198
|
return createError(400, `Validation Error: ${messages.join(", ")}`);
|
|
1178
1199
|
}
|
|
1179
|
-
if (error instanceof
|
|
1200
|
+
if (error instanceof mongoose4.Error.CastError) {
|
|
1180
1201
|
return createError(400, `Invalid ${error.path}: ${error.value}`);
|
|
1181
1202
|
}
|
|
1182
1203
|
if (error.status && error.message) return error;
|
|
@@ -2207,7 +2228,7 @@ function cascadePlugin(options) {
|
|
|
2207
2228
|
}
|
|
2208
2229
|
const isSoftDelete = context.softDeleted === true;
|
|
2209
2230
|
const cascadeDelete = async (relation) => {
|
|
2210
|
-
const RelatedModel =
|
|
2231
|
+
const RelatedModel = mongoose4.models[relation.model];
|
|
2211
2232
|
if (!RelatedModel) {
|
|
2212
2233
|
logger?.warn?.(`Cascade delete skipped: model '${relation.model}' not found`, {
|
|
2213
2234
|
parentModel: context.model,
|
|
@@ -2298,7 +2319,7 @@ function cascadePlugin(options) {
|
|
|
2298
2319
|
}
|
|
2299
2320
|
const isSoftDelete = context.softDeleted === true;
|
|
2300
2321
|
const cascadeDeleteMany = async (relation) => {
|
|
2301
|
-
const RelatedModel =
|
|
2322
|
+
const RelatedModel = mongoose4.models[relation.model];
|
|
2302
2323
|
if (!RelatedModel) {
|
|
2303
2324
|
logger?.warn?.(`Cascade deleteMany skipped: model '${relation.model}' not found`, {
|
|
2304
2325
|
parentModel: context.model
|
|
@@ -2414,6 +2435,244 @@ function createMemoryCache(maxEntries = 1e3) {
|
|
|
2414
2435
|
}
|
|
2415
2436
|
};
|
|
2416
2437
|
}
|
|
2438
|
+
function isMongooseSchema(value) {
|
|
2439
|
+
return value instanceof mongoose4.Schema;
|
|
2440
|
+
}
|
|
2441
|
+
function isPlainObject(value) {
|
|
2442
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
2443
|
+
}
|
|
2444
|
+
function isObjectIdType(t) {
|
|
2445
|
+
return t === mongoose4.Schema.Types.ObjectId || t === mongoose4.Types.ObjectId;
|
|
2446
|
+
}
|
|
2447
|
+
function buildCrudSchemasFromMongooseSchema(mongooseSchema, options = {}) {
|
|
2448
|
+
const tree = mongooseSchema?.obj || {};
|
|
2449
|
+
const jsonCreate = buildJsonSchemaForCreate(tree, options);
|
|
2450
|
+
const jsonUpdate = buildJsonSchemaForUpdate(jsonCreate, options);
|
|
2451
|
+
const jsonParams = {
|
|
2452
|
+
type: "object",
|
|
2453
|
+
properties: { id: { type: "string", pattern: "^[0-9a-fA-F]{24}$" } },
|
|
2454
|
+
required: ["id"]
|
|
2455
|
+
};
|
|
2456
|
+
const jsonQuery = buildJsonSchemaForQuery(tree, options);
|
|
2457
|
+
return { createBody: jsonCreate, updateBody: jsonUpdate, params: jsonParams, listQuery: jsonQuery };
|
|
2458
|
+
}
|
|
2459
|
+
function buildCrudSchemasFromModel(mongooseModel, options = {}) {
|
|
2460
|
+
if (!mongooseModel || !mongooseModel.schema) {
|
|
2461
|
+
throw new Error("Invalid mongoose model");
|
|
2462
|
+
}
|
|
2463
|
+
return buildCrudSchemasFromMongooseSchema(mongooseModel.schema, options);
|
|
2464
|
+
}
|
|
2465
|
+
function getImmutableFields(options = {}) {
|
|
2466
|
+
const immutable = [];
|
|
2467
|
+
const fieldRules = options?.fieldRules || {};
|
|
2468
|
+
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
2469
|
+
if (rules.immutable || rules.immutableAfterCreate) {
|
|
2470
|
+
immutable.push(field);
|
|
2471
|
+
}
|
|
2472
|
+
});
|
|
2473
|
+
(options?.update?.omitFields || []).forEach((f) => {
|
|
2474
|
+
if (!immutable.includes(f)) immutable.push(f);
|
|
2475
|
+
});
|
|
2476
|
+
return immutable;
|
|
2477
|
+
}
|
|
2478
|
+
function getSystemManagedFields(options = {}) {
|
|
2479
|
+
const systemManaged = [];
|
|
2480
|
+
const fieldRules = options?.fieldRules || {};
|
|
2481
|
+
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
2482
|
+
if (rules.systemManaged) {
|
|
2483
|
+
systemManaged.push(field);
|
|
2484
|
+
}
|
|
2485
|
+
});
|
|
2486
|
+
return systemManaged;
|
|
2487
|
+
}
|
|
2488
|
+
function isFieldUpdateAllowed(fieldName, options = {}) {
|
|
2489
|
+
const immutableFields = getImmutableFields(options);
|
|
2490
|
+
const systemManagedFields = getSystemManagedFields(options);
|
|
2491
|
+
return !immutableFields.includes(fieldName) && !systemManagedFields.includes(fieldName);
|
|
2492
|
+
}
|
|
2493
|
+
function validateUpdateBody(body = {}, options = {}) {
|
|
2494
|
+
const violations = [];
|
|
2495
|
+
const immutableFields = getImmutableFields(options);
|
|
2496
|
+
const systemManagedFields = getSystemManagedFields(options);
|
|
2497
|
+
Object.keys(body).forEach((field) => {
|
|
2498
|
+
if (immutableFields.includes(field)) {
|
|
2499
|
+
violations.push({ field, reason: "Field is immutable" });
|
|
2500
|
+
} else if (systemManagedFields.includes(field)) {
|
|
2501
|
+
violations.push({ field, reason: "Field is system-managed" });
|
|
2502
|
+
}
|
|
2503
|
+
});
|
|
2504
|
+
return {
|
|
2505
|
+
valid: violations.length === 0,
|
|
2506
|
+
violations
|
|
2507
|
+
};
|
|
2508
|
+
}
|
|
2509
|
+
function jsonTypeFor(def, options, seen) {
|
|
2510
|
+
if (Array.isArray(def)) {
|
|
2511
|
+
if (def[0] === mongoose4.Schema.Types.Mixed) {
|
|
2512
|
+
return { type: "array", items: { type: "object", additionalProperties: true } };
|
|
2513
|
+
}
|
|
2514
|
+
return { type: "array", items: jsonTypeFor(def[0] ?? String, options, seen) };
|
|
2515
|
+
}
|
|
2516
|
+
if (isPlainObject(def) && "type" in def) {
|
|
2517
|
+
const typedDef = def;
|
|
2518
|
+
if (typedDef.enum && Array.isArray(typedDef.enum) && typedDef.enum.length) {
|
|
2519
|
+
return { type: "string", enum: typedDef.enum.map(String) };
|
|
2520
|
+
}
|
|
2521
|
+
if (Array.isArray(typedDef.type)) {
|
|
2522
|
+
const inner = typedDef.type[0] !== void 0 ? typedDef.type[0] : String;
|
|
2523
|
+
if (inner === mongoose4.Schema.Types.Mixed) {
|
|
2524
|
+
return { type: "array", items: { type: "object", additionalProperties: true } };
|
|
2525
|
+
}
|
|
2526
|
+
return { type: "array", items: jsonTypeFor(inner, options, seen) };
|
|
2527
|
+
}
|
|
2528
|
+
if (typedDef.type === String) return { type: "string" };
|
|
2529
|
+
if (typedDef.type === Number) return { type: "number" };
|
|
2530
|
+
if (typedDef.type === Boolean) return { type: "boolean" };
|
|
2531
|
+
if (typedDef.type === Date) {
|
|
2532
|
+
const mode = options?.dateAs || "datetime";
|
|
2533
|
+
return mode === "date" ? { type: "string", format: "date" } : { type: "string", format: "date-time" };
|
|
2534
|
+
}
|
|
2535
|
+
if (typedDef.type === Map || typedDef.type === mongoose4.Schema.Types.Map) {
|
|
2536
|
+
const ofSchema = jsonTypeFor(typedDef.of || String, options, seen);
|
|
2537
|
+
return { type: "object", additionalProperties: ofSchema };
|
|
2538
|
+
}
|
|
2539
|
+
if (typedDef.type === mongoose4.Schema.Types.Mixed) {
|
|
2540
|
+
return { type: "object", additionalProperties: true };
|
|
2541
|
+
}
|
|
2542
|
+
if (isObjectIdType(typedDef.type)) {
|
|
2543
|
+
return { type: "string", pattern: "^[0-9a-fA-F]{24}$" };
|
|
2544
|
+
}
|
|
2545
|
+
if (isMongooseSchema(typedDef.type)) {
|
|
2546
|
+
const obj = typedDef.type.obj;
|
|
2547
|
+
if (obj && typeof obj === "object") {
|
|
2548
|
+
if (seen.has(obj)) return { type: "object", additionalProperties: true };
|
|
2549
|
+
seen.add(obj);
|
|
2550
|
+
return convertTreeToJsonSchema(obj, options, seen);
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
if (def === String) return { type: "string" };
|
|
2555
|
+
if (def === Number) return { type: "number" };
|
|
2556
|
+
if (def === Boolean) return { type: "boolean" };
|
|
2557
|
+
if (def === Date) {
|
|
2558
|
+
const mode = options?.dateAs || "datetime";
|
|
2559
|
+
return mode === "date" ? { type: "string", format: "date" } : { type: "string", format: "date-time" };
|
|
2560
|
+
}
|
|
2561
|
+
if (isObjectIdType(def)) return { type: "string", pattern: "^[0-9a-fA-F]{24}$" };
|
|
2562
|
+
if (isPlainObject(def)) {
|
|
2563
|
+
if (seen.has(def)) return { type: "object", additionalProperties: true };
|
|
2564
|
+
seen.add(def);
|
|
2565
|
+
return convertTreeToJsonSchema(def, options, seen);
|
|
2566
|
+
}
|
|
2567
|
+
return {};
|
|
2568
|
+
}
|
|
2569
|
+
function convertTreeToJsonSchema(tree, options, seen = /* @__PURE__ */ new WeakSet()) {
|
|
2570
|
+
if (!tree || typeof tree !== "object") {
|
|
2571
|
+
return { type: "object", properties: {} };
|
|
2572
|
+
}
|
|
2573
|
+
if (seen.has(tree)) {
|
|
2574
|
+
return { type: "object", additionalProperties: true };
|
|
2575
|
+
}
|
|
2576
|
+
seen.add(tree);
|
|
2577
|
+
const properties = {};
|
|
2578
|
+
const required = [];
|
|
2579
|
+
for (const [key, val] of Object.entries(tree || {})) {
|
|
2580
|
+
if (key === "__v" || key === "_id" || key === "id") continue;
|
|
2581
|
+
const cfg = isPlainObject(val) && "type" in val ? val : { };
|
|
2582
|
+
properties[key] = jsonTypeFor(val, options, seen);
|
|
2583
|
+
if (cfg.required === true) required.push(key);
|
|
2584
|
+
}
|
|
2585
|
+
const schema = { type: "object", properties };
|
|
2586
|
+
if (required.length) schema.required = required;
|
|
2587
|
+
return schema;
|
|
2588
|
+
}
|
|
2589
|
+
function buildJsonSchemaForCreate(tree, options) {
|
|
2590
|
+
const base = convertTreeToJsonSchema(tree, options, /* @__PURE__ */ new WeakSet());
|
|
2591
|
+
const fieldsToOmit = /* @__PURE__ */ new Set(["createdAt", "updatedAt", "__v"]);
|
|
2592
|
+
(options?.create?.omitFields || []).forEach((f) => fieldsToOmit.add(f));
|
|
2593
|
+
const fieldRules = options?.fieldRules || {};
|
|
2594
|
+
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
2595
|
+
if (rules.systemManaged) {
|
|
2596
|
+
fieldsToOmit.add(field);
|
|
2597
|
+
}
|
|
2598
|
+
});
|
|
2599
|
+
fieldsToOmit.forEach((field) => {
|
|
2600
|
+
if (base.properties?.[field]) {
|
|
2601
|
+
delete base.properties[field];
|
|
2602
|
+
}
|
|
2603
|
+
if (base.required) {
|
|
2604
|
+
base.required = base.required.filter((k) => k !== field);
|
|
2605
|
+
}
|
|
2606
|
+
});
|
|
2607
|
+
const reqOv = options?.create?.requiredOverrides || {};
|
|
2608
|
+
const optOv = options?.create?.optionalOverrides || {};
|
|
2609
|
+
base.required = base.required || [];
|
|
2610
|
+
for (const [k, v] of Object.entries(reqOv)) {
|
|
2611
|
+
if (v && !base.required.includes(k)) base.required.push(k);
|
|
2612
|
+
}
|
|
2613
|
+
for (const [k, v] of Object.entries(optOv)) {
|
|
2614
|
+
if (v && base.required) base.required = base.required.filter((x) => x !== k);
|
|
2615
|
+
}
|
|
2616
|
+
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
2617
|
+
if (rules.optional && base.required) {
|
|
2618
|
+
base.required = base.required.filter((x) => x !== field);
|
|
2619
|
+
}
|
|
2620
|
+
});
|
|
2621
|
+
const schemaOverrides = options?.create?.schemaOverrides || {};
|
|
2622
|
+
for (const [k, override] of Object.entries(schemaOverrides)) {
|
|
2623
|
+
if (base.properties?.[k]) {
|
|
2624
|
+
base.properties[k] = override;
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
if (options?.strictAdditionalProperties === true) {
|
|
2628
|
+
base.additionalProperties = false;
|
|
2629
|
+
}
|
|
2630
|
+
return base;
|
|
2631
|
+
}
|
|
2632
|
+
function buildJsonSchemaForUpdate(createJson, options) {
|
|
2633
|
+
const clone = JSON.parse(JSON.stringify(createJson));
|
|
2634
|
+
delete clone.required;
|
|
2635
|
+
const fieldsToOmit = /* @__PURE__ */ new Set();
|
|
2636
|
+
(options?.update?.omitFields || []).forEach((f) => fieldsToOmit.add(f));
|
|
2637
|
+
const fieldRules = options?.fieldRules || {};
|
|
2638
|
+
Object.entries(fieldRules).forEach(([field, rules]) => {
|
|
2639
|
+
if (rules.immutable || rules.immutableAfterCreate) {
|
|
2640
|
+
fieldsToOmit.add(field);
|
|
2641
|
+
}
|
|
2642
|
+
});
|
|
2643
|
+
fieldsToOmit.forEach((field) => {
|
|
2644
|
+
if (clone.properties?.[field]) {
|
|
2645
|
+
delete clone.properties[field];
|
|
2646
|
+
}
|
|
2647
|
+
});
|
|
2648
|
+
if (options?.strictAdditionalProperties === true) {
|
|
2649
|
+
clone.additionalProperties = false;
|
|
2650
|
+
}
|
|
2651
|
+
return clone;
|
|
2652
|
+
}
|
|
2653
|
+
function buildJsonSchemaForQuery(_tree, options) {
|
|
2654
|
+
const basePagination = {
|
|
2655
|
+
type: "object",
|
|
2656
|
+
properties: {
|
|
2657
|
+
page: { type: "string" },
|
|
2658
|
+
limit: { type: "string" },
|
|
2659
|
+
sort: { type: "string" },
|
|
2660
|
+
populate: { type: "string" },
|
|
2661
|
+
search: { type: "string" },
|
|
2662
|
+
select: { type: "string" },
|
|
2663
|
+
lean: { type: "string" },
|
|
2664
|
+
includeDeleted: { type: "string" }
|
|
2665
|
+
},
|
|
2666
|
+
additionalProperties: true
|
|
2667
|
+
};
|
|
2668
|
+
const filterable = options?.query?.filterableFields || {};
|
|
2669
|
+
for (const [k, v] of Object.entries(filterable)) {
|
|
2670
|
+
if (basePagination.properties) {
|
|
2671
|
+
basePagination.properties[k] = v && typeof v === "object" && "type" in v ? v : { type: "string" };
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
return basePagination;
|
|
2675
|
+
}
|
|
2417
2676
|
var QueryParser = class {
|
|
2418
2677
|
options;
|
|
2419
2678
|
operators = {
|
|
@@ -2687,7 +2946,7 @@ var QueryParser = class {
|
|
|
2687
2946
|
const stringValue = String(value);
|
|
2688
2947
|
if (stringValue === "true") return true;
|
|
2689
2948
|
if (stringValue === "false") return false;
|
|
2690
|
-
if (
|
|
2949
|
+
if (mongoose4.Types.ObjectId.isValid(stringValue) && stringValue.length === 24) {
|
|
2691
2950
|
return stringValue;
|
|
2692
2951
|
}
|
|
2693
2952
|
return stringValue;
|
|
@@ -2784,4 +3043,4 @@ var index_default = Repository;
|
|
|
2784
3043
|
* ```
|
|
2785
3044
|
*/
|
|
2786
3045
|
|
|
2787
|
-
export { PaginationEngine, QueryParser, Repository, actions_exports as actions, aggregateHelpersPlugin, auditLogPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, createError, createFieldPreset, createMemoryCache, createRepository, index_default as default, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, immutableField, methodRegistryPlugin, mongoOperationsPlugin, queryParser_default as queryParser, requireField, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
|
|
3046
|
+
export { PaginationEngine, QueryParser, Repository, actions_exports as actions, aggregateHelpersPlugin, auditLogPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, createError, createFieldPreset, createMemoryCache, createRepository, index_default as default, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getSystemManagedFields, immutableField, isFieldUpdateAllowed, methodRegistryPlugin, mongoOperationsPlugin, queryParser_default as queryParser, requireField, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Model } from 'mongoose';
|
|
2
|
-
import { A as AnyDocument, P as PaginationConfig, O as OffsetPaginationOptions, a as OffsetPaginationResult, K as KeysetPaginationOptions, b as KeysetPaginationResult, c as AggregatePaginationOptions, d as AggregatePaginationResult } from '../types-
|
|
2
|
+
import { A as AnyDocument, P as PaginationConfig, O as OffsetPaginationOptions, a as OffsetPaginationResult, K as KeysetPaginationOptions, b as KeysetPaginationResult, c as AggregatePaginationOptions, d as AggregatePaginationResult } from '../types-DDDYo18H.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Pagination Engine
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as FieldPreset, r as Plugin, L as Logger, M as SoftDeleteOptions, t as RepositoryInstance, G as ValidatorDefinition, I as ValidationChainOptions, i as RepositoryContext,
|
|
1
|
+
import { F as FieldPreset, r as Plugin, L as Logger, M as SoftDeleteOptions, t as RepositoryInstance, G as ValidatorDefinition, I as ValidationChainOptions, i as RepositoryContext, _ as CacheOptions, a2 as CascadeOptions } from '../types-DDDYo18H.js';
|
|
2
2
|
import 'mongoose';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { q as UserContext, F as FieldPreset, H as HttpError,
|
|
1
|
+
import { q as UserContext, F as FieldPreset, H as HttpError, Z as CacheAdapter, y as SchemaBuilderOptions, z as CrudSchemas, V as ValidationResult, v as ParsedQuery } from './types-DDDYo18H.js';
|
|
2
|
+
import mongoose__default, { Schema } from 'mongoose';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Field Selection Utilities
|
|
@@ -139,6 +140,58 @@ declare function createError(status: number, message: string): HttpError;
|
|
|
139
140
|
*/
|
|
140
141
|
declare function createMemoryCache(maxEntries?: number): CacheAdapter;
|
|
141
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Mongoose to JSON Schema Converter with Field Rules
|
|
145
|
+
*
|
|
146
|
+
* Generates Fastify JSON schemas from Mongoose models with declarative field rules.
|
|
147
|
+
*
|
|
148
|
+
* Field Rules (options.fieldRules):
|
|
149
|
+
* - immutable: Field cannot be updated (omitted from update schema)
|
|
150
|
+
* - immutableAfterCreate: Alias for immutable
|
|
151
|
+
* - systemManaged: System-only field (omitted from create/update)
|
|
152
|
+
* - optional: Remove from required array
|
|
153
|
+
*
|
|
154
|
+
* Additional Options:
|
|
155
|
+
* - strictAdditionalProperties: Set to true to add "additionalProperties: false" to schemas
|
|
156
|
+
* This makes Fastify reject unknown fields at validation level (default: false for backward compatibility)
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* buildCrudSchemasFromModel(Model, {
|
|
160
|
+
* strictAdditionalProperties: true, // Reject unknown fields
|
|
161
|
+
* fieldRules: {
|
|
162
|
+
* organizationId: { immutable: true },
|
|
163
|
+
* status: { systemManaged: true },
|
|
164
|
+
* },
|
|
165
|
+
* create: { omitFields: ['verifiedAt'] },
|
|
166
|
+
* update: { omitFields: ['customerId'] }
|
|
167
|
+
* })
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Build CRUD schemas from Mongoose schema
|
|
172
|
+
*/
|
|
173
|
+
declare function buildCrudSchemasFromMongooseSchema(mongooseSchema: Schema, options?: SchemaBuilderOptions): CrudSchemas;
|
|
174
|
+
/**
|
|
175
|
+
* Build CRUD schemas from Mongoose model
|
|
176
|
+
*/
|
|
177
|
+
declare function buildCrudSchemasFromModel(mongooseModel: mongoose__default.Model<unknown>, options?: SchemaBuilderOptions): CrudSchemas;
|
|
178
|
+
/**
|
|
179
|
+
* Get fields that are immutable (cannot be updated)
|
|
180
|
+
*/
|
|
181
|
+
declare function getImmutableFields(options?: SchemaBuilderOptions): string[];
|
|
182
|
+
/**
|
|
183
|
+
* Get fields that are system-managed (cannot be set by users)
|
|
184
|
+
*/
|
|
185
|
+
declare function getSystemManagedFields(options?: SchemaBuilderOptions): string[];
|
|
186
|
+
/**
|
|
187
|
+
* Check if field is allowed in update
|
|
188
|
+
*/
|
|
189
|
+
declare function isFieldUpdateAllowed(fieldName: string, options?: SchemaBuilderOptions): boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Validate update body against field rules
|
|
192
|
+
*/
|
|
193
|
+
declare function validateUpdateBody(body?: Record<string, unknown>, options?: SchemaBuilderOptions): ValidationResult;
|
|
194
|
+
|
|
142
195
|
/**
|
|
143
196
|
* Query Parser
|
|
144
197
|
*
|
|
@@ -247,4 +300,4 @@ declare class QueryParser {
|
|
|
247
300
|
/** Default query parser instance with standard options */
|
|
248
301
|
declare const defaultQueryParser: QueryParser;
|
|
249
302
|
|
|
250
|
-
export { type FilterValue as F, type OperatorMap as O, QueryParser as Q, getMongooseProjection as a,
|
|
303
|
+
export { type FilterValue as F, type OperatorMap as O, QueryParser as Q, getMongooseProjection as a, type QueryParserOptions as b, createFieldPreset as c, defaultQueryParser as d, buildCrudSchemasFromMongooseSchema as e, filterResponseData as f, getFieldsForUser as g, buildCrudSchemasFromModel as h, getImmutableFields as i, getSystemManagedFields as j, isFieldUpdateAllowed as k, createError as l, createMemoryCache as m, validateUpdateBody as v };
|
|
@@ -158,6 +158,13 @@ interface OperationOptions {
|
|
|
158
158
|
/** Additional query filters (e.g., for soft delete) */
|
|
159
159
|
query?: Record<string, unknown>;
|
|
160
160
|
}
|
|
161
|
+
/** withTransaction options */
|
|
162
|
+
interface WithTransactionOptions {
|
|
163
|
+
/** Allow non-transactional fallback when transactions are unsupported */
|
|
164
|
+
allowFallback?: boolean;
|
|
165
|
+
/** Optional hook to observe fallback triggers */
|
|
166
|
+
onFallback?: (error: Error) => void;
|
|
167
|
+
}
|
|
161
168
|
/** Create operation options */
|
|
162
169
|
interface CreateOptions {
|
|
163
170
|
/** MongoDB session for transactions */
|
|
@@ -348,30 +355,16 @@ interface JsonSchema {
|
|
|
348
355
|
format?: string;
|
|
349
356
|
pattern?: string;
|
|
350
357
|
}
|
|
351
|
-
/** CRUD schemas result */
|
|
358
|
+
/** CRUD schemas result - framework-agnostic JSON schemas */
|
|
352
359
|
interface CrudSchemas {
|
|
360
|
+
/** JSON Schema for create request body */
|
|
353
361
|
createBody: JsonSchema;
|
|
362
|
+
/** JSON Schema for update request body */
|
|
354
363
|
updateBody: JsonSchema;
|
|
364
|
+
/** JSON Schema for route params (id validation) */
|
|
355
365
|
params: JsonSchema;
|
|
366
|
+
/** JSON Schema for list/query parameters */
|
|
356
367
|
listQuery: JsonSchema;
|
|
357
|
-
crudSchemas: {
|
|
358
|
-
create: {
|
|
359
|
-
body: JsonSchema;
|
|
360
|
-
};
|
|
361
|
-
update: {
|
|
362
|
-
body: JsonSchema;
|
|
363
|
-
params: JsonSchema;
|
|
364
|
-
};
|
|
365
|
-
get: {
|
|
366
|
-
params: JsonSchema;
|
|
367
|
-
};
|
|
368
|
-
list: {
|
|
369
|
-
query: JsonSchema;
|
|
370
|
-
};
|
|
371
|
-
remove: {
|
|
372
|
-
params: JsonSchema;
|
|
373
|
-
};
|
|
374
|
-
};
|
|
375
368
|
}
|
|
376
369
|
/** Decoded cursor */
|
|
377
370
|
interface DecodedCursor {
|
|
@@ -580,4 +573,4 @@ interface HttpError extends Error {
|
|
|
580
573
|
}>;
|
|
581
574
|
}
|
|
582
575
|
|
|
583
|
-
export type {
|
|
576
|
+
export type { CacheOperationOptions as $, AnyDocument as A, DecodedCursor as B, CreateOptions as C, DeleteResult as D, EventPayload as E, FieldPreset as F, ValidatorDefinition as G, HttpError as H, ValidationChainOptions as I, JsonSchema as J, KeysetPaginationOptions as K, Logger as L, SoftDeleteOptions as M, SoftDeleteFilterMode as N, OffsetPaginationOptions as O, PaginationConfig as P, SoftDeleteRepository as Q, RepositoryOptions as R, SelectSpec as S, LookupOptions as T, UpdateOptions as U, ValidationResult as V, WithTransactionOptions as W, GroupResult as X, MinMaxResult as Y, CacheAdapter as Z, CacheOptions as _, OffsetPaginationResult as a, CacheStats as a0, CascadeRelation as a1, CascadeOptions as a2, KeysetPaginationResult as b, AggregatePaginationOptions as c, AggregatePaginationResult as d, PopulateSpec as e, SortSpec as f, PluginType as g, ObjectId as h, RepositoryContext as i, AnyModel as j, SortDirection as k, HookMode as l, PaginationResult as m, OperationOptions as n, UpdateManyResult as o, UpdateWithValidationResult as p, UserContext as q, Plugin as r, PluginFunction as s, RepositoryInstance as t, RepositoryEvent as u, ParsedQuery as v, FilterQuery as w, FieldRules as x, SchemaBuilderOptions as y, CrudSchemas as z };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,58 +1,6 @@
|
|
|
1
|
-
export { F as FilterValue, O as OperatorMap, Q as QueryParser,
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Mongoose to JSON Schema Converter with Field Rules
|
|
7
|
-
*
|
|
8
|
-
* Generates Fastify JSON schemas from Mongoose models with declarative field rules.
|
|
9
|
-
*
|
|
10
|
-
* Field Rules (options.fieldRules):
|
|
11
|
-
* - immutable: Field cannot be updated (omitted from update schema)
|
|
12
|
-
* - immutableAfterCreate: Alias for immutable
|
|
13
|
-
* - systemManaged: System-only field (omitted from create/update)
|
|
14
|
-
* - optional: Remove from required array
|
|
15
|
-
*
|
|
16
|
-
* Additional Options:
|
|
17
|
-
* - strictAdditionalProperties: Set to true to add "additionalProperties: false" to schemas
|
|
18
|
-
* This makes Fastify reject unknown fields at validation level (default: false for backward compatibility)
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* buildCrudSchemasFromModel(Model, {
|
|
22
|
-
* strictAdditionalProperties: true, // Reject unknown fields
|
|
23
|
-
* fieldRules: {
|
|
24
|
-
* organizationId: { immutable: true },
|
|
25
|
-
* status: { systemManaged: true },
|
|
26
|
-
* },
|
|
27
|
-
* create: { omitFields: ['verifiedAt'] },
|
|
28
|
-
* update: { omitFields: ['customerId'] }
|
|
29
|
-
* })
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Build CRUD schemas from Mongoose schema
|
|
34
|
-
*/
|
|
35
|
-
declare function buildCrudSchemasFromMongooseSchema(mongooseSchema: Schema, options?: SchemaBuilderOptions): CrudSchemas;
|
|
36
|
-
/**
|
|
37
|
-
* Build CRUD schemas from Mongoose model
|
|
38
|
-
*/
|
|
39
|
-
declare function buildCrudSchemasFromModel(mongooseModel: mongoose__default.Model<unknown>, options?: SchemaBuilderOptions): CrudSchemas;
|
|
40
|
-
/**
|
|
41
|
-
* Get fields that are immutable (cannot be updated)
|
|
42
|
-
*/
|
|
43
|
-
declare function getImmutableFields(options?: SchemaBuilderOptions): string[];
|
|
44
|
-
/**
|
|
45
|
-
* Get fields that are system-managed (cannot be set by users)
|
|
46
|
-
*/
|
|
47
|
-
declare function getSystemManagedFields(options?: SchemaBuilderOptions): string[];
|
|
48
|
-
/**
|
|
49
|
-
* Check if field is allowed in update
|
|
50
|
-
*/
|
|
51
|
-
declare function isFieldUpdateAllowed(fieldName: string, options?: SchemaBuilderOptions): boolean;
|
|
52
|
-
/**
|
|
53
|
-
* Validate update body against field rules
|
|
54
|
-
*/
|
|
55
|
-
declare function validateUpdateBody(body?: Record<string, unknown>, options?: SchemaBuilderOptions): ValidationResult;
|
|
1
|
+
export { F as FilterValue, O as OperatorMap, Q as QueryParser, b as QueryParserOptions, h as buildCrudSchemasFromModel, e as buildCrudSchemasFromMongooseSchema, l as createError, c as createFieldPreset, m as createMemoryCache, f as filterResponseData, g as getFieldsForUser, i as getImmutableFields, a as getMongooseProjection, j as getSystemManagedFields, k as isFieldUpdateAllowed, d as queryParser, v as validateUpdateBody } from '../queryParser-Do3SgsyJ.js';
|
|
2
|
+
import { S as SelectSpec, e as PopulateSpec, f as SortSpec } from '../types-DDDYo18H.js';
|
|
3
|
+
import 'mongoose';
|
|
56
4
|
|
|
57
5
|
/**
|
|
58
6
|
* Cache Key Utilities
|
|
@@ -131,4 +79,4 @@ declare function modelPattern(prefix: string, model: string): string;
|
|
|
131
79
|
*/
|
|
132
80
|
declare function listPattern(prefix: string, model: string): string;
|
|
133
81
|
|
|
134
|
-
export {
|
|
82
|
+
export { byIdKey, byQueryKey, listPattern, listQueryKey, modelPattern, versionKey };
|
package/dist/utils/index.js
CHANGED
|
@@ -379,14 +379,7 @@ function buildCrudSchemasFromMongooseSchema(mongooseSchema, options = {}) {
|
|
|
379
379
|
required: ["id"]
|
|
380
380
|
};
|
|
381
381
|
const jsonQuery = buildJsonSchemaForQuery(tree, options);
|
|
382
|
-
|
|
383
|
-
create: { body: jsonCreate },
|
|
384
|
-
update: { body: jsonUpdate, params: jsonParams },
|
|
385
|
-
get: { params: jsonParams },
|
|
386
|
-
list: { query: jsonQuery },
|
|
387
|
-
remove: { params: jsonParams }
|
|
388
|
-
};
|
|
389
|
-
return { createBody: jsonCreate, updateBody: jsonUpdate, params: jsonParams, listQuery: jsonQuery, crudSchemas };
|
|
382
|
+
return { createBody: jsonCreate, updateBody: jsonUpdate, params: jsonParams, listQuery: jsonQuery };
|
|
390
383
|
}
|
|
391
384
|
function buildCrudSchemasFromModel(mongooseModel, options = {}) {
|
|
392
385
|
if (!mongooseModel || !mongooseModel.schema) {
|
package/package.json
CHANGED