UNPKG

seedgoose

Version:

Mongoose data seeding with smart id references tracking.

150 lines (149 loc) 6.88 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const series_async_each_1 = require("series-async-each"); const get_1 = require("./get"); const idMap_1 = require("./idMap"); const SeedingCommand_1 = require("./SeedingCommand"); const stringIsObjectId_1 = require("./stringIsObjectId"); const shouldIgnoreItem = (item, key, mongoose) => { if (key === '_id') return true; if (key === 'id') return true; if (item instanceof mongoose.VirtualType) return true; }; const transformRecord = (record, schema, mongoose, root) => __awaiter(this, void 0, void 0, function* () { if (record === undefined) record = null; // this is a primitive type declared with mongoose primitive types if (schema.schemaName) { // ignore mongoose Schema primitive types for now // TODO: handle date casting here return record; } // schema object type if (schema instanceof mongoose.Schema) { const retval = {}; yield series_async_each_1.default(schema.tree, (item, key) => __awaiter(this, void 0, void 0, function* () { if (record && record[key]) { if (!shouldIgnoreItem(item, key, mongoose)) { retval[key] = yield transformRecord(record[key], item, mongoose, root); } } })); return retval; } // Array type if (Array.isArray(schema)) { if (record) { const retval = []; yield series_async_each_1.default(record, (recordItem) => __awaiter(this, void 0, void 0, function* () { retval.push(yield transformRecord(recordItem, schema[0], mongoose, root)); })); return retval; } else { return []; } } // Very primitive type declared with function constructor if (typeof schema === 'function') { // TODO: handle date casting here return record; } // Declared with an object if (typeof schema === 'object') { // Primitive type declared with type if (schema.type) { if ((schema.type === mongoose.Schema.Types.ObjectId) || (schema.type === mongoose.Types.ObjectId)) { if (stringIsObjectId_1.default(record)) return mongoose.Types.ObjectId(record); // Reference type if (schema.ref) { // Static type reference return yield idMap_1.getUniqId(mongoose.model(schema.ref).collection.name, record); } else if (schema.refPath) { // Dynamic type reference return yield idMap_1.getUniqId(mongoose.model(get_1.default(root, schema.refPath)).collection.name, record); } else { // Just ObjectId without references return mongoose.Types.ObjectId(); } } else { // Primitive type // TODO: handle date casting here return record; } } else { // nested declared with object syntax const retval = {}; yield series_async_each_1.default(schema, (item, key) => __awaiter(this, void 0, void 0, function* () { if (record && record[key]) { if (!shouldIgnoreItem(item, key, mongoose)) { retval[key] = yield transformRecord(record[key], item, mongoose, root); } } })); return retval; } } }); const genericSeed = function (collectionName, records, mongoose, reporter, command) { return __awaiter(this, void 0, void 0, function* () { reporter.startSeedCollection(collectionName); const model = Object.values(mongoose.models).find((m) => m.collection.name === collectionName); yield series_async_each_1.default(records, (record, index) => __awaiter(this, void 0, void 0, function* () { if (Array.isArray(records) && !record._id && !record.id) { throw new Error(`id not found for a record of \`${collectionName}'.`); } if (Array.isArray(records)) { if (!record._id) record._id = record.id; } else { record._id = index; } const nativeId = mongoose.Types.ObjectId(stringIsObjectId_1.default(record._id) ? record._id : yield idMap_1.getUniqId(collectionName, record._id)); const db = mongoose.connection.db; const dbCollection = db.collection(collectionName); if (command === SeedingCommand_1.SeedingCommandType.UNSEED) { const result = yield dbCollection.deleteOne({ _id: nativeId }); reporter.didHandleRecord(result.result.n === 0 ? 'unexist' : 'delete', collectionName, record._id); return; } const transformedRecord = yield transformRecord(record, model.schema, model.base, record); if (command === SeedingCommand_1.SeedingCommandType.RESEED) { const result = yield dbCollection.findOneAndUpdate({ _id: nativeId }, { $set: transformedRecord }, { upsert: true, returnOriginal: false }); const update = result.lastErrorObject.updatedExisting; reporter.didHandleRecord(update ? 'update' : 'create', collectionName, record._id); return; } if (command === SeedingCommand_1.SeedingCommandType.SEED) { const exist = yield dbCollection.findOne({ _id: nativeId }); if (exist) { reporter.didHandleRecord('untouch', collectionName, record._id); } else { const insertResult = (yield dbCollection.insertOne(Object.assign({ _id: nativeId }, transformedRecord))).ops[0]; reporter.didHandleRecord('create', collectionName, record._id); return; } } })); reporter.endSeedCollection(collectionName); }); }; exports.default = genericSeed;