UNPKG

26.9 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Passthrough = exports.getDiscriminatorModelForClass = exports.deleteModelWithClass = exports.deleteModel = exports.addModelToTypegoose = exports.buildSchema = exports.getModelWithString = exports.getModelForClass = exports.PropType = exports.Severity = exports.getName = exports.getClass = exports.types = exports.errors = exports.defaultClasses = exports.LogLevels = exports.setLogLevel = exports.setGlobalOptions = exports.mongoose = void 0;
4const tslib_1 = require("tslib");
5/* imports */
6const mongoose = require("mongoose");
7exports.mongoose = mongoose;
8require("reflect-metadata");
9const semver = require("semver");
10const utils_1 = require("./internal/utils");
11// using "typeof process", because somehow js gives a ReferenceError when using "process === undefined" in browser
12/* istanbul ignore next */
13if (typeof process !== 'undefined' && !(0, utils_1.isNullOrUndefined)(process?.version) && !(0, utils_1.isNullOrUndefined)(mongoose?.version)) {
14 // for usage on client side
15 /* istanbul ignore next */
16 if (semver.lt(mongoose?.version, '6.10.0')) {
17 throw new Error(`Please use mongoose 6.10.0 or higher (Current mongoose: ${mongoose.version}) [E001]`);
18 }
19 /* istanbul ignore next */
20 if (semver.lt(process.version.slice(1), '14.17.0')) {
21 throw new Error('You are using a NodeJS Version below 14.17.0, Please Upgrade! [E002]');
22 }
23}
24const globalOptions_1 = require("./globalOptions");
25Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return globalOptions_1.setGlobalOptions; } });
26const constants_1 = require("./internal/constants");
27const data_1 = require("./internal/data");
28const schema_1 = require("./internal/schema");
29const logSettings_1 = require("./logSettings");
30const typeguards_1 = require("./typeguards");
31const errors_1 = require("./internal/errors");
32var logSettings_2 = require("./logSettings");
33Object.defineProperty(exports, "setLogLevel", { enumerable: true, get: function () { return logSettings_2.setLogLevel; } });
34Object.defineProperty(exports, "LogLevels", { enumerable: true, get: function () { return logSettings_2.LogLevels; } });
35tslib_1.__exportStar(require("./prop"), exports);
36tslib_1.__exportStar(require("./hooks"), exports);
37tslib_1.__exportStar(require("./plugin"), exports);
38tslib_1.__exportStar(require("./indexes"), exports);
39tslib_1.__exportStar(require("./modelOptions"), exports);
40tslib_1.__exportStar(require("./queryMethod"), exports);
41tslib_1.__exportStar(require("./typeguards"), exports);
42exports.defaultClasses = require("./defaultClasses");
43exports.errors = require("./internal/errors");
44exports.types = require("./types");
45var utils_2 = require("./internal/utils");
46Object.defineProperty(exports, "getClass", { enumerable: true, get: function () { return utils_2.getClass; } });
47Object.defineProperty(exports, "getName", { enumerable: true, get: function () { return utils_2.getName; } });
48var constants_2 = require("./internal/constants");
49Object.defineProperty(exports, "Severity", { enumerable: true, get: function () { return constants_2.Severity; } });
50Object.defineProperty(exports, "PropType", { enumerable: true, get: function () { return constants_2.PropType; } });
51(0, globalOptions_1.parseENV)(); // call this before anything to ensure they are applied
52/**
53 * Build a Model From a Class
54 * @param cl The Class to build a Model from
55 * @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with
56 * @returns The finished Model
57 * @public
58 * @example
59 * ```ts
60 * class ClassName {}
61 *
62 * const NameModel = getModelForClass(ClassName);
63 * ```
64 */
65function getModelForClass(cl, options) {
66 (0, utils_1.assertionIsClass)(cl);
67 const rawOptions = typeof options === 'object' ? options : {};
68 const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models
69 const mergedOptions = (0, utils_1.mergeMetadata)(constants_1.DecoratorKeys.ModelOptions, rawOptions, cl);
70 mergedOptions[constants_1.AlreadyMerged] = true;
71 const name = (0, utils_1.getName)(cl, overwriteNaming);
72 if ((0, utils_1.isCachingEnabled)(mergedOptions.options?.disableCaching) && data_1.models.has(name)) {
73 return data_1.models.get(name);
74 }
75 const modelFn = mergedOptions?.existingConnection?.model.bind(mergedOptions.existingConnection) ??
76 mergedOptions?.existingMongoose?.model.bind(mergedOptions.existingMongoose) ??
77 mongoose.model.bind(mongoose);
78 const compiledModel = modelFn(name, buildSchema(cl, mergedOptions));
79 return addModelToTypegoose(compiledModel, cl, {
80 existingMongoose: mergedOptions?.existingMongoose,
81 existingConnection: mergedOptions?.existingConnection,
82 disableCaching: mergedOptions.options?.disableCaching,
83 });
84}
85exports.getModelForClass = getModelForClass;
86/**
87 * Get Model from internal cache
88 * @param key Model's name key
89 * @example
90 * ```ts
91 * class ClassName {}
92 * getModelForClass(ClassName); // build the model
93 * const NameModel = getModelWithString<typeof ClassName>("ClassName");
94 * ```
95 */
96function getModelWithString(key) {
97 (0, utils_1.assertion)(typeof key === 'string', () => new errors_1.ExpectedTypeError('key', 'string', key));
98 (0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('getModelWithString'));
99 return data_1.models.get(key);
100}
101exports.getModelWithString = getModelWithString;
102/**
103 * Generates a Mongoose schema out of class props, iterating through all parents
104 * @param cl The Class to build a Schema from
105 * @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with
106 * @returns Returns the Build Schema
107 * @example
108 * ```ts
109 * class ClassName {}
110 * const NameSchema = buildSchema(ClassName);
111 * const NameModel = mongoose.model("Name", NameSchema);
112 * ```
113 */
114function buildSchema(cl, options) {
115 (0, utils_1.assertionIsClass)(cl);
116 const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(options);
117 logSettings_1.logger.debug('buildSchema called for "%s"', (0, utils_1.getName)(cl, overwriteNaming));
118 // dont re-run the merging if already done so before (like in getModelForClass)
119 const rawOptions = typeof options === 'object' ? options : {};
120 const mergedOptions = rawOptions?.[constants_1.AlreadyMerged] ? rawOptions : (0, utils_1.mergeMetadata)(constants_1.DecoratorKeys.ModelOptions, rawOptions, cl);
121 mergedOptions[constants_1.AlreadyMerged] = true;
122 let sch = undefined;
123 /** Parent Constructor */
124 let parentCtor = Object.getPrototypeOf(cl.prototype).constructor;
125 /* This array is to execute from lowest class to highest (when extending) */
126 const parentClasses = [];
127 let upperOptions = {};
128 // iterate trough all parents to the lowest class
129 while (parentCtor?.name !== 'Object') {
130 // add lower classes (when extending) to the front of the array to be processed first
131 parentClasses.unshift([parentCtor, upperOptions]);
132 // clone object, because otherwise it will affect the upper classes too because the same reference is used
133 upperOptions = { ...upperOptions };
134 const ropt = Reflect.getMetadata(constants_1.DecoratorKeys.ModelOptions, parentCtor) ?? {};
135 // only affect options of lower classes, not the class the options are from
136 if (ropt.options?.disableLowerIndexes) {
137 upperOptions.buildIndexes = false;
138 }
139 // set next parent
140 parentCtor = Object.getPrototypeOf(parentCtor.prototype).constructor;
141 }
142 // 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
143 for (const [parentClass, extraOptions] of parentClasses) {
144 // extend schema
145 sch = (0, schema_1._buildSchema)(parentClass, sch, mergedOptions, false, undefined, extraOptions);
146 }
147 // get schema of current model
148 sch = (0, schema_1._buildSchema)(cl, sch, mergedOptions, true, overwriteNaming);
149 return sch;
150}
151exports.buildSchema = buildSchema;
152/**
153 * Add a Class-Model Pair to the Typegoose Cache
154 * This can be used to add custom Models to Typegoose, with the type information of "cl"
155 * Note: no guarrantee that the type information is fully correct when used manually
156 * @param model The Model to store
157 * @param cl The Class to store
158 * @param options Overwrite existingMongoose or existingConnection
159 * @example
160 * ```ts
161 * class ClassName {}
162 *
163 * const schema = buildSchema(ClassName);
164 * // modifications to the schema can be done
165 * const model = addModelToTypegoose(mongoose.model("Name", schema), ClassName);
166 * ```
167 */
168function addModelToTypegoose(model, cl, options) {
169 const mongooseModel = options?.existingMongoose?.Model || options?.existingConnection?.base?.Model || mongoose.Model;
170 (0, utils_1.assertion)(model.prototype instanceof mongooseModel, new errors_1.NotValidModelError(model, 'addModelToTypegoose.model'));
171 (0, utils_1.assertionIsClass)(cl);
172 // only check cache after the above checks, just to make sure they run
173 if (!(0, utils_1.isCachingEnabled)(options?.disableCaching)) {
174 logSettings_1.logger.info('Caching is not enabled, skipping adding');
175 return model;
176 }
177 const name = model.modelName;
178 (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`));
179 if (data_1.constructors.get(name)) {
180 logSettings_1.logger.info('Class "%s" already existed in the constructors Map', name);
181 }
182 data_1.models.set(name, model);
183 data_1.constructors.set(name, cl);
184 return data_1.models.get(name);
185}
186exports.addModelToTypegoose = addModelToTypegoose;
187/**
188 * Deletes a existing model so that it can be overwritten with another model
189 * (deletes from mongoose.connection and typegoose models cache and typegoose constructors cache)
190 * @param name The Model's mongoose name
191 * @example
192 * ```ts
193 * class ClassName {}
194 * const NameModel = getModelForClass(ClassName);
195 * deleteModel("ClassName");
196 * ```
197 */
198function deleteModel(name) {
199 (0, utils_1.assertion)(typeof name === 'string', () => new errors_1.ExpectedTypeError('name', 'string', name));
200 (0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('deleteModelWithClass'));
201 logSettings_1.logger.debug('Deleting Model "%s"', name);
202 const model = data_1.models.get(name);
203 if (!(0, utils_1.isNullOrUndefined)(model)) {
204 model.db.deleteModel(name);
205 }
206 data_1.models.delete(name);
207 data_1.constructors.delete(name);
208}
209exports.deleteModel = deleteModel;
210/**
211 * Delete a model, with the given class
212 * Same as "deleteModel", only that it can be done with the class instead of the name
213 * @param cl The Class to delete the model from
214 * @example
215 * ```ts
216 * class ClassName {}
217 * const NameModel = getModelForClass(ClassName);
218 * deleteModelWithClass(ClassName);
219 * ```
220 */
221function deleteModelWithClass(cl) {
222 (0, utils_1.assertionIsClass)(cl);
223 (0, utils_1.assertion)((0, utils_1.isGlobalCachingEnabled)(), () => new errors_1.CacheDisabledError('deleteModelWithClass'));
224 let name = (0, utils_1.getName)(cl);
225 if (!data_1.models.has(name)) {
226 logSettings_1.logger.debug(`Class "${name}" is not in "models", trying to find in "constructors"`);
227 let found = false;
228 // type "Map" does not have a "find" function, and using "get" would maybe result in the incorrect values
229 for (const [cname, constructor] of data_1.constructors) {
230 if (constructor === cl) {
231 logSettings_1.logger.debug(`Found Class in "constructors" with class name "${name}" and entered name "${cname}""`);
232 name = cname;
233 found = true;
234 }
235 }
236 if (!found) {
237 logSettings_1.logger.debug(`Could not find class "${name}" in constructors`);
238 return;
239 }
240 }
241 return deleteModel(name);
242}
243exports.deleteModelWithClass = deleteModelWithClass;
244function getDiscriminatorModelForClass(from, cl, value_or_options, options) {
245 (0, utils_1.assertion)((0, typeguards_1.isModel)(from), new errors_1.NotValidModelError(from, 'getDiscriminatorModelForClass.from'));
246 (0, utils_1.assertionIsClass)(cl);
247 const value = typeof value_or_options === 'string' ? value_or_options : undefined;
248 const rawOptions = typeof value_or_options !== 'string' ? value_or_options : typeof options === 'object' ? options : {};
249 const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models
250 const mergedOptions = (0, utils_1.mergeMetadata)(constants_1.DecoratorKeys.ModelOptions, rawOptions, cl);
251 mergedOptions[constants_1.AlreadyMerged] = true;
252 const name = (0, utils_1.getName)(cl, overwriteNaming);
253 if ((0, utils_1.isCachingEnabled)(mergedOptions.options?.disableCaching) && data_1.models.has(name)) {
254 return data_1.models.get(name);
255 }
256 if (mergedOptions.existingConnection && mergedOptions.existingConnection !== from.db) {
257 (0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingConnection');
258 }
259 if (mergedOptions.existingMongoose && mergedOptions.existingMongoose !== from.base) {
260 (0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingMongoose');
261 }
262 const sch = buildSchema(cl, mergedOptions);
263 const mergeHooks = mergedOptions.options?.enableMergeHooks ?? false;
264 // Note: this option is not actually for "merging plugins", but if "true" it will *overwrite* all plugins with the base-schema's
265 const mergePlugins = mergedOptions.options?.enableMergePlugins ?? false;
266 const discriminatorKey = sch.get('discriminatorKey');
267 if (!!discriminatorKey && sch.path(discriminatorKey)) {
268 sch.paths[discriminatorKey].options.$skipDiscriminatorCheck = true;
269 }
270 const compiledModel = from.discriminator(name, sch, {
271 value: value ? value : name,
272 mergeHooks,
273 mergePlugins,
274 });
275 return addModelToTypegoose(compiledModel, cl, {
276 disableCaching: mergedOptions.options?.disableCaching,
277 });
278}
279exports.getDiscriminatorModelForClass = getDiscriminatorModelForClass;
280/**
281 * Use this class if raw mongoose for a path is wanted
282 * It is still recommended to use the typegoose classes directly
283 * @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}
284 * @example
285 * ```ts
286 * class Dummy {
287 * @prop({ type: () => new Passthrough({ somePath: String }) })
288 * public somepath: { somePath: string };
289 * }
290 *
291 * class Dummy {
292 * @prop({ type: () => new Passthrough({ somePath: String }, true) })
293 * public somepath: { somePath: string };
294 * }
295 * ```
296 */
297class Passthrough {
298 /**
299 * Use this like `new mongoose.Schema()`
300 * @param raw The Schema definition
301 * @param direct Directly insert "raw", instead of using "type" (this will not apply any other inner options)
302 */
303 constructor(raw, direct) {
304 this.raw = raw;
305 this.direct = direct ?? false;
306 }
307}
308exports.Passthrough = Passthrough;
309//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWdvb3NlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3R5cGVnb29zZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsYUFBYTtBQUNiLHFDQUFxQztBQW1ENUIsNEJBQVE7QUFsRGpCLDRCQUEwQjtBQUMxQixpQ0FBaUM7QUFDakMsNENBVTBCO0FBRTFCLGtIQUFrSDtBQUNsSCwwQkFBMEI7QUFDMUIsSUFBSSxPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksQ0FBQyxJQUFBLHlCQUFpQixFQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUEseUJBQWlCLEVBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxFQUFFO0lBQ25ILDJCQUEyQjtJQUMzQiwwQkFBMEI7SUFDMUIsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLEVBQUU7UUFDMUMsTUFBTSxJQUFJLEtBQUssQ0FBQywyREFBMkQsUUFBUSxDQUFDLE9BQU8sVUFBVSxDQUFDLENBQUM7S0FDeEc7SUFFRCwwQkFBMEI7SUFDMUIsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFO1FBQ2xELE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztLQUN6RjtDQUNGO0FBRUQsbURBQTZEO0FBcUIxQyxpR0FyQkEsZ0NBQWdCLE9BcUJBO0FBcEJuQyxvREFBb0U7QUFDcEUsMENBQXVEO0FBQ3ZELDhDQUFpRDtBQUNqRCwrQ0FBdUM7QUFDdkMsNkNBQXVDO0FBWXZDLDhDQUFvSTtBQUtwSSw2Q0FBdUQ7QUFBOUMsMEdBQUEsV0FBVyxPQUFBO0FBQUUsd0dBQUEsU0FBUyxPQUFBO0FBQy9CLGlEQUF1QjtBQUN2QixrREFBd0I7QUFDeEIsbURBQXlCO0FBQ3pCLG9EQUEwQjtBQUMxQix5REFBK0I7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
\No newline at end of file