1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.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;
|
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 === 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 | }
|
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 === 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 | }
|
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 === 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 | }
|
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 | 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 | }
|
91 | exports.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 | */
|
97 | function 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 | }
|
102 | exports.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 | */
|
109 | function 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 | }
|
124 | exports.initProperty = initProperty;
|
125 | /**
|
126 | * Get the Class for a given Document
|
127 | * @param document The Document to fetch the class from
|
128 | */
|
129 | function getClassForDocument(document) {
|
130 | const modelName = document.constructor.modelName;
|
131 | return data_1.constructors.get(modelName);
|
132 | }
|
133 | exports.getClassForDocument = getClassForDocument;
|
134 | /**
|
135 | * Get the Class for a number of inputs
|
136 | * @param input The Input to fetch the class from
|
137 | */
|
138 | function 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 | }
|
150 | exports.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 | */
|
155 | function isWithStringValidate(options) {
|
156 | return (0, lodash_1.intersection)(Object.keys(options), ['match', 'minlength', 'maxlength']);
|
157 | }
|
158 | exports.isWithStringValidate = isWithStringValidate;
|
159 | /**
|
160 | * Returns all options found in "options" that are String-transform related
|
161 | * @param options The raw Options
|
162 | */
|
163 | function isWithStringTransform(options) {
|
164 | return (0, lodash_1.intersection)(Object.keys(options), ['lowercase', 'uppercase', 'trim']);
|
165 | }
|
166 | exports.isWithStringTransform = isWithStringTransform;
|
167 | /**
|
168 | * Returns all options found in "options" that are Number-Validate related
|
169 | * @param options The raw Options
|
170 | */
|
171 | function isWithNumberValidate(options) {
|
172 | return (0, lodash_1.intersection)(Object.keys(options), ['min', 'max']);
|
173 | }
|
174 | exports.isWithNumberValidate = isWithNumberValidate;
|
175 | /**
|
176 | * Returns all options found in "options" that are Enum Related
|
177 | * @param options The raw Options
|
178 | */
|
179 | function isWithEnumValidate(options) {
|
180 | return (0, lodash_1.intersection)(Object.keys(options), ['enum']);
|
181 | }
|
182 | exports.isWithEnumValidate = isWithEnumValidate;
|
183 | const 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 | */
|
188 | function isWithVirtualPOP(options) {
|
189 | return Object.keys(options).some((v) => virtualOptions.includes(v));
|
190 | }
|
191 | exports.isWithVirtualPOP = isWithVirtualPOP;
|
192 | exports.allVirtualoptions = virtualOptions.slice(0); // copy "virtualOptions" array
|
193 | exports.allVirtualoptions.push('ref');
|
194 | /**
|
195 | * Check if all Required options for Virtual-Populate are included in "options"
|
196 | * @param options The raw Options
|
197 | */
|
198 | function includesAllVirtualPOP(options) {
|
199 | return exports.allVirtualoptions.every((v) => Object.keys(options).includes(v));
|
200 | }
|
201 | exports.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 | */
|
211 | function 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 | }
|
219 | exports.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 | */
|
230 | function 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 | }
|
236 | exports.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 | */
|
242 | function 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 | */
|
256 | function mergeSchemaOptions(value, cl) {
|
257 | return mergeMetadata(constants_1.DecoratorKeys.ModelOptions, { schemaOptions: value }, cl).schemaOptions;
|
258 | }
|
259 | exports.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 | */
|
265 | function getRightTarget(target) {
|
266 | var _a;
|
267 | return ((_a = target.constructor) === null || _a === void 0 ? void 0 : _a.name) === 'Function' ? target : target.constructor;
|
268 | }
|
269 | exports.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 | */
|
276 | function 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 | }
|
302 | exports.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 | */
|
307 | function isNotDefined(Type) {
|
308 | return typeof Type === 'function' && !isPrimitive(Type) && Type !== Object && !data_1.schemas.has(getName(Type));
|
309 | }
|
310 | exports.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 | */
|
324 | function 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 | }
|
344 | exports.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 | */
|
353 | function 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 | }
|
418 | exports.mapOptions = mapOptions;
|
419 | /**
|
420 | * Check if the current Type is meant to be a Array
|
421 | * @param rawOptions The raw options
|
422 | */
|
423 | function 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 | }
|
427 | exports.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 | */
|
434 | function 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 | }
|
453 | exports.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 | */
|
459 | function isNullOrUndefined(val) {
|
460 | return val === null || val === undefined;
|
461 | }
|
462 | exports.isNullOrUndefined = isNullOrUndefined;
|
463 | /**
|
464 | * Assign Global ModelOptions if not already existing
|
465 | * @param target Target Class
|
466 | */
|
467 | function 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 | }
|
473 | exports.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 | */
|
481 | function 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 | }
|
496 | exports.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 | */
|
505 | function assertion(cond, error) {
|
506 | if (!cond) {
|
507 | throw typeof error === 'function' ? error() : error !== null && error !== void 0 ? error : new errors_1.AssertionFallbackError();
|
508 | }
|
509 | }
|
510 | exports.assertion = assertion;
|
511 | /**
|
512 | * Assert if "val" is an function (constructor for classes)
|
513 | * @param val Value to test
|
514 | */
|
515 | function assertionIsClass(val) {
|
516 | assertion(isConstructor(val), () => new errors_1.NoValidClassError(val));
|
517 | }
|
518 | exports.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 | */
|
524 | function 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 | }
|
550 | exports.getType = getType;
|
551 | /**
|
552 | * Is the provided input an class with an constructor?
|
553 | * @param obj The Value to test
|
554 | */
|
555 | function 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 | }
|
559 | exports.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 | */
|
582 | function 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 | }
|
588 | exports.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 | */
|
594 | function toStringNoFail(value) {
|
595 | try {
|
596 | return String(value);
|
597 | }
|
598 | catch (_) {
|
599 | return '(Error: Converting value to String failed)';
|
600 | }
|
601 | }
|
602 | exports.toStringNoFail = toStringNoFail;
|
603 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJuYWwvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXVEO0FBQ3ZELHFDQUFxQztBQUNyQyxnREFBd0M7QUFpQnhDLDJDQUFnRTtBQUNoRSxpQ0FBOEQ7QUFDOUQscUNBT2tCO0FBRWxCOzs7O0dBSUc7QUFDSCxTQUFnQixXQUFXLENBQUMsSUFBUztJQUNuQyxJQUFJLE9BQU8sQ0FBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSxDQUFBLEtBQUssUUFBUSxFQUFFO1FBQ2xDLGtGQUFrRjtRQUNsRixzREFBc0Q7UUFDdEQsT0FBTyxDQUNMLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3JFLG1FQUFtRTtZQUNuRSxpRUFBaUU7WUFDakUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUNqRixDQUFDO0tBQ0g7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFiRCxrQ0FhQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixXQUFXLENBQUMsSUFBUztJQUNuQyxJQUFJLE9BQU8sQ0FBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSxDQUFBLEtBQUssUUFBUSxFQUFFO1FBQ2xDLDJFQUEyRTtRQUMzRSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUs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 |
\ | No newline at end of file |