UNPKG

24.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/* istanbul ignore next */
12if (!(0, utils_1.isNullOrUndefined)(process?.version) && !(0, utils_1.isNullOrUndefined)(mongoose?.version)) {
13 // for usage on client side
14 /* istanbul ignore next */
15 if (semver.lt(mongoose?.version, '6.9.0')) {
16 throw new Error(`Please use mongoose 6.9.0 or higher (Current mongoose: ${mongoose.version}) [E001]`);
17 }
18 /* istanbul ignore next */
19 if (semver.lt(process.version.slice(1), '14.17.0')) {
20 throw new Error('You are using a NodeJS Version below 14.17.0, Please Upgrade! [E002]');
21 }
22}
23const globalOptions_1 = require("./globalOptions");
24Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return globalOptions_1.setGlobalOptions; } });
25const constants_1 = require("./internal/constants");
26const data_1 = require("./internal/data");
27const schema_1 = require("./internal/schema");
28const logSettings_1 = require("./logSettings");
29const typeguards_1 = require("./typeguards");
30const errors_1 = require("./internal/errors");
31var logSettings_2 = require("./logSettings");
32Object.defineProperty(exports, "setLogLevel", { enumerable: true, get: function () { return logSettings_2.setLogLevel; } });
33Object.defineProperty(exports, "LogLevels", { enumerable: true, get: function () { return logSettings_2.LogLevels; } });
34tslib_1.__exportStar(require("./prop"), exports);
35tslib_1.__exportStar(require("./hooks"), exports);
36tslib_1.__exportStar(require("./plugin"), exports);
37tslib_1.__exportStar(require("./indexes"), exports);
38tslib_1.__exportStar(require("./modelOptions"), exports);
39tslib_1.__exportStar(require("./queryMethod"), exports);
40tslib_1.__exportStar(require("./typeguards"), exports);
41exports.defaultClasses = require("./defaultClasses");
42exports.errors = require("./internal/errors");
43exports.types = require("./types");
44var utils_2 = require("./internal/utils");
45Object.defineProperty(exports, "getClass", { enumerable: true, get: function () { return utils_2.getClass; } });
46Object.defineProperty(exports, "getName", { enumerable: true, get: function () { return utils_2.getName; } });
47var constants_2 = require("./internal/constants");
48Object.defineProperty(exports, "Severity", { enumerable: true, get: function () { return constants_2.Severity; } });
49Object.defineProperty(exports, "PropType", { enumerable: true, get: function () { return constants_2.PropType; } });
50(0, globalOptions_1.parseENV)(); // call this before anything to ensure they are applied
51/**
52 * Symbol to track if options have already been merged
53 * This is to reduce the "merge*" calls, which dont need to be run often if already done
54 */
55const AlreadyMerged = Symbol('MOAlreadyMergedOptions');
56/**
57 * Build a Model From a Class
58 * @param cl The Class to build a Model from
59 * @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with
60 * @returns The finished Model
61 * @public
62 * @example
63 * ```ts
64 * class ClassName {}
65 *
66 * const NameModel = getModelForClass(ClassName);
67 * ```
68 */
69function getModelForClass(cl, options) {
70 (0, utils_1.assertionIsClass)(cl);
71 const rawOptions = typeof options === 'object' ? options : {};
72 const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models
73 const mergedOptions = (0, utils_1.mergeMetadata)(constants_1.DecoratorKeys.ModelOptions, rawOptions, cl);
74 mergedOptions[AlreadyMerged] = true;
75 const name = (0, utils_1.getName)(cl, overwriteNaming);
76 if (data_1.models.has(name)) {
77 return data_1.models.get(name);
78 }
79 const modelFn = mergedOptions?.existingConnection?.model.bind(mergedOptions.existingConnection) ??
80 mergedOptions?.existingMongoose?.model.bind(mergedOptions.existingMongoose) ??
81 mongoose.model.bind(mongoose);
82 const compiledModel = modelFn(name, buildSchema(cl, mergedOptions));
83 return addModelToTypegoose(compiledModel, cl, {
84 existingMongoose: mergedOptions?.existingMongoose,
85 existingConnection: mergedOptions?.existingConnection,
86 });
87}
88exports.getModelForClass = getModelForClass;
89/**
90 * Get Model from internal cache
91 * @param key Model's name key
92 * @example
93 * ```ts
94 * class ClassName {}
95 * getModelForClass(ClassName); // build the model
96 * const NameModel = getModelWithString<typeof ClassName>("ClassName");
97 * ```
98 */
99function getModelWithString(key) {
100 (0, utils_1.assertion)(typeof key === 'string', () => new errors_1.ExpectedTypeError('key', 'string', key));
101 return data_1.models.get(key);
102}
103exports.getModelWithString = getModelWithString;
104/**
105 * Generates a Mongoose schema out of class props, iterating through all parents
106 * @param cl The Class to build a Schema from
107 * @param options Overwrite Options, like for naming or general SchemaOptions the class gets compiled with
108 * @returns Returns the Build Schema
109 * @example
110 * ```ts
111 * class ClassName {}
112 * const NameSchema = buildSchema(ClassName);
113 * const NameModel = mongoose.model("Name", NameSchema);
114 * ```
115 */
116function buildSchema(cl, options) {
117 (0, utils_1.assertionIsClass)(cl);
118 const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(options);
119 logSettings_1.logger.debug('buildSchema called for "%s"', (0, utils_1.getName)(cl, overwriteNaming));
120 // dont re-run the merging if already done so before (like in getModelForClass)
121 const mergedOptions = options?.[AlreadyMerged] ? options?.schemaOptions : (0, utils_1.mergeSchemaOptions)(options?.schemaOptions, cl);
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 const name = model.modelName;
173 (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`));
174 if (data_1.constructors.get(name)) {
175 logSettings_1.logger.info('Class "%s" already existed in the constructors Map', name);
176 }
177 data_1.models.set(name, model);
178 data_1.constructors.set(name, cl);
179 return data_1.models.get(name);
180}
181exports.addModelToTypegoose = addModelToTypegoose;
182/**
183 * Deletes a existing model so that it can be overwritten with another model
184 * (deletes from mongoose.connection and typegoose models cache and typegoose constructors cache)
185 * @param name The Model's mongoose name
186 * @example
187 * ```ts
188 * class ClassName {}
189 * const NameModel = getModelForClass(ClassName);
190 * deleteModel("ClassName");
191 * ```
192 */
193function deleteModel(name) {
194 (0, utils_1.assertion)(typeof name === 'string', () => new errors_1.ExpectedTypeError('name', 'string', name));
195 logSettings_1.logger.debug('Deleting Model "%s"', name);
196 const model = data_1.models.get(name);
197 if (!(0, utils_1.isNullOrUndefined)(model)) {
198 model.db.deleteModel(name);
199 }
200 data_1.models.delete(name);
201 data_1.constructors.delete(name);
202}
203exports.deleteModel = deleteModel;
204/**
205 * Delete a model, with the given class
206 * Same as "deleteModel", only that it can be done with the class instead of the name
207 * @param cl The Class to delete the model from
208 * @example
209 * ```ts
210 * class ClassName {}
211 * const NameModel = getModelForClass(ClassName);
212 * deleteModelWithClass(ClassName);
213 * ```
214 */
215function deleteModelWithClass(cl) {
216 (0, utils_1.assertionIsClass)(cl);
217 let name = (0, utils_1.getName)(cl);
218 if (!data_1.models.has(name)) {
219 logSettings_1.logger.debug(`Class "${name}" is not in "models", trying to find in "constructors"`);
220 let found = false;
221 // type "Map" does not have a "find" function, and using "get" would maybe result in the incorrect values
222 for (const [cname, constructor] of data_1.constructors) {
223 if (constructor === cl) {
224 logSettings_1.logger.debug(`Found Class in "constructors" with class name "${name}" and entered name "${cname}""`);
225 name = cname;
226 found = true;
227 }
228 }
229 if (!found) {
230 logSettings_1.logger.debug(`Could not find class "${name}" in constructors`);
231 return;
232 }
233 }
234 return deleteModel(name);
235}
236exports.deleteModelWithClass = deleteModelWithClass;
237function getDiscriminatorModelForClass(from, cl, value_or_options, options) {
238 (0, utils_1.assertion)((0, typeguards_1.isModel)(from), new errors_1.NotValidModelError(from, 'getDiscriminatorModelForClass.from'));
239 (0, utils_1.assertionIsClass)(cl);
240 const value = typeof value_or_options === 'string' ? value_or_options : undefined;
241 const rawOptions = typeof value_or_options !== 'string' ? value_or_options : typeof options === 'object' ? options : {};
242 const overwriteNaming = (0, utils_1.mapModelOptionsToNaming)(rawOptions); // use "rawOptions" instead of "mergedOptions" to consistently differentiate between classes & models
243 const mergedOptions = (0, utils_1.mergeMetadata)(constants_1.DecoratorKeys.ModelOptions, rawOptions, cl);
244 mergedOptions[AlreadyMerged] = true;
245 const name = (0, utils_1.getName)(cl, overwriteNaming);
246 if (data_1.models.has(name)) {
247 return data_1.models.get(name);
248 }
249 if (mergedOptions.existingConnection && mergedOptions.existingConnection !== from.db) {
250 (0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingConnection');
251 }
252 if (mergedOptions.existingMongoose && mergedOptions.existingMongoose !== from.base) {
253 (0, utils_1.warnNotMatchingExisting)(from.modelName, (0, utils_1.getName)(cl), 'existingMongoose');
254 }
255 const sch = buildSchema(cl, mergedOptions);
256 const mergeHooks = mergedOptions.options?.enableMergeHooks ?? false;
257 // Note: this option is not actually for "merging plugins", but if "true" it will *overwrite* all plugins with the base-schema's
258 const mergePlugins = mergedOptions.options?.enableMergePlugins ?? false;
259 const discriminatorKey = sch.get('discriminatorKey');
260 if (!!discriminatorKey && sch.path(discriminatorKey)) {
261 sch.paths[discriminatorKey].options.$skipDiscriminatorCheck = true;
262 }
263 const compiledModel = from.discriminator(name, sch, {
264 value: value ? value : name,
265 mergeHooks,
266 mergePlugins,
267 });
268 return addModelToTypegoose(compiledModel, cl);
269}
270exports.getDiscriminatorModelForClass = getDiscriminatorModelForClass;
271/**
272 * Use this class if raw mongoose for a path is wanted
273 * It is still recommended to use the typegoose classes directly
274 * @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}
275 * @example
276 * ```ts
277 * class Dummy {
278 * @prop({ type: () => new Passthrough({ somePath: String }) })
279 * public somepath: { somePath: string };
280 * }
281 *
282 * class Dummy {
283 * @prop({ type: () => new Passthrough({ somePath: String }, true) })
284 * public somepath: { somePath: string };
285 * }
286 * ```
287 */
288class Passthrough {
289 /**
290 * Use this like `new mongoose.Schema()`
291 * @param raw The Schema definition
292 * @param direct Directly insert "raw", instead of using "type" (this will not apply any other inner options)
293 */
294 constructor(raw, direct) {
295 this.raw = raw;
296 this.direct = direct ?? false;
297 }
298}
299exports.Passthrough = Passthrough;
300//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWdvb3NlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3R5cGVnb29zZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsYUFBYTtBQUNiLHFDQUFxQztBQWlENUIsNEJBQVE7QUFoRGpCLDRCQUEwQjtBQUMxQixpQ0FBaUM7QUFDakMsNENBUzBCO0FBRTFCLDBCQUEwQjtBQUMxQixJQUFJLENBQUMsSUFBQSx5QkFBaUIsRUFBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFBLHlCQUFpQixFQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBRTtJQUNqRiwyQkFBMkI7SUFDM0IsMEJBQTBCO0lBQzFCLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFO1FBQ3pDLE1BQU0sSUFBSSxLQUFLLENBQUMsMERBQTBELFFBQVEsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxDQUFDO0tBQ3ZHO0lBRUQsMEJBQTBCO0lBQzFCLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsRUFBRTtRQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLHNFQUFzRSxDQUFDLENBQUM7S0FDekY7Q0FDRjtBQUVELG1EQUE2RDtBQXFCMUMsaUdBckJBLGdDQUFnQixPQXFCQTtBQXBCbkMsb0RBQXFEO0FBQ3JELDBDQUF1RDtBQUN2RCw4Q0FBaUQ7QUFDakQsK0NBQXVDO0FBQ3ZDLDZDQUF1QztBQVl2Qyw4Q0FBZ0g7QUFLaEgsNkNBQXVEO0FBQTlDLDBHQUFBLFdBQVcsT0FBQTtBQUFFLHdHQUFBLFNBQVMsT0FBQTtBQUMvQixpREFBdUI7QUFDdkIsa0RBQXdCO0FBQ3hCLG1EQUF5QjtBQUN6QixvREFBMEI7QUFDMUIseURBQStCO0FBQy9CLHdEQUE4QjtBQUM5Qix1REFBNkI7QUFDN0IscURBQW1E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
\No newline at end of file