@typegoose/typegoose
Version:
Define Mongoose models using TypeScript classes
328 lines • 28.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Passthrough = exports.PropType = exports.Severity = exports.getName = exports.getClass = exports.types = exports.errors = exports.defaultClasses = exports.LogLevels = exports.setLogLevel = exports.setGlobalOptions = exports.mongoose = void 0;
exports.getModelForClass = getModelForClass;
exports.getModelWithString = getModelWithString;
exports.buildSchema = buildSchema;
exports.addModelToTypegoose = addModelToTypegoose;
exports.deleteModel = deleteModel;
exports.deleteModelWithClass = deleteModelWithClass;
exports.getDiscriminatorModelForClass = getDiscriminatorModelForClass;
const tslib_1 = require("tslib");
/* imports */
const mongoose_1 = tslib_1.__importDefault(require("mongoose"));
exports.mongoose = mongoose_1.default;
require("reflect-metadata");
const semver = tslib_1.__importStar(require("semver"));
const utils_1 = require("./internal/utils");
// using "typeof process", because somehow js gives a ReferenceError when using "process === undefined" in browser
/* istanbul ignore next */
if (typeof process !== 'undefined' && !(0, utils_1.isNullOrUndefined)(process?.version) && !(0, utils_1.isNullOrUndefined)(mongoose_1.default?.version)) {
// for usage on client side
/* istanbul ignore next */
if (semver.lt(mongoose_1.default?.version, '9.0.0')) {
throw new Error(`Please use mongoose 9.0.0 or higher (Current mongoose: ${mongoose_1.default.version}) [E001]`);
}
/* istanbul ignore next */
if (semver.lt(process.version.slice(1), '20.19.0')) {
throw new Error('You are using a NodeJS Version below 20.19.0, Please Upgrade! [E002]');
}
}
const globalOptions_1 = require("./globalOptions");
Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return globalOptions_1.setGlobalOptions; } });
const constants_1 = require("./internal/constants");
const data_1 = require("./internal/data");
const schema_1 = require("./internal/schema");
const logSettings_1 = require("./logSettings");
const typeguards_1 = require("./typeguards");
const errors_1 = require("./internal/errors");
(0, globalOptions_1.parseENV)(); // call this before anything to ensure they are applied (including before defaultclasses)
var logSettings_2 = require("./logSettings");
Object.defineProperty(exports, "setLogLevel", { enumerable: true, get: function () { return logSettings_2.setLogLevel; } });
Object.defineProperty(exports, "LogLevels", { enumerable: true, get: function () { return logSettings_2.LogLevels; } });
tslib_1.__exportStar(require("./prop"), exports);
tslib_1.__exportStar(require("./hooks"), exports);
tslib_1.__exportStar(require("./plugin"), exports);
tslib_1.__exportStar(require("./indexes"), exports);
tslib_1.__exportStar(require("./searchIndexes"), exports);
tslib_1.__exportStar(require("./modelOptions"), exports);
tslib_1.__exportStar(require("./queryMethod"), exports);
tslib_1.__exportStar(require("./typeguards"), exports);
exports.defaultClasses = tslib_1.__importStar(require("./defaultClasses"));
exports.errors = tslib_1.__importStar(require("./internal/errors"));
exports.types = tslib_1.__importStar(require("./types"));
var utils_2 = require("./internal/utils");
Object.defineProperty(exports, "getClass", { enumerable: true, get: function () { return utils_2.getClass; } });
Object.defineProperty(exports, "getName", { enumerable: true, get: function () { return utils_2.getName; } });
var constants_2 = require("./internal/constants");
Object.defineProperty(exports, "Severity", { enumerable: true, get: function () { return constants_2.Severity; } });
Object.defineProperty(exports, "PropType", { enumerable: true, get: function () { return constants_2.PropType; } });
/**
* Build a Model From a Class
* @param cl The Class to build a Model from
* @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with
* @returns The finished Model
* @public
* @example
* ```ts
* class ClassName {}
*
* const NameModel = getModelForClass(ClassName);
* ```
*/
function getModelForClass(cl, options) {
(0, utils_1.assertionIsClass)(cl);
const rawOptions = typeof options === 'object' ? options : {};
const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models
const mergedOptions = (0, utils_1.getMergedModelOptions)(rawOptions, cl);
const name = (0, utils_1.getName)(cl, overwriteNaming);
if ((0, utils_1.isCachingEnabled)(mergedOptions.options?.disableCaching) && data_1.models.has(name)) {
return data_1.models.get(name);
}
const modelFn = mergedOptions?.existingConnection?.model.bind(mergedOptions.existingConnection) ??
mergedOptions?.existingMongoose?.model.bind(mergedOptions.existingMongoose) ??
mongoose_1.default.model.bind(mongoose_1.default);
const compiledModel = modelFn(name, buildSchema(cl, mergedOptions));
return addModelToTypegoose(compiledModel, cl, {
existingMongoose: mergedOptions?.existingMongoose,
existingConnection: mergedOptions?.existingConnection,
disableCaching: mergedOptions.options?.disableCaching,
});
}
/**
* Get Model from internal cache
* @param key Model's name key
* @example
* ```ts
* class ClassName {}
* getModelForClass(ClassName); // build the model
* const NameModel = getModelWithString<typeof ClassName>("ClassName");
* ```
*/
function getModelWithString(key) {
(0, utils_1.assertion)(typeof key === 'string', () => new errors_1.ExpectedTypeError('key', 'string', key));
(0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('getModelWithString'));
return data_1.models.get(key);
}
/**
* Generates a Mongoose schema out of class props, iterating through all parents
* @param cl The Class to build a Schema from
* @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with
* @returns Returns the Build Schema
* @example
* ```ts
* class ClassName {}
* const NameSchema = buildSchema(ClassName);
* const NameModel = mongoose.model("Name", NameSchema);
* ```
*/
function buildSchema(cl, options) {
(0, utils_1.assertionIsClass)(cl);
const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(options);
logSettings_1.logger.debug('buildSchema called for "%s"', (0, utils_1.getName)(cl, overwriteNaming));
// dont re-run the merging if already done so before (like in getModelForClass)
const mergedOptions = (0, utils_1.getMergedModelOptions)(options, cl);
let sch = undefined;
/** Parent Constructor */
let parentCtor = Object.getPrototypeOf(cl.prototype).constructor;
/* This array is to execute from lowest class to highest (when extending) */
const parentClasses = [];
/** Options for the next lower class that gets unshifted to {@link parentClasses} (ie the super-class) */
let superOptions = {};
// first run for some options based on input class options (if any), because the while-loop is for the prototypes (if any)
{
// get new options because "mergedOptions" is merged with lower options, but "upperOptions" requires the "own" version, if any
const mergedOwnOptions = (0, utils_1.getMergedModelOptions)(options, cl, true);
applySuperOptions(superOptions, mergedOwnOptions);
}
// iterate trough all parents to the lowest class
while (parentCtor?.name !== 'Object') {
// add lower classes (when extending) to the front of the array to be processed first
parentClasses.unshift([parentCtor, superOptions]);
// clone object, because otherwise it will affect the upper classes too because the same reference is used
superOptions = { ...superOptions };
{
// only get the own metadata, possible because "upperOptions" at the moment only requires the "own" metadata
const ropt = Reflect.getOwnMetadata(constants_1.DecoratorKeys.ModelOptions, parentCtor) ?? {};
applySuperOptions(superOptions, ropt);
}
// set next parent
parentCtor = Object.getPrototypeOf(parentCtor.prototype).constructor;
}
// iterate and build class schemas from lowest to highest (when extending classes, the lower class will get build first) see https://github.com/typegoose/typegoose/pull/243
for (const [parentClass, extraOptions] of parentClasses) {
// extend schema
sch = (0, schema_1._buildSchema)(parentClass, sch, mergedOptions, false, undefined, extraOptions);
}
// get schema of current model
sch = (0, schema_1._buildSchema)(cl, sch, mergedOptions, true, overwriteNaming);
return sch;
}
/**
* Apply options to "superOptions" object, based on "modelOptions"
* @param superOptions The "superOptions" object
* @param modelOptions The Model Options of the current class
*/
function applySuperOptions(superOptions, modelOptions) {
// only affect options of lower classes, not the class the options are from
if (modelOptions.options?.disableLowerIndexes) {
superOptions.buildIndexes = false;
}
}
/**
* Add a Class-Model Pair to the Typegoose Cache
* This can be used to add custom Models to Typegoose, with the type information of "cl"
* Note: no guarrantee that the type information is fully correct when used manually
* @param model The Model to store
* @param cl The Class to store
* @param options Overwrite existingMongoose or existingConnection
* @example
* ```ts
* class ClassName {}
*
* const schema = buildSchema(ClassName);
* // modifications to the schema can be done
* const model = addModelToTypegoose(mongoose.model("Name", schema), ClassName);
* ```
*/
function addModelToTypegoose(model, cl, options) {
// run this before the assertions below, for compatability with mongoose browser (browser version does not have "mongoose.Model")
// see https://github.com/typegoose/typegoose/issues/981
if (!(0, utils_1.isCachingEnabled)(options?.disableCaching)) {
logSettings_1.logger.info('Caching is not enabled, skipping adding');
return model;
}
const mongooseModel = options?.existingMongoose?.Model || options?.existingConnection?.base?.Model || mongoose_1.default.Model;
(0, utils_1.assertion)(model.prototype instanceof mongooseModel, new errors_1.NotValidModelError(model, 'addModelToTypegoose.model'));
(0, utils_1.assertionIsClass)(cl);
const name = model.modelName;
(0, utils_1.assertion)(!data_1.models.has(name), new errors_1.FunctionCalledMoreThanSupportedError('addModelToTypegoose', 1, `This was caused because the model name "${name}" already exists in the typegoose-internal "models" cache`));
if (data_1.constructors.get(name)) {
logSettings_1.logger.info('Class "%s" already existed in the constructors Map', name);
}
data_1.models.set(name, model);
data_1.constructors.set(name, cl);
return data_1.models.get(name);
}
/**
* Deletes a existing model so that it can be overwritten with another model
* (deletes from mongoose.connection and typegoose models cache and typegoose constructors cache)
* @param name The Model's mongoose name
* @example
* ```ts
* class ClassName {}
* const NameModel = getModelForClass(ClassName);
* deleteModel("ClassName");
* ```
*/
function deleteModel(name) {
(0, utils_1.assertion)(typeof name === 'string', () => new errors_1.ExpectedTypeError('name', 'string', name));
(0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('deleteModelWithClass'));
logSettings_1.logger.debug('Deleting Model "%s"', name);
const model = data_1.models.get(name);
if (!(0, utils_1.isNullOrUndefined)(model)) {
model.db.deleteModel(name);
}
data_1.models.delete(name);
data_1.constructors.delete(name);
}
/**
* Delete a model, with the given class
* Same as "deleteModel", only that it can be done with the class instead of the name
* @param cl The Class to delete the model from
* @example
* ```ts
* class ClassName {}
* const NameModel = getModelForClass(ClassName);
* deleteModelWithClass(ClassName);
* ```
*/
function deleteModelWithClass(cl) {
(0, utils_1.assertionIsClass)(cl);
(0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('deleteModelWithClass'));
let name = (0, utils_1.getName)(cl);
if (!data_1.models.has(name)) {
logSettings_1.logger.debug(`Class "${name}" is not in "models", trying to find in "constructors"`);
let found = false;
// type "Map" does not have a "find" function, and using "get" would maybe result in the incorrect values
for (const [cname, constructor] of data_1.constructors) {
if (constructor === cl) {
logSettings_1.logger.debug(`Found Class in "constructors" with class name "${name}" and entered name "${cname}""`);
name = cname;
found = true;
}
}
if (!found) {
logSettings_1.logger.debug(`Could not find class "${name}" in constructors`);
return;
}
}
return deleteModel(name);
}
function getDiscriminatorModelForClass(from, cl, value_or_options, options) {
(0, utils_1.assertion)((0, typeguards_1.isModel)(from), new errors_1.NotValidModelError(from, 'getDiscriminatorModelForClass.from'));
(0, utils_1.assertionIsClass)(cl);
const value = typeof value_or_options === 'string' ? value_or_options : undefined;
const rawOptions = typeof value_or_options !== 'string' ? value_or_options : typeof options === 'object' ? options : {};
const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models
const mergedOptions = (0, utils_1.getMergedModelOptions)(rawOptions, cl);
const name = (0, utils_1.getName)(cl, overwriteNaming);
if ((0, utils_1.isCachingEnabled)(mergedOptions.options?.disableCaching) && data_1.models.has(name)) {
return data_1.models.get(name);
}
if (mergedOptions.existingConnection && mergedOptions.existingConnection !== from.db) {
(0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingConnection');
}
if (mergedOptions.existingMongoose && mergedOptions.existingMongoose !== from.base) {
(0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingMongoose');
}
const sch = buildSchema(cl, mergedOptions);
const mergeHooks = mergedOptions.options?.enableMergeHooks ?? false;
// Note: this option is not actually for "merging plugins", but if "true" it will *overwrite* all plugins with the base-schema's
const mergePlugins = mergedOptions.options?.enableMergePlugins ?? false;
const discriminatorKey = sch.get('discriminatorKey');
if (!!discriminatorKey && sch.path(discriminatorKey)) {
sch.paths[discriminatorKey].options.$skipDiscriminatorCheck = true;
}
const compiledModel = from.discriminator(name, sch, {
value: value ? value : name,
mergeHooks,
mergePlugins,
});
return addModelToTypegoose(compiledModel, cl, {
disableCaching: mergedOptions.options?.disableCaching,
});
}
/**
* Use this class if raw mongoose for a path is wanted
* It is still recommended to use the typegoose classes directly
* @see Using `Passthrough`, the paths created will also result as an `Schema` (since mongoose 6.0), see {@link https://github.com/Automattic/mongoose/issues/7181 Mongoose#7181}
* @example
* ```ts
* class Dummy {
* @prop({ type: () => new Passthrough({ somePath: String }) })
* public somepath: { somePath: string };
* }
*
* class Dummy {
* @prop({ type: () => new Passthrough({ somePath: String }, true) })
* public somepath: { somePath: string };
* }
* ```
*/
class Passthrough {
// this property has no types, because it can slightly differentiate than a normal mongoose schema (like being a direct array)
raw;
direct;
/**
* Use this like `new mongoose.Schema()`
* @param raw The Schema definition
* @param direct Directly insert "raw", instead of using "type" (this will not apply any other inner options)
*/
constructor(raw, direct) {
this.raw = raw;
this.direct = direct ?? false;
}
}
exports.Passthrough = Passthrough;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWdvb3NlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3R5cGVnb29zZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFxRkEsNENBd0JDO0FBWUQsZ0RBT0M7QUFjRCxrQ0F3REM7QUE4QkQsa0RBcUNDO0FBYUQsa0NBY0M7QUFhRCxvREEyQkM7QUEwR0Qsc0VBK0NDOztBQXJlRCxhQUFhO0FBQ2IsZ0VBQWdDO0FBcUR2QixtQkFyREYsa0JBQVEsQ0FxREU7QUFwRGpCLDRCQUEwQjtBQUMxQix1REFBaUM7QUFDakMsNENBVTBCO0FBRTFCLGtIQUFrSDtBQUNsSCwwQkFBMEI7QUFDMUIsSUFBSSxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksQ0FBQyxJQUFBLHlCQUFpQixFQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUEseUJBQWlCLEVBQUMsa0JBQVEsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDO0lBQ3BILDJCQUEyQjtJQUMzQiwwQkFBMEI7SUFDMUIsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDLGtCQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDMUMsTUFBTSxJQUFJLEtBQUssQ0FBQywwREFBMEQsa0JBQVEsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxDQUFDO0lBQ3hHLENBQUM7SUFFRCwwQkFBMEI7SUFDMUIsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDbkQsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO0lBQzFGLENBQUM7QUFDSCxDQUFDO0FBRUQsbURBQTZEO0FBdUIxQyxpR0F2QkEsZ0NBQWdCLE9BdUJBO0FBdEJuQyxvREFBcUQ7QUFDckQsMENBQXVEO0FBQ3ZELDhDQUFpRDtBQUNqRCwrQ0FBdUM7QUFDdkMsNkNBQXVDO0FB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