UNPKG

14.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports._buildSchema = void 0;
4const mongoose = require("mongoose");
5const logSettings_1 = require("../logSettings");
6const typegoose_1 = require("../typegoose");
7const constants_1 = require("./constants");
8const data_1 = require("./data");
9const errors_1 = require("./errors");
10const processProp_1 = require("./processProp");
11const utils_1 = require("./utils");
12/**
13 * Internal Schema Builder for Classes
14 * This Function should not be used directly outside of typegoose internals, use "buildSchema" from typegoose.ts directly
15 * @param cl The Class to build a Model from
16 * @param origSch A Schema to clone and extend onto
17 * @param opt Overwrite SchemaOptions (Merged with Decorator Options)
18 * @param isFinalSchema Set if this Schema is the final (top-level) to build, only when "true" are discriminators, hooks, virtuals, etc applied
19 * @param overwriteNaming Overwrite options for name generation
20 * @param extraOptions Extra options to affect what needs to be done
21 * @returns Returns the Build Schema
22 * @private
23 */
24function _buildSchema(cl, origSch, opt, isFinalSchema = true, overwriteNaming, extraOptions) {
25 (0, utils_1.assertionIsClass)(cl);
26 (0, utils_1.assignGlobalModelOptions)(cl); // to ensure global options are applied to the current class
27 // Options sanity check
28 opt = (0, utils_1.mergeSchemaOptions)((0, utils_1.isNullOrUndefined)(opt) || typeof opt !== 'object' ? {} : opt, cl);
29 const finalName = (0, utils_1.getName)(cl, overwriteNaming);
30 logSettings_1.logger.debug('_buildSchema Called for %s with options:', finalName, opt);
31 /** Simplify the usage */
32 const Schema = mongoose.Schema;
33 const ropt = Reflect.getMetadata(constants_1.DecoratorKeys.ModelOptions, cl) ?? {};
34 const schemaOptions = Object.assign({}, ropt?.schemaOptions ?? {}, opt);
35 const decorators = Reflect.getMetadata(constants_1.DecoratorKeys.PropCache, cl.prototype);
36 if (!(0, utils_1.isNullOrUndefined)(decorators)) {
37 for (const decorator of decorators.values()) {
38 (0, processProp_1.processProp)({ ...decorator, cl: cl });
39 }
40 }
41 let sch;
42 {
43 const schemaReflectTarget = (0, utils_1.getCachedSchema)(cl);
44 if (!(origSch instanceof Schema)) {
45 sch = new Schema(schemaReflectTarget, schemaOptions);
46 }
47 else {
48 sch = origSch.clone();
49 sch.add(schemaReflectTarget);
50 }
51 }
52 sch.loadClass(cl);
53 // in the block below are all the things that need to be done for each class, not just the final schema
54 // for example when using "getOwnMetadata" over "getMetadata" (and having a clone in there)
55 {
56 /** Get Metadata for indices */
57 const indices = Reflect.getOwnMetadata(constants_1.DecoratorKeys.Index, cl);
58 const buildIndexes = typeof extraOptions?.buildIndexes === 'boolean' ? extraOptions?.buildIndexes : true;
59 if (Array.isArray(indices) && buildIndexes) {
60 for (const index of indices) {
61 logSettings_1.logger.debug('Applying Index:', index);
62 sch.index(index.fields, index.options);
63 }
64 }
65 }
66 if (isFinalSchema) {
67 /** Get Metadata for Nested Discriminators */
68 const disMap = Reflect.getMetadata(constants_1.DecoratorKeys.NestedDiscriminators, cl);
69 if (disMap instanceof Map) {
70 for (const [key, discriminators] of disMap) {
71 logSettings_1.logger.debug('Applying Nested Discriminators for:', key, discriminators);
72 const path = sch.path(key);
73 (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(path), () => new errors_1.PathNotInSchemaError(finalName, key));
74 (0, utils_1.assertion)(typeof path.discriminator === 'function', () => new errors_1.NoDiscriminatorFunctionError(finalName, key));
75 for (const { type: child, value: childName } of discriminators) {
76 const childSch = (0, utils_1.getName)(child) === finalName ? sch : (0, typegoose_1.buildSchema)(child);
77 const discriminatorKey = childSch.get('discriminatorKey');
78 if (!!discriminatorKey && childSch.path(discriminatorKey)) {
79 // skip this check, otherwise "extends DiscriminatorBase" would not be allowed (discriminators cannot have the discriminator key defined multiple times)
80 childSch.paths[discriminatorKey].options.$skipDiscriminatorCheck = true;
81 }
82 path.discriminator((0, utils_1.getName)(child), childSch, childName);
83 }
84 }
85 }
86 // Hooks
87 {
88 /** Get Metadata for PreHooks */
89 const preHooks = Reflect.getMetadata(constants_1.DecoratorKeys.HooksPre, cl);
90 if (Array.isArray(preHooks)) {
91 // "as any" is used here because mongoose explicitly types out many methods, but the input type (from IHooksArray) is a combination of multiple types
92 preHooks.forEach((obj) => callCorrectSignature(sch, 'pre', obj));
93 }
94 /** Get Metadata for PreHooks */
95 const postHooks = Reflect.getMetadata(constants_1.DecoratorKeys.HooksPost, cl);
96 if (Array.isArray(postHooks)) {
97 // "as any" is used here because mongoose explicitly types out many methods, but the input type (from IHooksArray) is a combination of multiple types
98 postHooks.forEach((obj) => callCorrectSignature(sch, 'post', obj));
99 }
100 }
101 /** Get Metadata for Virtual Populates */
102 const virtuals = Reflect.getMetadata(constants_1.DecoratorKeys.VirtualPopulate, cl);
103 if (virtuals instanceof Map) {
104 for (const [key, options] of virtuals) {
105 logSettings_1.logger.debug('Applying Virtual Populates:', key, options);
106 sch.virtual(key, options);
107 }
108 }
109 /** Get Metadata for Query Methods */
110 const queryMethods = Reflect.getMetadata(constants_1.DecoratorKeys.QueryMethod, cl);
111 if (queryMethods instanceof Map) {
112 for (const [funcName, func] of queryMethods) {
113 logSettings_1.logger.debug('Applying Query Method:', funcName, func);
114 sch.query[funcName] = func;
115 }
116 }
117 /** Get Metadata for indices */
118 const plugins = Reflect.getMetadata(constants_1.DecoratorKeys.Plugins, cl);
119 if (Array.isArray(plugins)) {
120 for (const plugin of plugins) {
121 logSettings_1.logger.debug('Applying Plugin:', plugin);
122 sch.plugin(plugin.mongoosePlugin, plugin.options);
123 }
124 }
125 // this method is to get the typegoose name of the model/class if it is user-handled (like buildSchema, then manually mongoose.model)
126 sch.method('typegooseName', () => {
127 return finalName;
128 });
129 }
130 // add the class to the constructors map
131 data_1.constructors.set(finalName, cl);
132 return sch;
133}
134exports._buildSchema = _buildSchema;
135/**
136 * Helper function to call the correct signature for a given "fnToCall" (pre / post hooks)
137 * @param fnToCall The function to call (sch.pre / sch.post)
138 * @param obj The object to call as arguments with
139 */
140function callCorrectSignature(sch, fn, obj) {
141 // we have to bind "sch", otherwise "this" will not be defined in the "pre / post" functions
142 const fnToCall = (fn === 'pre' ? sch.pre : sch.post).bind(sch);
143 if (!(0, utils_1.isNullOrUndefined)(obj.options)) {
144 return fnToCall(obj.methods, obj.options, obj.func);
145 }
146 return fnToCall(obj.methods, obj.func);
147}
148//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludGVybmFsL3NjaGVtYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxQ0FBcUM7QUFDckMsZ0RBQXdDO0FBQ3hDLDRDQUEyQztBQWMzQywyQ0FBNEM7QUFDNUMsaUNBQXNDO0FBQ3RDLHFDQUE4RTtBQUM5RSwrQ0FBNEM7QUFDNUMsbUNBUWlCO0FBRWpCOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsU0FBZ0IsWUFBWSxDQUMxQixFQUFLLEVBQ0wsT0FBOEIsRUFDOUIsR0FBNEIsRUFDNUIsZ0JBQXlCLElBQUksRUFDN0IsZUFBZ0MsRUFDaEMsWUFBa0M7SUFFbEMsSUFBQSx3QkFBZ0IsRUFBQyxFQUFFLENBQUMsQ0FBQztJQUVyQixJQUFBLGdDQUF3QixFQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsNERBQTREO0lBRTFGLHVCQUF1QjtJQUN2QixHQUFHLEdBQUcsSUFBQSwwQkFBa0IsRUFBQyxJQUFBLHlCQUFpQixFQUFDLEdBQUcsQ0FBQyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFM0YsTUFBTSxTQUFTLEdBQUcsSUFBQSxlQUFPLEVBQUMsRUFBRSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBRS9DLG9CQUFNLENBQUMsS0FBSyxDQUFDLDBDQUEwQyxFQUFFLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUV6RSx5QkFBeUI7SUFDekIsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQztJQUMvQixNQUFNLElBQUksR0FBa0IsT0FBTyxDQUFDLFdBQVcsQ0FBQyx5QkFBYSxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEYsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFB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
\No newline at end of file