1 | "use strict";
|
2 | const Mongoose = require('mongoose');
|
3 | const Sequelize = require("sequelize");
|
4 | const decorators_1 = require('../core/constants/decorators');
|
5 | const utils_1 = require("../core/metadata/utils");
|
6 | const sequelizeService_1 = require('./sequelizeService');
|
7 | class DynamicSchema {
|
8 | constructor(target, name, tableSpecs) {
|
9 | this._relations = {};
|
10 | this._defaultPrimaryKey = null;
|
11 | this._removeColumnProperties = ['name', 'otherProperties'];
|
12 | this.target = target;
|
13 | this.schemaName = name;
|
14 | this.parsedSchema = this.parse(target);
|
15 | this._tablespecs = tableSpecs;
|
16 | this._schema = sequelizeService_1.sequelizeService.addScheam(this.schemaName, this.parsedSchema, this._tablespecs);
|
17 | if (this._defaultPrimaryKey) {
|
18 | this._schema.beforeCreate((user, _) => {
|
19 | let id = this['_defaultPrimaryKey'](user);
|
20 | user[this._schema.primaryKeyField] = id;
|
21 | return user;
|
22 | });
|
23 | }
|
24 | }
|
25 | getSchema() {
|
26 | return this._schema;
|
27 | }
|
28 | getRelations() {
|
29 | return this._relations;
|
30 | }
|
31 | getTarget() {
|
32 | return this.target;
|
33 | }
|
34 | parse(target) {
|
35 | if (!target || !(target instanceof Object)) {
|
36 | throw TypeError;
|
37 | }
|
38 | var schema = {};
|
39 | var primaryKeyProp;
|
40 |
|
41 | var metaDataMap = utils_1.MetaUtils.getMetaData(this.target, decorators_1.Decorators.COLUMN);
|
42 | for (var field in metaDataMap) {
|
43 | var fieldMetadata = metaDataMap[field];
|
44 | let newParam = {};
|
45 | Object.keys(fieldMetadata.params).forEach(x => {
|
46 | if (this._removeColumnProperties.indexOf(x) < 0) {
|
47 | newParam[x] = fieldMetadata.params[x];
|
48 | }
|
49 | else if (x == 'otherProperties') {
|
50 | Object.keys(fieldMetadata.params[x]).forEach(subProp => {
|
51 | newParam[subProp] = fieldMetadata.params[x][subProp];
|
52 | });
|
53 | }
|
54 | });
|
55 | if (fieldMetadata.params.primaryKey && typeof fieldMetadata.params.defaultValue == "function") {
|
56 | this._defaultPrimaryKey = fieldMetadata.params.defaultValue;
|
57 | delete newParam['defaultValue'];
|
58 | }
|
59 | schema[fieldMetadata.params.name] = newParam;
|
60 | }
|
61 | var metaDataMap1 = utils_1.MetaUtils.getMetaData(this.target, decorators_1.Decorators.ONETOMANY);
|
62 | var oneTomanyrels = [];
|
63 | for (var field in metaDataMap1) {
|
64 | var fieldMetadata = metaDataMap1[field];
|
65 | var params = fieldMetadata.params;
|
66 | params.propertyKey = fieldMetadata.propertyKey;
|
67 | if (!params.foreignKey)
|
68 | throw 'Please add foreign key for association ' + this.schemaName + ' -> ' + params.propertyKey;
|
69 | oneTomanyrels.push(params);
|
70 | }
|
71 | this._relations[decorators_1.Decorators.ONETOMANY] = oneTomanyrels;
|
72 | var metaDataMap2 = utils_1.MetaUtils.getMetaData(this.target, decorators_1.Decorators.MANYTOONE);
|
73 | var manytoonerels = [];
|
74 | for (var field in metaDataMap2) {
|
75 | var fieldMetadata = metaDataMap2[field];
|
76 | var params = fieldMetadata.params;
|
77 | params.propertyKey = fieldMetadata.propertyKey;
|
78 | if (!params.foreignKey)
|
79 | throw 'Please add foreign key for association ' + this.schemaName + ' -> ' + params.propertyKey;
|
80 | else if (!schema[params.foreignKey])
|
81 | throw 'Please choose a valid foreign key from the defined properties for ' + this.schemaName + ' -> ' + params.propertyKey;
|
82 | manytoonerels.push(params);
|
83 | }
|
84 | this._relations[decorators_1.Decorators.MANYTOONE] = manytoonerels;
|
85 | var metaDataMap3 = utils_1.MetaUtils.getMetaData(this.target, decorators_1.Decorators.ONETOONE);
|
86 | var onetoonerels = [];
|
87 | for (var field in metaDataMap3) {
|
88 | var fieldMetadata = metaDataMap3[field];
|
89 | var params = fieldMetadata.params;
|
90 | params.propertyKey = fieldMetadata.propertyKey;
|
91 | if (!params.foreignKey)
|
92 | throw 'Please add foreign key for association ' + this.schemaName + ' -> ' + params.propertyKey;
|
93 | onetoonerels.push(params);
|
94 | }
|
95 | this._relations[decorators_1.Decorators.ONETOONE] = onetoonerels;
|
96 | return schema;
|
97 | }
|
98 | getSearchSchemaTypeForParam(fieldMetadata) {
|
99 | var schemaType = this.getSchemaTypeForType(fieldMetadata.getType());
|
100 | if (fieldMetadata.params && fieldMetadata.params.rel) {
|
101 | return fieldMetadata.propertyType.isArray ? [schemaType] : schemaType;
|
102 | }
|
103 | else {
|
104 | return fieldMetadata.propertyType.isArray ? [schemaType] : { type: schemaType, es_indexed: true };
|
105 | }
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | }
|
121 | getSchemaTypeForParam(fieldMetadata) {
|
122 | var schemaType = this.getSchemaTypeForType(fieldMetadata.getType());
|
123 | return fieldMetadata.propertyType.isArray ? [schemaType] : schemaType;
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 | }
|
139 | getSchemaTypeForType(type) {
|
140 | switch (type) {
|
141 | case Mongoose.Types.ObjectId: return Mongoose.Schema.Types.ObjectId;
|
142 | case String: return Sequelize.STRING(128);
|
143 | case Number: return Number;
|
144 | case Buffer: return Buffer;
|
145 | case Date: return Date;
|
146 | case Boolean: return Boolean;
|
147 | case Array: return Array;
|
148 |
|
149 |
|
150 | case Object:
|
151 | default: return Mongoose.Schema.Types.Mixed;
|
152 | }
|
153 | }
|
154 | getMongooseOptions(target) {
|
155 | var meta = utils_1.MetaUtils.getMetaData(target, decorators_1.Decorators.ENTITY);
|
156 | var entityMeta = meta[0];
|
157 | var options = {};
|
158 | var params = (entityMeta.params || {});
|
159 | options.strict = true;
|
160 | return options;
|
161 | }
|
162 | isSchemaDecorator(decorator) {
|
163 | return decorator === decorators_1.Decorators.FIELD || decorator === decorators_1.Decorators.ONETOMANY || decorator === decorators_1.Decorators.MANYTOONE || decorator === decorators_1.Decorators.MANYTOMANY || decorator === decorators_1.Decorators.ONETOONE;
|
164 | }
|
165 | getAllMetadataForSchema(target) {
|
166 | var metaDataMap = utils_1.MetaUtils.getMetaData(target);
|
167 | var metaDataMapFiltered = {};
|
168 | for (var i in metaDataMap) {
|
169 | var meta = metaDataMap[i];
|
170 | if (!this.isSchemaDecorator(meta.decorator))
|
171 | continue;
|
172 | if (metaDataMapFiltered[meta.propertyKey])
|
173 | throw "A property cannot have more than one schema decorator";
|
174 | metaDataMapFiltered[meta.propertyKey] = meta;
|
175 | }
|
176 | return metaDataMapFiltered;
|
177 | }
|
178 | }
|
179 | exports.DynamicSchema = DynamicSchema;
|
180 |
|
181 |
|