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