UNPKG

@typegoose/typegoose

Version:

Define Mongoose models using TypeScript classes

413 lines 40.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.processProp = void 0; const tslib_1 = require("tslib"); const logSettings_1 = require("../logSettings"); const typegoose_1 = require("../typegoose"); const constants_1 = require("./constants"); const errors_1 = require("./errors"); const utils = tslib_1.__importStar(require("./utils")); /** * Function that is the actual processing of the prop's (used for caching) * @param input All the options needed for prop's */ function processProp(input) { const { key, target } = input; const name = utils.getName(target); const rawOptions = Object.assign({}, input.options); let Type = Reflect.getMetadata(constants_1.DecoratorKeys.Type, target, key); let propKind = input.propType ?? detectPropType(Type); logSettings_1.logger.debug('Starting to process "%s.%s"', name, key); utils.assertion(typeof key === 'string', () => new errors_1.CannotBeSymbolError(name, key)); // optionDeprecation(rawOptions); { // soft errors & "type"-alias mapping switch (propKind) { case constants_1.PropType.NONE: break; case constants_1.PropType.MAP: case constants_1.PropType.ARRAY: // set the "Type" to undefined if "ref" or "refPath" are defined, as an fallback in case "type" is also not defined if (('ref' in rawOptions || 'refPath' in rawOptions) && !('type' in rawOptions)) { Type = undefined; } break; } } if (!utils.isNullOrUndefined(rawOptions.type)) { logSettings_1.logger.info('Prop Option "type" is set to ', rawOptions.type); const gotType = utils.getType(rawOptions.type); Type = gotType.type; if (gotType.dim > 0) { rawOptions.dim = gotType.dim; // Infer "type: [TYPE]" as a array, only if the PropType is not manually set or already inferred as something else // This is useful if reflection fails or when working without "emitDecoratorMetadata" if (utils.isNullOrUndefined(input.propType) && propKind == constants_1.PropType.NONE) { logSettings_1.logger.debug('Detected "type" being set to a array, using PropType.ARRAY'); propKind = constants_1.PropType.ARRAY; } } delete rawOptions.type; } // prevent "infinite" buildSchema loop / Maximum Stack size exceeded if (Type === target.constructor) { throw new errors_1.SelfContainingClassError(name, key); } // map to correct buffer type, otherwise it would result in "Mixed" if (Type === typegoose_1.mongoose.Types.Buffer) { Type = typegoose_1.mongoose.Schema.Types.Buffer; } // confirm that "PropType" is an ARRAY and if that the Type is still an *ARRAY, set them to Mixed // for issues like https://github.com/typegoose/typegoose/issues/300 if (propKind === constants_1.PropType.ARRAY && detectPropType(Type) === constants_1.PropType.ARRAY) { logSettings_1.logger.debug('Type is still *ARRAY, defaulting to Mixed'); Type = typegoose_1.mongoose.Schema.Types.Mixed; } // confirm that "PropType" is an MAP and if that the Type is still an *MAP, set them to Mixed if (propKind === constants_1.PropType.MAP && detectPropType(Type) === constants_1.PropType.MAP) { logSettings_1.logger.debug('Type is still *Map, defaulting to Mixed'); Type = typegoose_1.mongoose.Schema.Types.Mixed; } if (utils.isNotDefined(Type)) { (0, typegoose_1.buildSchema)(Type); } const modelOptionsOfType = Reflect.getMetadata(constants_1.DecoratorKeys.ModelOptions, Type ?? {}) ?? {}; // throw a error when both "discriminators" as a prop-option and as a model-option are defined if ('discriminators' in rawOptions && !utils.isNullOrUndefined(modelOptionsOfType?.options?.discriminators)) { throw new errors_1.DuplicateOptionsError(['discriminators(prop-option)', 'discriminators(model-option)']); } if ('discriminators' in rawOptions || !utils.isNullOrUndefined(modelOptionsOfType?.options?.discriminators)) { const discriminatorsToUse = rawOptions?.discriminators ?? modelOptionsOfType?.options?.discriminators; logSettings_1.logger.debug('Found option "discriminators" in "%s.%s"', name, key); const gotType = utils.getType(discriminatorsToUse, true); utils.assertion(gotType.dim === 1, () => new errors_1.OptionDoesNotSupportOptionError('discriminators', 'dim', '1', `dim: ${gotType.dim}`)); const discriminators = gotType.type.map((val, index) => { if (utils.isConstructor(val)) { return { type: val }; } if (typeof val === 'object') { if (!('type' in val)) { throw new Error(`"${name}.${key}" discriminator index "${index}" is an object, but does not contain the "type" property!`); } return val; } throw new Error(`"${name}.${key}" discriminators index "${index}" is not an object or an constructor!`); }); const disMap = new Map(Reflect.getMetadata(constants_1.DecoratorKeys.NestedDiscriminators, target.constructor) ?? []); disMap.set(key, discriminators); Reflect.defineMetadata(constants_1.DecoratorKeys.NestedDiscriminators, disMap, target.constructor); delete rawOptions.discriminators; } // allow setting the type asynchronously if ('ref' in rawOptions) { const gotType = utils.getType(rawOptions.ref); utils.assertion(gotType.dim === 0, () => new errors_1.OptionDoesNotSupportOptionError('ref', 'dim', '0', `dim: ${gotType.dim}`)); rawOptions.ref = gotType.type; utils.assertion(!utils.isNullOrUndefined(rawOptions.ref), () => new errors_1.RefOptionIsUndefinedError(name, key)); rawOptions.ref = typeof rawOptions.ref === 'string' ? rawOptions.ref : utils.isConstructor(rawOptions.ref) ? utils.getName(rawOptions.ref) : rawOptions.ref; } if (utils.isWithVirtualPOP(rawOptions)) { if (!utils.includesAllVirtualPOP(rawOptions)) { throw new errors_1.NotAllVPOPElementsError(name, key); } const virtuals = new Map(Reflect.getMetadata(constants_1.DecoratorKeys.VirtualPopulate, target.constructor) ?? []); virtuals.set(key, rawOptions); Reflect.defineMetadata(constants_1.DecoratorKeys.VirtualPopulate, virtuals, target.constructor); return; } if ('justOne' in rawOptions) { logSettings_1.logger.warn(`Option "justOne" is defined in "${name}.${key}" but no Virtual-Populate-Options!\n` + 'Look here for more: https://typegoose.github.io/typegoose/docs/api/virtuals#virtual-populate'); } const schemaProp = utils.getCachedSchema(input.cl); // do this early, because the other options (enum, ref, refPath, discriminators) should not matter for this one if (Type instanceof typegoose_1.Passthrough) { logSettings_1.logger.debug('Type is "instanceof Passthrough" ("%s.%s", %s, direct: %s)', name, key, propKind, Type.direct); // this is because the check above narrows down the type, which somehow is not compatible const newType = Type.raw; if (Type.direct) { schemaProp[key] = newType; return; } switch (propKind) { case constants_1.PropType.ARRAY: schemaProp[key] = utils.mapArrayOptions(rawOptions, newType, target, key); return; case constants_1.PropType.MAP: const mapped = utils.mapOptions(rawOptions, newType, target, key); schemaProp[key] = { ...mapped.outer, type: Map, of: { type: newType, ...mapped.inner }, }; return; case constants_1.PropType.NONE: schemaProp[key] = { ...rawOptions, type: newType, }; return; default: throw new errors_1.InvalidPropTypeError(propKind, name, key, 'PropType(Passthrough)'); } } // use "Type" if it is an suitable ref-type, otherwise default back to "ObjectId" const refType = utils.isAnRefType(Type) ? Type : typegoose_1.mongoose.Schema.Types.ObjectId; if ('ref' in rawOptions) { const ref = rawOptions.ref; delete rawOptions.ref; switch (propKind) { case constants_1.PropType.ARRAY: schemaProp[key] = utils.mapArrayOptions(rawOptions, refType, target, key, undefined, { ref }); break; case constants_1.PropType.NONE: schemaProp[key] = { type: refType, ref, ...rawOptions, }; break; case constants_1.PropType.MAP: const mapped = utils.mapOptions(rawOptions, refType, target, key); schemaProp[key] = { ...mapped.outer, type: Map, of: { type: refType, ref, ...mapped.inner, }, }; break; default: throw new errors_1.InvalidPropTypeError(propKind, name, key, 'PropType(ref)'); } return; } if ('refPath' in rawOptions) { const refPath = rawOptions.refPath; delete rawOptions.refPath; utils.assertion(typeof refPath === 'string' && refPath.length > 0, () => new errors_1.StringLengthExpectedError(1, refPath, `${name}.${key}`, 'refPath')); switch (propKind) { case constants_1.PropType.ARRAY: schemaProp[key] = utils.mapArrayOptions(rawOptions, refType, target, key, undefined, { refPath }); break; case constants_1.PropType.NONE: schemaProp[key] = { type: refType, refPath, ...rawOptions, }; break; default: throw new errors_1.InvalidPropTypeError(propKind, name, key, 'PropType(refPath)'); } return; } // check if Type is actually a real working Type if (utils.isNullOrUndefined(Type) || typeof Type !== 'function') { throw new errors_1.InvalidTypeError(name, key, Type); } if (!utils.isNullOrUndefined(rawOptions.enum)) { let useType = rawOptions.enum; let inValues = false; if (rawOptions.enum?.constructor === Object && 'values' in rawOptions.enum) { useType = rawOptions.enum.values; inValues = true; } // disabling lint line, because eslint seemingly cant handle a changing value and a unchanging value in the same destruction // eslint-disable-next-line prefer-const let { dim: enumDim, type: enumType } = utils.getType(useType, true); utils.assertion(enumDim === 1 || enumDim === 0, () => new errors_1.OptionDoesNotSupportOptionError('enum', 'dim', '0 or 1', `dim: ${enumDim}`)); // check if the option is already a array (mongoose enum), if not convert it if (!Array.isArray(enumType)) { if (Type === String || Type === typegoose_1.mongoose.Schema.Types.String) { enumType = Object.entries(enumType) // get all key-value pairs of the enum // no reverse-filtering because if it is full of strings, there is no reverse mapping .map(([enumKey, enumValue]) => { // convert key-value pairs to an mongoose-usable enum // safeguard, this should never happen because TypeScript only sets "design:type" to "String" // if the enum is full of strings if (typeof enumValue !== 'string') { throw new errors_1.NotStringTypeError(name, key, enumKey, typeof enumValue); } return enumValue; }); } else if (Type === Number || Type === typegoose_1.mongoose.Schema.Types.Number) { enumType = Object.entries(enumType) // get all key-value pairs of the enum // filter out the "reverse (value -> name) mappings" // https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings .filter(([enumKey, enumValue], _i, arr) => { // safeguard, this should never happen because typescript only sets "design:type" to "Number" // if the enum is full of numbers if (utils.isNullOrUndefined(enumValue) || arr.findIndex(([k]) => k === enumValue.toString()) <= -1) { // if there is no reverse mapping, throw an error throw new errors_1.NotNumberTypeError(name, key, enumKey, typeof enumValue); } return typeof enumValue === 'number'; }) .map(([enumKey, enumValue]) => { // convert key-value pairs to an mongoose-useable enum if (typeof enumValue !== 'number') { throw new errors_1.NotNumberTypeError(name, key, enumKey, typeof enumValue); } return enumValue; }); } else { // this will happen if the enum type is not "String" or "Number" // most likely this error happened because the code got transpiled with babel or "tsc --transpile-only" throw new errors_1.InvalidEnumTypeError(name, key, Type); } } // re-assign the option with the updated type if (inValues) { rawOptions.enum.values = enumType; } else { rawOptions.enum = enumType; } } if (!utils.isNullOrUndefined(rawOptions.addNullToEnum)) { rawOptions.enum = Array.isArray(rawOptions.enum) ? rawOptions.enum : []; rawOptions.enum.push(null); delete rawOptions.addNullToEnum; } { let included = utils.isWithStringValidate(rawOptions); if (!utils.isString(Type)) { // warn if String-Validate options are included, but is not string utils.warnNotCorrectTypeOptions(name, key, 'String', 'String-Validate', included); } included = utils.isWithStringTransform(rawOptions); if (!utils.isString(Type)) { // warn if String-Transform options are included, but is not string utils.warnNotCorrectTypeOptions(name, key, 'String', 'String-Transform', included); } included = utils.isWithNumberValidate(rawOptions); if (!utils.isNumber(Type)) { // warn if Number-Validate options are included, but is not number utils.warnNotCorrectTypeOptions(name, key, 'Number', 'Number-Validate', included); } included = utils.isWithEnumValidate(rawOptions); if (!utils.isString(Type) && !utils.isNumber(Type)) { // warn if "enum" is included, but is not Number or String utils.warnNotCorrectTypeOptions(name, key, 'String | Number', 'extra', included); } } /** Is this Type (/Class) in the schemas Map? */ const hasCachedSchema = !utils.isNullOrUndefined(Reflect.getMetadata(constants_1.DecoratorKeys.CachedSchema, Type)); if (utils.isPrimitive(Type)) { if (utils.isObject(Type, true)) { utils.warnMixed(target, key); } switch (propKind) { case constants_1.PropType.ARRAY: schemaProp[key] = utils.mapArrayOptions(rawOptions, Type, target, key); return; case constants_1.PropType.MAP: let mapped; let finalType; // Map the correct options for the end type if (utils.isTypeMeantToBeArray(rawOptions)) { mapped = utils.mapOptions(rawOptions, typegoose_1.mongoose.Schema.Types.Array, target, key); // "rawOptions" is not used here, because that would duplicate some options to where the should not be finalType = utils.mapArrayOptions({ ...mapped.inner, dim: rawOptions.dim }, Type, target, key); } else { mapped = utils.mapOptions(rawOptions, Type, target, key); finalType = { ...mapped.inner, type: Type }; } schemaProp[key] = { ...mapped.outer, type: Map, of: { ...finalType }, }; return; case constants_1.PropType.NONE: schemaProp[key] = { ...rawOptions, type: Type, }; return; default: throw new errors_1.InvalidPropTypeError(propKind, name, key, 'PropType(primitive)'); } } // If the 'Type' is not a 'Primitive Type' and no subschema was found treat the type as 'Object' // so that mongoose can store it as nested document if (utils.isObject(Type) && !hasCachedSchema) { utils.warnMixed(target, key); logSettings_1.logger.warn('if someone can see this message, please open an new issue at https://github.com/typegoose/typegoose/issues with reproduction code for tests'); schemaProp[key] = { ...rawOptions, type: typegoose_1.mongoose.Schema.Types.Mixed, }; return; } const virtualSchema = (0, typegoose_1.buildSchema)(Type); switch (propKind) { case constants_1.PropType.ARRAY: schemaProp[key] = utils.mapArrayOptions(rawOptions, virtualSchema, target, key, Type); return; case constants_1.PropType.MAP: // special handling if the lower type should be an array if ('dim' in rawOptions) { logSettings_1.logger.debug('Map SubDocument Array for "%s.%s"', name, key); const { type, ...outer } = utils.mapArrayOptions(rawOptions, virtualSchema, target, key, Type); schemaProp[key] = { ...outer, type: Map, of: type, }; return; } const mapped = utils.mapOptions(rawOptions, virtualSchema, target, key, Type); schemaProp[key] = { ...mapped.outer, type: Map, of: { type: virtualSchema, ...mapped.inner }, }; return; case constants_1.PropType.NONE: schemaProp[key] = { ...rawOptions, type: virtualSchema, }; return; default: throw new errors_1.InvalidPropTypeError(propKind, name, key, 'PropType(subSchema)'); } } exports.processProp = processProp; // The following function ("optionDeprecation") is disabled until used again /** * Check for deprecated options, and if needed process them * @param options */ // function optionDeprecation(options: any) {} /** * Detect "PropType" based on "Type" * @param Type The Type used for detection */ function detectPropType(Type) { logSettings_1.logger.debug('Detecting PropType'); if (Type === Array || Type === typegoose_1.mongoose.Types.Array || Type === typegoose_1.mongoose.Schema.Types.Array || Type === typegoose_1.mongoose.Types.DocumentArray || Type === typegoose_1.mongoose.Schema.Types.DocumentArray) { return constants_1.PropType.ARRAY; } if (Type === Map || Type === typegoose_1.mongoose.Types.Map || Type === typegoose_1.mongoose.Schema.Types.Map) { return constants_1.PropType.MAP; } return constants_1.PropType.NONE; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvY2Vzc1Byb3AuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJuYWwvcHJvY2Vzc1Byb3AudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLGdEQUF3QztBQUN4Qyw0Q0FBa0U7QUFXbEUsMkNBQXNEO0FBQ3RELHFDQWFrQjtBQUNsQix1REFBaUM7QUFFakM7OztHQUdHO0FBQ0gsU0FBZ0IsV0FBVyxDQUFDLEtBQXlCO0lBQ25ELE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDO0lBQzlCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkMsTUFBTSxVQUFVLEdBQWlCLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNsRSxJQUFJLElBQUksR0FBb0IsT0FBTyxDQUFDLFdBQVcsQ0FBQyx5QkFBYSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDakYsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFdEQsb0JBQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZELEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksNEJBQW1CLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFbkYsaUNBQWlDO0lBRWpDLENBQUM7UUFDQyxxQ0FBcUM7UUFDckMsUUFBUSxRQUFRLEVBQUUsQ0FBQztZQUNqQixLQUFLLG9CQUFRLENBQUMsSUFBSTtnQkFDaEIsTUFBTTtZQUNSLEtBQUssb0JBQVEsQ0FBQyxHQUFHLENBQUM7WUFDbEIsS0FBSyxvQkFBUSxDQUFD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