UNPKG

47.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.toStringNoFail = exports.warnNotCorrectTypeOptions = exports.isConstructor = exports.getType = exports.assertionIsClass = exports.assertion = exports.createArrayFromDimensions = exports.assignGlobalModelOptions = exports.isNullOrUndefined = exports.warnMixed = exports.isTypeMeantToBeArray = exports.mapOptions = exports.mapArrayOptions = exports.isNotDefined = exports.getName = exports.getRightTarget = exports.mergeSchemaOptions = exports.mergeMetadata = exports.assignMetadata = exports.includesAllVirtualPOP = exports.allVirtualoptions = exports.isWithVirtualPOP = exports.isWithEnumValidate = exports.isWithNumberValidate = exports.isWithStringTransform = exports.isWithStringValidate = exports.getClass = exports.getClassForDocument = exports.initProperty = exports.isString = exports.isNumber = exports.isObject = exports.isAnRefType = exports.isPrimitive = void 0;
4const lodash_1 = require("lodash");
5const mongoose = require("mongoose");
6const logSettings_1 = require("../logSettings");
7const constants_1 = require("./constants");
8const data_1 = require("./data");
9const errors_1 = require("./errors");
10/**
11 * Returns true, if the type is included in mongoose.Schema.Types
12 * @param Type The Type to test
13 * @returns true, if it includes it
14 */
15function isPrimitive(Type) {
16 if (typeof (Type === null || Type === void 0 ? void 0 : Type.name) === 'string') {
17 // try to match "Type.name" with all the Property Names of "mongoose.Schema.Types"
18 // (like "String" with "mongoose.Schema.Types.String")
19 return (Object.getOwnPropertyNames(mongoose.Schema.Types).includes(Type.name) ||
20 // try to match "Type.name" with all "mongoose.Schema.Types.*.name"
21 // (like "SchemaString" with "mongoose.Schema.Types.String.name")
22 Object.values(mongoose.Schema.Types).findIndex((v) => v.name === Type.name) >= 0);
23 }
24 return false;
25}
26exports.isPrimitive = isPrimitive;
27/**
28 * Returns true, if the type is included in mongoose.Schema.Types except the aliases
29 * @param Type The Type to test
30 * @returns true, if it includes it
31 */
32function isAnRefType(Type) {
33 if (typeof (Type === null || Type === void 0 ? void 0 : Type.name) === 'string') {
34 // Note: this is not done "once" because types can be added as custom types
35 const tmp = Object.getOwnPropertyNames(mongoose.Schema.Types).filter((x) => {
36 switch (x) {
37 case 'Oid':
38 case 'Bool':
39 case 'Object':
40 case 'Boolean':
41 return false;
42 default:
43 return true;
44 }
45 });
46 // try to match "Type.name" with all the Property Names of "mongoose.Schema.Types" except the ones with aliases
47 // (like "String" with "mongoose.Schema.Types.String")
48 return (tmp.includes(Type.name) ||
49 // try to match "Type.name" with all "mongoose.Schema.Types.*.name"
50 // (like "SchemaString" with "mongoose.Schema.Types.String.name")
51 Object.values(mongoose.Schema.Types).findIndex((v) => v.name === Type.name) >= 0);
52 }
53 return false;
54}
55exports.isAnRefType = isAnRefType;
56/**
57 * Returns true, if it is an Object
58 * Looks down the prototype chain, unless "once" is set to "true"
59 * @param Type The Type to test
60 * @param once Set to not loop down the prototype chain, default "false"
61 * @returns true, if it is an Object
62 */
63function isObject(Type, once = false) {
64 if (typeof (Type === null || Type === void 0 ? void 0 : Type.name) === 'string') {
65 let prototype = Type.prototype;
66 let name = Type.name;
67 while (name) {
68 if (name === 'Object' || name === 'Mixed') {
69 return true;
70 }
71 if (once) {
72 break;
73 }
74 prototype = Object.getPrototypeOf(prototype);
75 name = prototype === null || prototype === void 0 ? void 0 : prototype.constructor.name;
76 }
77 }
78 return false;
79}
80exports.isObject = isObject;
81/**
82 * Returns true, if it is an Number
83 * @param Type The Type to test
84 * @returns true, if it is an Number
85 */
86function isNumber(Type) {
87 var _a;
88 const name = (_a = Type === null || Type === void 0 ? void 0 : Type.name) !== null && _a !== void 0 ? _a : '';
89 return name === 'Number' || name === mongoose.Schema.Types.Number.name;
90}
91exports.isNumber = isNumber;
92/**
93 * Returns true, if it is an String
94 * @param Type The Type to test
95 * @returns true, if it is an String
96 */
97function isString(Type) {
98 var _a;
99 const name = (_a = Type === null || Type === void 0 ? void 0 : Type.name) !== null && _a !== void 0 ? _a : '';
100 return name === 'String' || name === mongoose.Schema.Types.String.name;
101}
102exports.isString = isString;
103/**
104 * Generate the initial values for the property to be extended upon
105 * @param name Name of the current Model/Class
106 * @param key Key of the property
107 * @param proptype Type of the Property
108 */
109function initProperty(name, key, proptype) {
110 const schemaProp = !data_1.schemas.has(name) ? data_1.schemas.set(name, {}).get(name) : data_1.schemas.get(name);
111 switch (proptype) {
112 case constants_1.PropType.ARRAY:
113 schemaProp[key] = [{}];
114 break;
115 case constants_1.PropType.MAP:
116 case constants_1.PropType.NONE:
117 schemaProp[key] = {};
118 break;
119 default:
120 throw new errors_1.InvalidPropTypeError(proptype, name, key, 'PropType(initProperty)');
121 }
122 return schemaProp;
123}
124exports.initProperty = initProperty;
125/**
126 * Get the Class for a given Document
127 * @param document The Document to fetch the class from
128 */
129function getClassForDocument(document) {
130 const modelName = document.constructor.modelName;
131 return data_1.constructors.get(modelName);
132}
133exports.getClassForDocument = getClassForDocument;
134/**
135 * Get the Class for a number of inputs
136 * @param input The Input to fetch the class from
137 */
138function getClass(input) {
139 if (typeof input === 'string') {
140 return data_1.constructors.get(input);
141 }
142 if (typeof (input === null || input === void 0 ? void 0 : input.typegooseName) === 'string') {
143 return data_1.constructors.get(input.typegooseName);
144 }
145 if (typeof (input === null || input === void 0 ? void 0 : input.typegooseName) === 'function') {
146 return data_1.constructors.get(input.typegooseName());
147 }
148 throw new errors_1.ResolveTypegooseNameError(input);
149}
150exports.getClass = getClass;
151/**
152 * Returns all options found in "options" that are String-validate related
153 * @param options The raw Options that may contain the wanted options
154 */
155function isWithStringValidate(options) {
156 return (0, lodash_1.intersection)(Object.keys(options), ['match', 'minlength', 'maxlength']);
157}
158exports.isWithStringValidate = isWithStringValidate;
159/**
160 * Returns all options found in "options" that are String-transform related
161 * @param options The raw Options
162 */
163function isWithStringTransform(options) {
164 return (0, lodash_1.intersection)(Object.keys(options), ['lowercase', 'uppercase', 'trim']);
165}
166exports.isWithStringTransform = isWithStringTransform;
167/**
168 * Returns all options found in "options" that are Number-Validate related
169 * @param options The raw Options
170 */
171function isWithNumberValidate(options) {
172 return (0, lodash_1.intersection)(Object.keys(options), ['min', 'max']);
173}
174exports.isWithNumberValidate = isWithNumberValidate;
175/**
176 * Returns all options found in "options" that are Enum Related
177 * @param options The raw Options
178 */
179function isWithEnumValidate(options) {
180 return (0, lodash_1.intersection)(Object.keys(options), ['enum']);
181}
182exports.isWithEnumValidate = isWithEnumValidate;
183const virtualOptions = ['localField', 'foreignField'];
184/**
185 * Check if the "options" contain any Virtual-Populate related options (excluding "ref" by it self)
186 * @param options The raw Options
187 */
188function isWithVirtualPOP(options) {
189 return Object.keys(options).some((v) => virtualOptions.includes(v));
190}
191exports.isWithVirtualPOP = isWithVirtualPOP;
192exports.allVirtualoptions = virtualOptions.slice(0); // copy "virtualOptions" array
193exports.allVirtualoptions.push('ref');
194/**
195 * Check if all Required options for Virtual-Populate are included in "options"
196 * @param options The raw Options
197 */
198function includesAllVirtualPOP(options) {
199 return exports.allVirtualoptions.every((v) => Object.keys(options).includes(v));
200}
201exports.includesAllVirtualPOP = includesAllVirtualPOP;
202/**
203 * Merge "value" with existing Metadata and save it to the class
204 * Difference with "mergeMetadata" is that this one DOES save it to the class
205 * Overwrites any existing Metadata that is new in "value"
206 * @param key Metadata key to read from and assign the new value to
207 * @param value Options to merge with
208 * @param cl The Class to read and assign the new metadata to
209 * @internal
210 */
211function assignMetadata(key, value, cl) {
212 if (isNullOrUndefined(value)) {
213 return value;
214 }
215 const newValue = mergeMetadata(key, value, cl);
216 Reflect.defineMetadata(key, newValue, cl);
217 return newValue;
218}
219exports.assignMetadata = assignMetadata;
220/**
221 * Merge "value" with existing Metadata
222 * Difference with "assignMetadata" is that this one DOES NOT save it to the class
223 * Overwrites any existing Metadata that is new in "value"
224 * @param key Metadata key to read existing metadata from
225 * @param value Option to merge with
226 * @param cl The Class to read the metadata from
227 * @returns Returns the merged output, where "value" overwrites existing Metadata values
228 * @internal
229 */
230function mergeMetadata(key, value, cl) {
231 assertion(typeof key === 'string' && key.length > 0, () => new errors_1.StringLengthExpectedError(1, key, getName(cl), 'key'));
232 assertionIsClass(cl);
233 // Please don't remove the other values from the function, even when unused - it is made to be clear what is what
234 return (0, lodash_1.mergeWith)({}, Reflect.getMetadata(key, cl), value, (_objValue, srcValue, ckey) => customMerger(ckey, srcValue));
235}
236exports.mergeMetadata = mergeMetadata;
237/**
238 * Used for lodash customizers (cloneWith, cloneDeepWith, mergeWith)
239 * @param key the key of the current object
240 * @param val the value of the object that should get returned for "existingMongoose" & "existingConnection"
241 */
242function customMerger(key, val) {
243 if (typeof key !== 'string') {
244 return undefined;
245 }
246 if (/^(existingMongoose|existingConnection)$/.test(key)) {
247 return val;
248 }
249 return undefined;
250}
251/**
252 * Merge only schemaOptions from ModelOptions of the class
253 * @param value The value to use
254 * @param cl The Class to get the values from
255 */
256function mergeSchemaOptions(value, cl) {
257 return mergeMetadata(constants_1.DecoratorKeys.ModelOptions, { schemaOptions: value }, cl).schemaOptions;
258}
259exports.mergeSchemaOptions = mergeSchemaOptions;
260/**
261 * Tries to return the right target
262 * if target.constructor.name is "Function", return "target", otherwise "target.constructor"
263 * @param target The target to determine
264 */
265function getRightTarget(target) {
266 var _a;
267 return ((_a = target.constructor) === null || _a === void 0 ? void 0 : _a.name) === 'Function' ? target : target.constructor;
268}
269exports.getRightTarget = getRightTarget;
270/**
271 * Get the Class's final name
272 * (combines all available options to generate a name)
273 * @param cl The Class to get the name for
274 * @param overwriteOptions Overwrite ModelOptions to generate a name from (Only name related options are merged)
275 */
276function getName(cl, overwriteOptions) {
277 var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
278 // this case (cl being undefined / null) can happen when type casting (or type being "any") happened and wanting to throw a Error (and there using "getName" to help)
279 // check if input variable is undefined, if it is throw a error (cannot be combined with the error below because of "getRightTarget")
280 assertion(!isNullOrUndefined(cl), () => new errors_1.NoValidClassError(cl));
281 const ctor = getRightTarget(cl);
282 assertion(isConstructor(ctor), () => new errors_1.NoValidClassError(ctor));
283 const options = (_a = Reflect.getMetadata(constants_1.DecoratorKeys.ModelOptions, ctor)) !== null && _a !== void 0 ? _a : {};
284 const baseName = ctor.name;
285 const customName = (_c = (_b = overwriteOptions === null || overwriteOptions === void 0 ? void 0 : overwriteOptions.options) === null || _b === void 0 ? void 0 : _b.customName) !== null && _c !== void 0 ? _c : (_d = options.options) === null || _d === void 0 ? void 0 : _d.customName;
286 if (typeof customName === 'function') {
287 const name = customName(options);
288 assertion(typeof name === 'string' && name.length > 0, () => new errors_1.StringLengthExpectedError(1, name, baseName, 'options.customName(function)'));
289 return name;
290 }
291 const automaticName = (_f = (_e = overwriteOptions === null || overwriteOptions === void 0 ? void 0 : overwriteOptions.options) === null || _e === void 0 ? void 0 : _e.automaticName) !== null && _f !== void 0 ? _f : (_g = options.options) === null || _g === void 0 ? void 0 : _g.automaticName;
292 if (automaticName) {
293 const suffix = (_j = customName !== null && customName !== void 0 ? customName : (_h = overwriteOptions === null || overwriteOptions === void 0 ? void 0 : overwriteOptions.schemaOptions) === null || _h === void 0 ? void 0 : _h.collection) !== null && _j !== void 0 ? _j : (_k = options.schemaOptions) === null || _k === void 0 ? void 0 : _k.collection;
294 return !isNullOrUndefined(suffix) ? `${baseName}_${suffix}` : baseName;
295 }
296 if (isNullOrUndefined(customName)) {
297 return baseName;
298 }
299 assertion(typeof customName === 'string' && customName.length > 0, () => new errors_1.StringLengthExpectedError(1, customName, baseName, 'options.customName'));
300 return customName;
301}
302exports.getName = getName;
303/**
304 * Check if "Type" is a class and if it is already in "schemas"
305 * @param Type The Type to check
306 */
307function isNotDefined(Type) {
308 return typeof Type === 'function' && !isPrimitive(Type) && Type !== Object && !data_1.schemas.has(getName(Type));
309}
310exports.isNotDefined = isNotDefined;
311/**
312 * Map Options to "inner" & "outer"
313 * -> inner: means inner of "type: [{here})"
314 * -> outer: means outer of "type: [{}], here"
315 *
316 * Specific to Arrays
317 * @param rawOptions The raw options
318 * @param Type The Type of the array
319 * @param target The Target class
320 * @param pkey Key of the Property
321 * @param loggerType Type to use for logging
322 * @param extraInner Extra Options to Mad explicitly to "inner"
323 */
324function mapArrayOptions(rawOptions, Type, target, pkey, loggerType, extraInner) {
325 logSettings_1.logger.debug('mapArrayOptions called');
326 loggerType = loggerType !== null && loggerType !== void 0 ? loggerType : Type;
327 if (!(Type instanceof mongoose.Schema)) {
328 loggerType = Type;
329 }
330 const dim = rawOptions.dim; // needed, otherwise it will be included (and not removed) in the returnObject
331 delete rawOptions.dim;
332 const mapped = mapOptions(rawOptions, Type, target, pkey, loggerType);
333 /** The Object that gets returned */
334 const returnObject = Object.assign(Object.assign({}, mapped.outer), { type: [
335 Object.assign(Object.assign({ type: Type }, mapped.inner), extraInner),
336 ] });
337 rawOptions.dim = dim; // re-add for "createArrayFromDimensions"
338 returnObject.type = createArrayFromDimensions(rawOptions, returnObject.type, getName(target), pkey);
339 if (loggerType) {
340 logSettings_1.logger.debug('(Array) Final mapped Options for Type "%s"', getName(loggerType), returnObject);
341 }
342 return returnObject;
343}
344exports.mapArrayOptions = mapArrayOptions;
345/**
346 * Map Options to "inner" & "outer"
347 * @param rawOptions The raw options
348 * @param Type The Type of the array
349 * @param target The Target class
350 * @param pkey Key of the Property
351 * @param loggerType Type to use for logging
352 */
353function mapOptions(rawOptions, Type, target, pkey, loggerType) {
354 var _a;
355 logSettings_1.logger.debug('mapOptions called');
356 loggerType = loggerType !== null && loggerType !== void 0 ? loggerType : Type;
357 /** The Object that gets returned */
358 const ret = {
359 inner: {},
360 outer: {},
361 };
362 // if Type is not a Schema, try to convert js type to mongoose type (Object => Mixed)
363 if (!(Type instanceof mongoose.Schema)) {
364 // set the loggerType to the js type
365 loggerType = Type;
366 const loggerTypeName = getName(loggerType);
367 if (loggerTypeName in mongoose.Schema.Types) {
368 logSettings_1.logger.info('Converting "%s" to mongoose Type', loggerTypeName);
369 Type = mongoose.Schema.Types[loggerTypeName];
370 if (Type === mongoose.Schema.Types.Mixed) {
371 warnMixed(target, pkey);
372 }
373 }
374 }
375 if (isNullOrUndefined(loggerType)) {
376 logSettings_1.logger.info('mapOptions loggerType is undefined!');
377 }
378 /** The OptionsConstructor to use */
379 let OptionsCTOR = (_a = Type === null || Type === void 0 ? void 0 : Type.prototype) === null || _a === void 0 ? void 0 : _a.OptionsConstructor;
380 if (Type instanceof mongoose.Schema) {
381 OptionsCTOR = mongoose.Schema.Types.Subdocument.prototype.OptionsConstructor;
382 }
383 assertion(!isNullOrUndefined(OptionsCTOR), () => new errors_1.InvalidOptionsConstructorError(getName(target), pkey, loggerType));
384 const options = Object.assign({}, rawOptions); // for sanity
385 if (OptionsCTOR.prototype instanceof mongoose.SchemaTypeOptions) {
386 for (const [key, value] of Object.entries(options)) {
387 if (Object.getOwnPropertyNames(OptionsCTOR.prototype).includes(key)) {
388 ret.inner[key] = value;
389 }
390 else {
391 ret.outer[key] = value;
392 }
393 }
394 }
395 else {
396 if (loggerType) {
397 logSettings_1.logger.info('The Type "%s" has a property "OptionsConstructor" but it does not extend "SchemaTypeOptions"', getName(loggerType));
398 }
399 ret.outer = options;
400 }
401 if (typeof (options === null || options === void 0 ? void 0 : options.innerOptions) === 'object') {
402 delete ret.outer.innerOptions;
403 for (const [key, value] of Object.entries(options.innerOptions)) {
404 ret.inner[key] = value;
405 }
406 }
407 if (typeof (options === null || options === void 0 ? void 0 : options.outerOptions) === 'object') {
408 delete ret.outer.outerOptions;
409 for (const [key, value] of Object.entries(options.outerOptions)) {
410 ret.outer[key] = value;
411 }
412 }
413 if (loggerType) {
414 logSettings_1.logger.debug('Final mapped Options for Type "%s"', getName(loggerType), ret);
415 }
416 return ret;
417}
418exports.mapOptions = mapOptions;
419/**
420 * Check if the current Type is meant to be a Array
421 * @param rawOptions The raw options
422 */
423function isTypeMeantToBeArray(rawOptions) {
424 // check if the "dim" option exists, if yes the type is meant to be a array in the end
425 return !isNullOrUndefined(rawOptions) && !isNullOrUndefined(rawOptions.dim) && typeof rawOptions.dim === 'number' && rawOptions.dim > 0;
426}
427exports.isTypeMeantToBeArray = isTypeMeantToBeArray;
428/**
429 * Warn, Error or Allow if an mixed type is set
430 * -> this function exists for de-duplication
431 * @param target Target Class
432 * @param key Property key
433 */
434function warnMixed(target, key) {
435 var _a, _b, _c, _d, _e, _f;
436 const name = getName(target);
437 const modelOptions = (_a = Reflect.getMetadata(constants_1.DecoratorKeys.ModelOptions, getRightTarget(target))) !== null && _a !== void 0 ? _a : {};
438 const rawOptions = Reflect.getMetadata(constants_1.DecoratorKeys.PropCache, target);
439 const setSeverity = (_f = (_d = (_c = (_b = rawOptions === null || rawOptions === void 0 ? void 0 : rawOptions.get(key)) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.allowMixed) !== null && _d !== void 0 ? _d : (_e = modelOptions.options) === null || _e === void 0 ? void 0 : _e.allowMixed) !== null && _f !== void 0 ? _f : constants_1.Severity.WARN;
440 logSettings_1.logger.debug(`setSeverity for "${name}.${key}" is "${setSeverity}"`);
441 switch (setSeverity) {
442 default:
443 case constants_1.Severity.WARN:
444 logSettings_1.logger.warn('Setting "Mixed" for property "%s.%s"\nLook here for how to disable this message: https://typegoose.github.io/typegoose/docs/api/decorators/model-options/#allowmixed', name, key);
445 break;
446 case constants_1.Severity.ALLOW:
447 break;
448 case constants_1.Severity.ERROR:
449 throw new TypeError(`Setting "Mixed" is not allowed! (${name}, ${key}) [E017]`);
450 }
451 return; // always return, if "allowMixed" is not "ERROR"
452}
453exports.warnMixed = warnMixed;
454/**
455 * Check if "val" is "null" to "undefined"
456 * This Function exists because since node 4.0.0 the internal util.is* functions got deprecated
457 * @param val Any value to test if null or undefined
458 */
459function isNullOrUndefined(val) {
460 return val === null || val === undefined;
461}
462exports.isNullOrUndefined = isNullOrUndefined;
463/**
464 * Assign Global ModelOptions if not already existing
465 * @param target Target Class
466 */
467function assignGlobalModelOptions(target) {
468 if (isNullOrUndefined(Reflect.getMetadata(constants_1.DecoratorKeys.ModelOptions, target))) {
469 logSettings_1.logger.info('Assigning global Schema Options to "%s"', getName(target));
470 assignMetadata(constants_1.DecoratorKeys.ModelOptions, (0, lodash_1.omit)(data_1.globalOptions, 'globalOptions'), target);
471 }
472}
473exports.assignGlobalModelOptions = assignGlobalModelOptions;
474/**
475 * Loop over "dimensions" and create an array from that
476 * @param rawOptions baseProp's rawOptions
477 * @param extra What is actually in the deepest array
478 * @param name name of the target for better error logging
479 * @param key key of target-key for better error logging
480 */
481function createArrayFromDimensions(rawOptions, extra, name, key) {
482 // dimensions start at 1 (not 0)
483 const dim = typeof rawOptions.dim === 'number' ? rawOptions.dim : 1;
484 if (dim < 1) {
485 throw new RangeError(`"dim" needs to be higher than 0 (${name}.${key}) [E018]`);
486 }
487 delete rawOptions.dim; // delete this property to not actually put it as an option
488 logSettings_1.logger.info('createArrayFromDimensions called with %d dimensions', dim);
489 let retArray = Array.isArray(extra) ? extra : [extra];
490 // index starts at 1 because "retArray" is already once wrapped in an array
491 for (let index = 1; index < dim; index++) {
492 retArray = [retArray];
493 }
494 return retArray;
495}
496exports.createArrayFromDimensions = createArrayFromDimensions;
497/**
498 * Assert a condition, if "false" throw error
499 * Note: it is not named "assert" to differentiate between node and jest types
500 *
501 * Note: "error" can be a function to not execute the constructor when not needed
502 * @param cond The Condition to check
503 * @param error A Custom Error to throw or a function that returns a Error
504 */
505function assertion(cond, error) {
506 if (!cond) {
507 throw typeof error === 'function' ? error() : error !== null && error !== void 0 ? error : new errors_1.AssertionFallbackError();
508 }
509}
510exports.assertion = assertion;
511/**
512 * Assert if "val" is an function (constructor for classes)
513 * @param val Value to test
514 */
515function assertionIsClass(val) {
516 assertion(isConstructor(val), () => new errors_1.NoValidClassError(val));
517}
518exports.assertionIsClass = assertionIsClass;
519/**
520 * Get Type, if input is an arrow-function, execute it and return the result
521 * @param typeOrFunc Function or Type
522 * @param returnLastFoundArray Return the last found array (used for something like PropOptions.discriminators)
523 */
524function getType(typeOrFunc, returnLastFoundArray = false) {
525 const returnObject = {
526 type: typeOrFunc,
527 dim: 0,
528 };
529 if (typeof returnObject.type === 'function' && !isConstructor(returnObject.type)) {
530 returnObject.type = returnObject.type();
531 }
532 function getDepth() {
533 if (returnObject.dim > 100) {
534 // this is arbitrary, but why would anyone have more than 10 nested arrays anyway?
535 throw new Error('getDepth recursed too much (dim > 100)');
536 }
537 if (Array.isArray(returnObject.type)) {
538 returnObject.dim++;
539 if (returnLastFoundArray && !Array.isArray(returnObject.type[0])) {
540 return;
541 }
542 returnObject.type = returnObject.type[0];
543 getDepth();
544 }
545 }
546 getDepth();
547 logSettings_1.logger.debug('Final getType: dim: %s, type:', returnObject.dim, returnObject.type);
548 return returnObject;
549}
550exports.getType = getType;
551/**
552 * Is the provided input an class with an constructor?
553 * @param obj The Value to test
554 */
555function isConstructor(obj) {
556 var _a, _b;
557 return typeof obj === 'function' && !isNullOrUndefined((_b = (_a = obj.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name);
558}
559exports.isConstructor = isConstructor;
560// /**
561// * Execute util.deprecate or when "process" does not exist use "console.log"
562// * (if "process" does not exist, the codes are not cached, and are always logged again)
563// * This Function is here to try to make typegoose compatible with the browser (see https://github.com/typegoose/typegoose/issues/33)
564// */
565// eslint-disable-next-line @typescript-eslint/ban-types
566// export function deprecate<T extends Function>(fn: T, message: string, code: string): T {
567// if (!isNullOrUndefined(process)) {
568// // eslint-disable-next-line @typescript-eslint/no-var-requires
569// return require('util').deprecate(fn, message, code);
570// }
571// console.log(`[${code}] DeprecationWarning: ${message}`);
572// return fn;
573// }
574/**
575 * Logs an warning if "included > 0" that the options of not the current type are included
576 * @param name Name of the Class
577 * @param key Name of the Currently Processed key
578 * @param type Name of the Expected Type
579 * @param extra Extra string to be included
580 * @param included Included Options to be listed
581 */
582function warnNotCorrectTypeOptions(name, key, type, extra, included) {
583 // this "if" is in this function to de-duplicate code
584 if (included.length > 0) {
585 logSettings_1.logger.warn(`Type of "${name}.${key}" is not ${type}, but includes the following ${extra} options [W001]:\n` + ` [${included.join(', ')}]`);
586 }
587}
588exports.warnNotCorrectTypeOptions = warnNotCorrectTypeOptions;
589/**
590 * Try to convert input "value" to a String, without it failing
591 * @param value The Value to convert to String
592 * @returns A String, either "value.toString" or a placeholder
593 */
594function toStringNoFail(value) {
595 try {
596 return String(value);
597 }
598 catch (_) {
599 return '(Error: Converting value to String failed)';
600 }
601}
602exports.toStringNoFail = toStringNoFail;
603//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJuYWwvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXVEO0FBQ3ZELHFDQUFxQztBQUNyQyxnREFBd0M7QUFpQnhDLDJDQUFnRTtBQUNoRSxpQ0FBOEQ7QUFDOUQscUNBT2tCO0FBRWxCOzs7O0dBSUc7QUFDSCxTQUFnQixXQUFXLENBQUMsSUFBUztJQUNuQyxJQUFJLE9BQU8sQ0FBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSxDQUFBLEtBQUssUUFBUSxFQUFFO1FBQ2xDLGtGQUFrRjtRQUNsRixzREFBc0Q7UUFDdEQsT0FBTyxDQUNMLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3JFLG1FQUFtRTtZQUNuRSxpRUFBaUU7WUFDakUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUNqRixDQUFDO0tBQ0g7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFiRCxrQ0FhQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixXQUFXLENBQUMsSUFBUztJQUNuQyxJQUFJLE9BQU8sQ0FBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSxDQUFBLEtBQUssUUFBUSxFQUFFO1FBQ2xDLDJFQUEyRTtRQUMzRSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUs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
\No newline at end of file