monsqlize 3.0.0 → 3.1.0
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/CHANGELOG.md +3 -2
- package/MIGRATION.md +22 -0
- package/README.md +11 -7
- package/changelogs/v3.0.0.md +4 -2
- package/changelogs/v3.1.0-rc.0.md +23 -0
- package/changelogs/v3.1.0.md +24 -0
- package/dist/cjs/cli/data-task.cjs +169 -17557
- package/dist/cjs/index.cjs +168 -65
- package/dist/esm/index.mjs +168 -65
- package/licenses/production-dependencies.json +11 -0
- package/package.json +21 -5
package/dist/cjs/index.cjs
CHANGED
|
@@ -769,31 +769,51 @@ async function runModelV1Hook(hooksFactory, model, operation, phase, context, ..
|
|
|
769
769
|
}
|
|
770
770
|
return hook(context, ...args);
|
|
771
771
|
}
|
|
772
|
+
function mapModelSchemaValidationErrors(errors = []) {
|
|
773
|
+
return errors.map((error) => ({
|
|
774
|
+
field: error.path ?? "",
|
|
775
|
+
message: error.message ?? ""
|
|
776
|
+
}));
|
|
777
|
+
}
|
|
772
778
|
function validateModelSchemaPayload(context, document, options, metadata = {}) {
|
|
773
779
|
const shouldValidate = context.validateEnabled || options?.validate === true;
|
|
774
780
|
if (!shouldValidate) {
|
|
775
|
-
return;
|
|
781
|
+
return document;
|
|
776
782
|
}
|
|
777
783
|
if (options?.skipValidation) {
|
|
778
|
-
return;
|
|
784
|
+
return document;
|
|
779
785
|
}
|
|
780
786
|
if (!context.schemaCache || !context.schemaValidateFn) {
|
|
781
|
-
return;
|
|
787
|
+
return document;
|
|
782
788
|
}
|
|
783
789
|
const result = context.schemaValidateFn(context.schemaCache, document);
|
|
784
|
-
if (result.valid) {
|
|
785
|
-
|
|
790
|
+
if (!result.valid) {
|
|
791
|
+
const errors = mapModelSchemaValidationErrors(result.errors);
|
|
792
|
+
const fields = [...new Set(errors.map((item) => item.field).filter(Boolean))];
|
|
793
|
+
const summary = fields.length > 0 ? ` (${fields.join(", ")})` : "";
|
|
794
|
+
throw withModelErrorMetadata(
|
|
795
|
+
createError(ErrorCodes.VALIDATION_ERROR, `Schema validation failed${summary}`),
|
|
796
|
+
{
|
|
797
|
+
errors,
|
|
798
|
+
...metadata
|
|
799
|
+
}
|
|
800
|
+
);
|
|
786
801
|
}
|
|
787
|
-
const
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
802
|
+
const normalized = result.data === void 0 ? document : result.data;
|
|
803
|
+
if (normalized === null || typeof normalized !== "object" || Array.isArray(normalized)) {
|
|
804
|
+
const errors = [{
|
|
805
|
+
field: "_schema",
|
|
806
|
+
message: "Schema validation returned non-object data for a complete-document write."
|
|
807
|
+
}];
|
|
808
|
+
throw withModelErrorMetadata(
|
|
809
|
+
createError(ErrorCodes.VALIDATION_ERROR, errors[0].message),
|
|
810
|
+
{
|
|
811
|
+
errors,
|
|
812
|
+
...metadata
|
|
813
|
+
}
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
return normalized;
|
|
797
817
|
}
|
|
798
818
|
function applyModelSoftDeleteFilter(query, options, softDeleteConfig) {
|
|
799
819
|
if (!softDeleteConfig?.enabled) {
|
|
@@ -999,6 +1019,19 @@ function applyModelReplaceTimestamps(replacement, timestampsConfig, nowFactory)
|
|
|
999
1019
|
[timestampsConfig.updatedAt]: nowFactory()
|
|
1000
1020
|
};
|
|
1001
1021
|
}
|
|
1022
|
+
function preserveModelReplaceCreatedAt(original, normalized, timestampsConfig) {
|
|
1023
|
+
if (!timestampsConfig || timestampsConfig.createdAt === false) {
|
|
1024
|
+
return normalized;
|
|
1025
|
+
}
|
|
1026
|
+
const field = timestampsConfig.createdAt;
|
|
1027
|
+
if (normalized[field] !== void 0 || original[field] === void 0) {
|
|
1028
|
+
return normalized;
|
|
1029
|
+
}
|
|
1030
|
+
return {
|
|
1031
|
+
...normalized,
|
|
1032
|
+
[field]: original[field]
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1002
1035
|
|
|
1003
1036
|
// src/capabilities/model/model-instance-helpers.ts
|
|
1004
1037
|
var DEFAULT_POPULATE_MAX_DEPTH = 5;
|
|
@@ -1219,11 +1252,8 @@ function validateModelDocument(runtime, document) {
|
|
|
1219
1252
|
const result = runtime.schemaValidateFn(runtime.schemaCache, document ?? {});
|
|
1220
1253
|
return {
|
|
1221
1254
|
valid: result.valid,
|
|
1222
|
-
errors: (result.errors
|
|
1223
|
-
|
|
1224
|
-
message: error.message ?? ""
|
|
1225
|
-
})),
|
|
1226
|
-
data: result.data ?? document
|
|
1255
|
+
errors: mapModelSchemaValidationErrors(result.errors),
|
|
1256
|
+
data: result.data === void 0 ? document : result.data
|
|
1227
1257
|
};
|
|
1228
1258
|
} catch (error) {
|
|
1229
1259
|
return {
|
|
@@ -1243,44 +1273,87 @@ function applyModelDefaults(definition, document) {
|
|
|
1243
1273
|
}
|
|
1244
1274
|
return payload;
|
|
1245
1275
|
}
|
|
1276
|
+
function serializeModelWriteDocument(document) {
|
|
1277
|
+
const payload = serializeDocument(document);
|
|
1278
|
+
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(document))) {
|
|
1279
|
+
if (descriptor.get || descriptor.set) {
|
|
1280
|
+
delete payload[key];
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
return payload;
|
|
1284
|
+
}
|
|
1285
|
+
function replaceModelDocumentData(document, payload) {
|
|
1286
|
+
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(document))) {
|
|
1287
|
+
if (!descriptor.enumerable || descriptor.get || descriptor.set || typeof descriptor.value === "function") {
|
|
1288
|
+
continue;
|
|
1289
|
+
}
|
|
1290
|
+
if (!Object.prototype.hasOwnProperty.call(payload, key) && descriptor.configurable !== false) {
|
|
1291
|
+
delete document[key];
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
1295
|
+
const descriptor = Object.getOwnPropertyDescriptor(document, key);
|
|
1296
|
+
if (descriptor?.get || descriptor?.set || descriptor?.writable === false) {
|
|
1297
|
+
continue;
|
|
1298
|
+
}
|
|
1299
|
+
document[key] = value;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1246
1302
|
async function saveModelDocument(collection, document, options = {}) {
|
|
1247
1303
|
const nowFactory = options.nowFactory ?? (() => /* @__PURE__ */ new Date());
|
|
1248
|
-
let payload =
|
|
1304
|
+
let payload = serializeModelWriteDocument(document);
|
|
1249
1305
|
if (payload._id !== void 0) {
|
|
1306
|
+
const documentId = payload._id;
|
|
1250
1307
|
if (options.versionConfig?.enabled) {
|
|
1251
1308
|
const expectedVersion = assertNumericExpectedVersion(payload[options.versionConfig.field], "save");
|
|
1252
|
-
|
|
1309
|
+
if (options.schemaValidationContext) {
|
|
1310
|
+
payload = preserveModelReplaceCreatedAt(
|
|
1311
|
+
serializeModelWriteDocument(document),
|
|
1312
|
+
validateModelSchemaPayload(options.schemaValidationContext, payload),
|
|
1313
|
+
options.timestampsConfig ?? null
|
|
1314
|
+
);
|
|
1315
|
+
}
|
|
1316
|
+
const replacement2 = applyModelReplaceVersion(
|
|
1253
1317
|
applyModelReplaceTimestamps(payload, options.timestampsConfig ?? null, nowFactory),
|
|
1254
1318
|
options.versionConfig,
|
|
1255
1319
|
expectedVersion
|
|
1256
1320
|
);
|
|
1257
|
-
if (options.schemaValidationContext) {
|
|
1258
|
-
validateModelSchemaPayload(options.schemaValidationContext, replacement);
|
|
1259
|
-
}
|
|
1260
1321
|
const result2 = await collection.replaceOne(
|
|
1261
|
-
{ _id:
|
|
1262
|
-
|
|
1322
|
+
{ _id: documentId, [options.versionConfig.field]: expectedVersion },
|
|
1323
|
+
replacement2,
|
|
1263
1324
|
{ upsert: false }
|
|
1264
1325
|
);
|
|
1265
1326
|
assertModelOptimisticLockMatched(result2, options.versionConfig);
|
|
1266
|
-
|
|
1327
|
+
replaceModelDocumentData(document, replacement2);
|
|
1328
|
+
document._id = documentId;
|
|
1267
1329
|
return document;
|
|
1268
1330
|
}
|
|
1269
1331
|
if (options.schemaValidationContext) {
|
|
1270
|
-
|
|
1332
|
+
payload = preserveModelReplaceCreatedAt(
|
|
1333
|
+
serializeModelWriteDocument(document),
|
|
1334
|
+
validateModelSchemaPayload(options.schemaValidationContext, payload),
|
|
1335
|
+
options.timestampsConfig ?? null
|
|
1336
|
+
);
|
|
1271
1337
|
}
|
|
1272
|
-
|
|
1338
|
+
const replacement = applyModelReplaceTimestamps(
|
|
1339
|
+
payload,
|
|
1340
|
+
options.timestampsConfig ?? null,
|
|
1341
|
+
nowFactory
|
|
1342
|
+
);
|
|
1343
|
+
await collection.replaceOne({ _id: documentId }, replacement, { upsert: true });
|
|
1344
|
+
replaceModelDocumentData(document, replacement);
|
|
1345
|
+
document._id = documentId;
|
|
1273
1346
|
return document;
|
|
1274
1347
|
}
|
|
1348
|
+
if (options.schemaValidationContext) {
|
|
1349
|
+
payload = validateModelSchemaPayload(options.schemaValidationContext, payload);
|
|
1350
|
+
}
|
|
1275
1351
|
payload = applyModelInsertVersion(
|
|
1276
1352
|
applyModelInsertTimestamps(payload, options.timestampsConfig ?? null, nowFactory),
|
|
1277
1353
|
options.versionConfig ?? null
|
|
1278
1354
|
);
|
|
1279
|
-
if (options.schemaValidationContext) {
|
|
1280
|
-
validateModelSchemaPayload(options.schemaValidationContext, payload);
|
|
1281
|
-
}
|
|
1282
1355
|
const result = await collection.insertOne(payload);
|
|
1283
|
-
|
|
1356
|
+
replaceModelDocumentData(document, payload);
|
|
1284
1357
|
document._id = result.insertedId;
|
|
1285
1358
|
return document;
|
|
1286
1359
|
}
|
|
@@ -5078,7 +5151,7 @@ async function orchestrateModelInsertOne(context, document, options) {
|
|
|
5078
5151
|
} else {
|
|
5079
5152
|
await invokeStandardOperationHook(context, "insert", "before", { operation: "insertOne", collection: context.collectionName, data: payload });
|
|
5080
5153
|
}
|
|
5081
|
-
validateModelSchemaPayload({
|
|
5154
|
+
payload = validateModelSchemaPayload({
|
|
5082
5155
|
validateEnabled: context.validateEnabled,
|
|
5083
5156
|
schemaCache: context.schemaCache,
|
|
5084
5157
|
schemaValidateFn: context.schemaValidateFn
|
|
@@ -5103,23 +5176,23 @@ async function orchestrateModelInsertOne(context, document, options) {
|
|
|
5103
5176
|
}
|
|
5104
5177
|
async function orchestrateModelInsertMany(context, documents, options) {
|
|
5105
5178
|
const hookContext = {};
|
|
5179
|
+
const docs = (documents ?? []).map((document) => context.applyDefaults(document));
|
|
5106
5180
|
if (context.hooksFactory) {
|
|
5107
|
-
await invokeV1Hook(context, "insert", "before", hookContext,
|
|
5181
|
+
await invokeV1Hook(context, "insert", "before", hookContext, docs);
|
|
5108
5182
|
} else {
|
|
5109
|
-
await invokeStandardOperationHook(context, "insert", "before", { operation: "insertMany", collection: context.collectionName, data:
|
|
5183
|
+
await invokeStandardOperationHook(context, "insert", "before", { operation: "insertMany", collection: context.collectionName, data: docs });
|
|
5110
5184
|
}
|
|
5111
5185
|
const resolvedOptions = options ?? {};
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
validateModelSchemaPayload({
|
|
5186
|
+
for (let index = 0; index < docs.length; index++) {
|
|
5187
|
+
let doc = docs[index];
|
|
5188
|
+
doc = validateModelSchemaPayload({
|
|
5116
5189
|
validateEnabled: context.validateEnabled,
|
|
5117
5190
|
schemaCache: context.schemaCache,
|
|
5118
5191
|
schemaValidateFn: context.schemaValidateFn
|
|
5119
5192
|
}, doc, resolvedOptions, { index });
|
|
5120
5193
|
doc = applyModelInsertTimestamps(doc, context.timestampsConfig, () => context.nowDate());
|
|
5121
5194
|
doc = applyModelInsertVersion(doc, context.versionConfig);
|
|
5122
|
-
docs
|
|
5195
|
+
docs[index] = doc;
|
|
5123
5196
|
}
|
|
5124
5197
|
const result = await context.collection.insertMany(docs, options);
|
|
5125
5198
|
if (context.hooksFactory) {
|
|
@@ -5197,17 +5270,22 @@ async function orchestrateModelReplaceOne(context, filter, replacement, options)
|
|
|
5197
5270
|
} else {
|
|
5198
5271
|
await invokeStandardOperationHook(context, "update", "before", { operation: "replaceOne", collection: context.collectionName, filter, update: replacement });
|
|
5199
5272
|
}
|
|
5273
|
+
let nextReplacement = validateModelSchemaPayload({
|
|
5274
|
+
validateEnabled: context.validateEnabled,
|
|
5275
|
+
schemaCache: context.schemaCache,
|
|
5276
|
+
schemaValidateFn: context.schemaValidateFn
|
|
5277
|
+
}, replacement, options);
|
|
5278
|
+
nextReplacement = preserveModelReplaceCreatedAt(
|
|
5279
|
+
replacement,
|
|
5280
|
+
nextReplacement,
|
|
5281
|
+
context.timestampsConfig
|
|
5282
|
+
);
|
|
5200
5283
|
const lock = await resolveModelOptimisticLockAsync(context.collection, filter, options, context.versionConfig, "replaceOne");
|
|
5201
|
-
|
|
5202
|
-
applyModelReplaceTimestamps(
|
|
5284
|
+
nextReplacement = applyModelReplaceVersion(
|
|
5285
|
+
applyModelReplaceTimestamps(nextReplacement, context.timestampsConfig, () => context.nowDate()),
|
|
5203
5286
|
context.versionConfig,
|
|
5204
5287
|
lock.expectedVersion
|
|
5205
5288
|
);
|
|
5206
|
-
validateModelSchemaPayload({
|
|
5207
|
-
validateEnabled: context.validateEnabled,
|
|
5208
|
-
schemaCache: context.schemaCache,
|
|
5209
|
-
schemaValidateFn: context.schemaValidateFn
|
|
5210
|
-
}, nextReplacement, lock.driverOptions);
|
|
5211
5289
|
const result = await context.collection.replaceOne(lock.filter, nextReplacement, lock.driverOptions);
|
|
5212
5290
|
assertModelOptimisticLockMatched(result, context.versionConfig);
|
|
5213
5291
|
if (context.hooksFactory) {
|
|
@@ -5251,17 +5329,22 @@ async function orchestrateModelFindOneAndReplace(context, filter, replacement, o
|
|
|
5251
5329
|
} else {
|
|
5252
5330
|
await invokeStandardOperationHook(context, "update", "before", { operation: "findOneAndReplace", collection: context.collectionName, filter, update: replacement });
|
|
5253
5331
|
}
|
|
5332
|
+
let nextReplacement = validateModelSchemaPayload({
|
|
5333
|
+
validateEnabled: context.validateEnabled,
|
|
5334
|
+
schemaCache: context.schemaCache,
|
|
5335
|
+
schemaValidateFn: context.schemaValidateFn
|
|
5336
|
+
}, replacement, options);
|
|
5337
|
+
nextReplacement = preserveModelReplaceCreatedAt(
|
|
5338
|
+
replacement,
|
|
5339
|
+
nextReplacement,
|
|
5340
|
+
context.timestampsConfig
|
|
5341
|
+
);
|
|
5254
5342
|
const lock = await resolveModelOptimisticLockAsync(context.collection, filter, options, context.versionConfig, "findOneAndReplace");
|
|
5255
|
-
|
|
5256
|
-
applyModelReplaceTimestamps(
|
|
5343
|
+
nextReplacement = applyModelReplaceVersion(
|
|
5344
|
+
applyModelReplaceTimestamps(nextReplacement, context.timestampsConfig, () => context.nowDate()),
|
|
5257
5345
|
context.versionConfig,
|
|
5258
5346
|
lock.expectedVersion
|
|
5259
5347
|
);
|
|
5260
|
-
validateModelSchemaPayload({
|
|
5261
|
-
validateEnabled: context.validateEnabled,
|
|
5262
|
-
schemaCache: context.schemaCache,
|
|
5263
|
-
schemaValidateFn: context.schemaValidateFn
|
|
5264
|
-
}, nextReplacement, lock.driverOptions);
|
|
5265
5348
|
const result = await context.extendedCollection().findOneAndReplace(lock.filter, nextReplacement, lock.driverOptions);
|
|
5266
5349
|
assertModelOptimisticLockDocument(result, context.versionConfig);
|
|
5267
5350
|
if (context.hooksFactory) {
|
|
@@ -5349,23 +5432,24 @@ async function orchestrateModelIncrementOne(context, filter, field, increment, o
|
|
|
5349
5432
|
}
|
|
5350
5433
|
async function orchestrateModelInsertBatch(context, docs, options) {
|
|
5351
5434
|
const hookContext = {};
|
|
5435
|
+
const docsToInsert = docs.map((doc) => context.applyDefaults(doc));
|
|
5352
5436
|
if (context.hooksFactory) {
|
|
5353
|
-
await invokeV1Hook(context, "insert", "before", hookContext,
|
|
5437
|
+
await invokeV1Hook(context, "insert", "before", hookContext, docsToInsert);
|
|
5354
5438
|
} else {
|
|
5355
|
-
await invokeStandardOperationHook(context, "insert", "before", { operation: "insertBatch", collection: context.collectionName, data:
|
|
5439
|
+
await invokeStandardOperationHook(context, "insert", "before", { operation: "insertBatch", collection: context.collectionName, data: docsToInsert });
|
|
5356
5440
|
}
|
|
5357
5441
|
const resolvedOptions = options ?? {};
|
|
5358
|
-
|
|
5359
|
-
let record =
|
|
5360
|
-
validateModelSchemaPayload({
|
|
5442
|
+
for (let index = 0; index < docsToInsert.length; index++) {
|
|
5443
|
+
let record = docsToInsert[index];
|
|
5444
|
+
record = validateModelSchemaPayload({
|
|
5361
5445
|
validateEnabled: context.validateEnabled,
|
|
5362
5446
|
schemaCache: context.schemaCache,
|
|
5363
5447
|
schemaValidateFn: context.schemaValidateFn
|
|
5364
5448
|
}, record, resolvedOptions, { index });
|
|
5365
5449
|
record = applyModelInsertTimestamps(record, context.timestampsConfig, () => context.nowDate());
|
|
5366
5450
|
record = applyModelInsertVersion(record, context.versionConfig);
|
|
5367
|
-
|
|
5368
|
-
}
|
|
5451
|
+
docsToInsert[index] = record;
|
|
5452
|
+
}
|
|
5369
5453
|
const result = await context.extendedCollection().insertBatch(docsToInsert, options);
|
|
5370
5454
|
if (context.hooksFactory) {
|
|
5371
5455
|
try {
|
|
@@ -6482,9 +6566,28 @@ async function sleep(ms) {
|
|
|
6482
6566
|
var import_node_fs = require("node:fs");
|
|
6483
6567
|
var import_node_path = __toESM(require("node:path"));
|
|
6484
6568
|
var import_mongodb3 = require("mongodb");
|
|
6485
|
-
|
|
6569
|
+
|
|
6570
|
+
// config/mongodb-memory-server.json
|
|
6571
|
+
var mongodb_memory_server_default = {
|
|
6572
|
+
defaultVersion: "7.0.37",
|
|
6573
|
+
requiredVersions: [
|
|
6574
|
+
{ label: "MongoDB 7.0", version: "7.0.37" },
|
|
6575
|
+
{ label: "MongoDB 8.0", version: "8.0.26" }
|
|
6576
|
+
],
|
|
6577
|
+
managedDbPathKinds: [
|
|
6578
|
+
"single",
|
|
6579
|
+
"replset",
|
|
6580
|
+
"examples-single",
|
|
6581
|
+
"examples-replset",
|
|
6582
|
+
"probe-single",
|
|
6583
|
+
"probe-replset"
|
|
6584
|
+
]
|
|
6585
|
+
};
|
|
6586
|
+
|
|
6587
|
+
// src/adapters/mongodb/common/connect.ts
|
|
6588
|
+
var DEFAULT_MEMORY_SERVER_VERSION = mongodb_memory_server_default.defaultVersion;
|
|
6486
6589
|
var DEFAULT_MEMORY_SERVER_LAUNCH_TIMEOUT_MS = 3e4;
|
|
6487
|
-
var MANAGED_DB_PATH_PREFIXES =
|
|
6590
|
+
var MANAGED_DB_PATH_PREFIXES = mongodb_memory_server_default.managedDbPathKinds.map((kind) => `${kind}-`);
|
|
6488
6591
|
var _memoryServerInstance = null;
|
|
6489
6592
|
var _memoryServerStartPromise = null;
|
|
6490
6593
|
var _memoryServerCleanupOptions = { doCleanup: true, force: true };
|