@reldens/storage 0.53.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ /**
2
+ *
3
+ * Reldens - BaseGenerator
4
+ *
5
+ */
6
+
7
+ class BaseGenerator
8
+ {
9
+
10
+ applyReplacements(content, replacements)
11
+ {
12
+ let result = content;
13
+ for(let placeholder of Object.keys(replacements)){
14
+ result = result.replace(new RegExp('{{'+placeholder+'}}','g'), replacements[placeholder]);
15
+ }
16
+ return result;
17
+ }
18
+
19
+ }
20
+
21
+ module.exports.BaseGenerator = BaseGenerator;
@@ -0,0 +1,174 @@
1
+ /**
2
+ *
3
+ * Reldens - EntitiesConfigGeneration
4
+ *
5
+ */
6
+
7
+ const { FileHandler } = require('@reldens/server-utils');
8
+ const { Logger, sc } = require('@reldens/utils');
9
+ const { BaseGenerator } = require('./base-generator');
10
+
11
+ class EntitiesConfigGeneration extends BaseGenerator
12
+ {
13
+
14
+ constructor(props)
15
+ {
16
+ super();
17
+ this.entitiesConfigPath = sc.get(props, 'entitiesConfigPath', '');
18
+ this.templatePath = sc.get(props, 'templatePath', '');
19
+ }
20
+
21
+ generateEntitiesConfigFile(generatedEntities, existingEntities, isOverride)
22
+ {
23
+ if(isOverride){
24
+ return this.regenerateEntitiesConfigFile(generatedEntities, existingEntities);
25
+ }
26
+ return this.appendToEntitiesConfigFile(generatedEntities);
27
+ }
28
+
29
+ regenerateEntitiesConfigFile(generatedEntities, existingEntities)
30
+ {
31
+ let configTemplateContent = FileHandler.fetchFileContents(this.templatePath);
32
+ if(!configTemplateContent){
33
+ Logger.critical('Failed to read entities config template file: '+this.templatePath);
34
+ return false;
35
+ }
36
+ let allEntities = Object.assign({}, existingEntities, generatedEntities);
37
+ let replacements = {
38
+ requireStatements: this.getRequireStatements(allEntities),
39
+ entitiesConfigExport: this.getEntitiesConfigExport(allEntities)
40
+ };
41
+ if(!FileHandler.writeFile(
42
+ this.entitiesConfigPath,
43
+ this.applyReplacements(configTemplateContent, replacements)
44
+ )){
45
+ Logger.critical('Failed to write entities config file: '+this.entitiesConfigPath);
46
+ return false;
47
+ }
48
+ Logger.info('Regenerated entities config file: '+this.entitiesConfigPath);
49
+ return true;
50
+ }
51
+
52
+ appendToEntitiesConfigFile(generatedEntities)
53
+ {
54
+ if(0 === Object.keys(generatedEntities).length){
55
+ return true;
56
+ }
57
+ if(!FileHandler.exists(this.entitiesConfigPath)){
58
+ Logger.info('Entities config file does not exist, creating new file.');
59
+ return this.regenerateEntitiesConfigFile(generatedEntities, {});
60
+ }
61
+ let existingContent = FileHandler.readFile(this.entitiesConfigPath);
62
+ if(!existingContent){
63
+ Logger.error('Could not read existing entities config file.');
64
+ return false;
65
+ }
66
+ let newRequires = [];
67
+ let newConfigs = [];
68
+ for(let tableName of Object.keys(generatedEntities)){
69
+ let entity = generatedEntities[tableName];
70
+ let entityClassName = sc.get(entity, 'entityClassName', sc.capitalizedCamelCase(tableName)+'Entity');
71
+ let entityFileName = sc.get(entity, 'entityFileName', sc.kebabCase(tableName)+'-entity').replace('.js', '');
72
+ let requireStatement = 'const { '+ entityClassName+' } = require(\'./entities/'+entityFileName+'\');';
73
+ let configEntry = sc.camelCase(tableName)+': '+entityClassName+'.propertiesConfig()';
74
+ if(!existingContent.includes(requireStatement)){
75
+ newRequires.push(requireStatement);
76
+ }
77
+ if(!this.entityExistsInConfig(tableName, existingContent)){
78
+ newConfigs.push(configEntry);
79
+ }
80
+ }
81
+ if(0 === newRequires.length && 0 === newConfigs.length){
82
+ return true;
83
+ }
84
+ let normalizedContent = existingContent.replace(/\s+/g, ' ');
85
+ let entitiesConfigPattern = /let\s+entitiesConfig\s*=\s*\{/;
86
+ let entitiesConfigMatch = normalizedContent.match(entitiesConfigPattern);
87
+ if(!entitiesConfigMatch){
88
+ Logger.error('Could not find entitiesConfig variable in config file.');
89
+ return false;
90
+ }
91
+ let entitiesConfigStart = existingContent.indexOf(entitiesConfigMatch[0]);
92
+ let searchStart = entitiesConfigStart + entitiesConfigMatch[0].length;
93
+ let braceCount = 1;
94
+ let entitiesConfigEnd = -1;
95
+ for(let i = searchStart; i < existingContent.length; i++){
96
+ if('{' === existingContent[i]){
97
+ braceCount++;
98
+ }
99
+ if('}' === existingContent[i]){
100
+ braceCount--;
101
+ if(0 === braceCount){
102
+ entitiesConfigEnd = i;
103
+ break;
104
+ }
105
+ }
106
+ }
107
+ if(-1 === entitiesConfigEnd){
108
+ Logger.error('Could not find end of entitiesConfig object.');
109
+ return false;
110
+ }
111
+ let firstRequirePosition = existingContent.indexOf('const {');
112
+ if(-1 === firstRequirePosition){
113
+ Logger.error('Could not find require statements in config file.');
114
+ return false;
115
+ }
116
+ let beforeFirstRequire = existingContent.substring(0, firstRequirePosition);
117
+ let afterFirstRequire = existingContent.substring(firstRequirePosition, entitiesConfigEnd);
118
+ let afterConfig = existingContent.substring(entitiesConfigEnd);
119
+ let updatedContent = beforeFirstRequire;
120
+ if(0 < newRequires.length){
121
+ updatedContent += newRequires.join('\n') + '\n';
122
+ }
123
+ updatedContent += afterFirstRequire;
124
+ if(0 < newConfigs.length){
125
+ let trimmedContent = afterFirstRequire.trimEnd();
126
+ if(!trimmedContent.endsWith(',')){
127
+ updatedContent = updatedContent.trimEnd() + ',';
128
+ }
129
+ updatedContent += '\n ' + newConfigs.join(',\n ');
130
+ }
131
+ updatedContent += afterConfig;
132
+ if(!FileHandler.writeFile(this.entitiesConfigPath, updatedContent)){
133
+ Logger.error('Failed to append to entities config file: '+this.entitiesConfigPath);
134
+ return false;
135
+ }
136
+ Logger.info('Updated entities config file with '+newConfigs.length+' new entities.');
137
+ return true;
138
+ }
139
+
140
+ getRequireStatements(allEntities)
141
+ {
142
+ let requireStatements = [];
143
+ for(let tableName of Object.keys(allEntities)){
144
+ let entity = allEntities[tableName];
145
+ let entityClassName = sc.get(entity, 'entityClassName', sc.capitalizedCamelCase(tableName)+'Entity');
146
+ let entityFileName = sc.get(entity, 'entityFileName', sc.kebabCase(tableName)+'-entity').replace('.js', '');
147
+ requireStatements.push(
148
+ 'const { '+ entityClassName+' } = require(\'./entities/'+entityFileName+'\');'
149
+ );
150
+ }
151
+ return requireStatements.join('\n');
152
+ }
153
+
154
+ getEntitiesConfigExport(allEntities)
155
+ {
156
+ let entitiesConfigExport = [];
157
+ for(let tableName of Object.keys(allEntities)){
158
+ entitiesConfigExport.push(
159
+ sc.camelCase(tableName)+': '
160
+ +sc.get(allEntities[tableName], 'entityClassName', sc.capitalizedCamelCase(tableName)+'Entity')
161
+ +'.propertiesConfig()'
162
+ );
163
+ }
164
+ return entitiesConfigExport.join(',\n ');
165
+ }
166
+
167
+ entityExistsInConfig(tableName, configContent)
168
+ {
169
+ return configContent.includes(sc.camelCase(tableName)+':');
170
+ }
171
+
172
+ }
173
+
174
+ module.exports.EntitiesConfigGeneration = EntitiesConfigGeneration;
@@ -0,0 +1,286 @@
1
+ /**
2
+ *
3
+ * Reldens - EntitiesGeneration
4
+ *
5
+ */
6
+
7
+ const { FileHandler } = require('@reldens/server-utils');
8
+ const { Logger, sc } = require('@reldens/utils');
9
+ const { TypeMapper } = require('../type-mapper');
10
+ const { BaseGenerator } = require('./base-generator');
11
+
12
+ class EntitiesGeneration extends BaseGenerator
13
+ {
14
+
15
+ constructor(props)
16
+ {
17
+ super();
18
+ this.entitiesFolder = sc.get(props, 'entitiesFolder', '');
19
+ this.templatePath = sc.get(props, 'templatePath', '');
20
+ this.generatedEntities = {};
21
+ }
22
+
23
+ async generateEntityFile(tableName, tableData)
24
+ {
25
+ if(!FileHandler.exists(this.templatePath)){
26
+ Logger.critical('Entity template file not found: '+this.templatePath);
27
+ return false;
28
+ }
29
+ let entityTemplateContent = FileHandler.fetchFileContents(this.templatePath);
30
+ if(!entityTemplateContent){
31
+ Logger.critical('Failed to read entity template file: '+this.templatePath);
32
+ return false;
33
+ }
34
+ let entityClassName = sc.capitalizedCamelCase(tableName)+'Entity';
35
+ let titleProperty = this.determineTitleProperty(tableData.columns);
36
+ for(let columnName of Object.keys(tableData.columns)){
37
+ tableData.columns[columnName].tableName = tableName;
38
+ }
39
+ let propertiesConfig = this.generatePropertiesConfig(tableData.columns, titleProperty);
40
+ let titlePropertyDeclaration = titleProperty ? '\n let titleProperty = \''+titleProperty+'\';' : '';
41
+ let titlePropertyReturn = titleProperty ? '\n titleProperty,' : '';
42
+ let fieldsToRemoveFromEdit = ['id'];
43
+ if(tableData.columns['created_at']){
44
+ fieldsToRemoveFromEdit.push('created_at');
45
+ }
46
+ if(tableData.columns['updated_at']){
47
+ fieldsToRemoveFromEdit.push('updated_at');
48
+ }
49
+ let editPropertiesRemoval = this.getEditPropertiesRemoval(fieldsToRemoveFromEdit);
50
+ let listPropertiesDeclaration = this.getListPropertiesDeclaration(tableData.columns);
51
+ let showPropertiesDeclaration = this.getShowPropertiesDeclaration(tableData.columns);
52
+ let needsSc = listPropertiesDeclaration.includes('sc.removeFromArray')
53
+ || editPropertiesRemoval.includes('sc.removeFromArray')
54
+ || showPropertiesDeclaration.includes('sc.removeFromArray');
55
+ let scRequire = needsSc ? '\nconst { sc } = require(\'@reldens/utils\');' : '';
56
+ let replacements = {
57
+ entityClassName,
58
+ propertiesConfig,
59
+ titlePropertyDeclaration,
60
+ titlePropertyReturn,
61
+ showPropertiesDeclaration,
62
+ editPropertiesRemoval,
63
+ listPropertiesDeclaration,
64
+ scRequire
65
+ };
66
+ let entityContent = this.applyReplacements(entityTemplateContent, replacements);
67
+ let fileName = sc.kebabCase(tableName)+'-entity.js';
68
+ let filePath = FileHandler.joinPaths(this.entitiesFolder, fileName);
69
+ if(!FileHandler.writeFile(filePath, entityContent)){
70
+ Logger.critical('Failed to write entity file: '+filePath);
71
+ return false;
72
+ }
73
+ Logger.info('Generated entity file: '+fileName);
74
+ this.generatedEntities[tableName] = {
75
+ entityClassName,
76
+ entityFileName: fileName,
77
+ tableName,
78
+ titleProperty
79
+ };
80
+ return true;
81
+ }
82
+
83
+ getFieldsToRemoveFromList(columns)
84
+ {
85
+ let fieldsToRemove = [];
86
+ for(let columnName of Object.keys(columns)){
87
+ let column = columns[columnName];
88
+ let type = column.type.toLowerCase();
89
+ if(['text', 'json', 'tinytext', 'mediumtext', 'longtext'].includes(type)){
90
+ fieldsToRemove.push(columnName);
91
+ }
92
+ if('password' === columnName.toLowerCase()){
93
+ fieldsToRemove.push(columnName);
94
+ }
95
+ }
96
+ return fieldsToRemove;
97
+ }
98
+
99
+ getEditPropertiesRemoval(fieldsToRemove)
100
+ {
101
+ if(1 === fieldsToRemove.length){
102
+ return 'let editProperties = [...propertiesKeys];\n editProperties.splice(editProperties.indexOf(\''+
103
+ fieldsToRemove[0]
104
+ +'\'), 1);';
105
+ }
106
+ return 'let editProperties = sc.removeFromArray([...propertiesKeys], [\''+fieldsToRemove.join('\', \'')+'\']);';
107
+ }
108
+
109
+ determineTitleProperty(columns)
110
+ {
111
+ if(columns['label']){
112
+ return 'label';
113
+ }
114
+ if(columns['title']){
115
+ return 'title';
116
+ }
117
+ if(columns['name']){
118
+ return 'name';
119
+ }
120
+ if(columns['key']){
121
+ return 'key';
122
+ }
123
+ return false;
124
+ }
125
+
126
+ generatePropertiesConfig(columns, titleProperty)
127
+ {
128
+ let propertiesConfig = [];
129
+ for(let columnName of Object.keys(columns)){
130
+ let column = columns[columnName];
131
+ let propertyKey = titleProperty && titleProperty === columnName ? '[titleProperty]' : columnName;
132
+ if('id' === columnName){
133
+ propertiesConfig.push(columnName+': {}');
134
+ continue;
135
+ }
136
+ let props = this.getPropertyAttributes(column);
137
+ if(0 === props.length){
138
+ propertiesConfig.push(propertyKey+': {}');
139
+ continue;
140
+ }
141
+ propertiesConfig.push(
142
+ propertyKey+': {\n '+props.join(',\n ')+ '\n }'
143
+ );
144
+ }
145
+ return propertiesConfig.join(',\n ');
146
+ }
147
+
148
+ getPropertyAttributes(column)
149
+ {
150
+ let props = [];
151
+ let type = column.type.toLowerCase();
152
+ this.addTypeAttribute(props, column, type);
153
+ this.addRequiredAttribute(props, column);
154
+ return props;
155
+ }
156
+
157
+ addTypeAttribute(props, column, type)
158
+ {
159
+ if(column.referencedTable){
160
+ props.push('type: \'reference\'');
161
+ props.push('reference: \''+this.getReferenceTable(column)+'\'');
162
+ return;
163
+ }
164
+ if('date' === type || 'datetime' === type || 'timestamp' === type){
165
+ props.push('type: \'datetime\'');
166
+ return;
167
+ }
168
+ if('text' === type || 'longtext' === type || 'mediumtext' === type || 'tinytext' === type || 'json' === type){
169
+ props.push('type: \'textarea\'');
170
+ return;
171
+ }
172
+ if('tinyint' === type){
173
+ props.push('type: \'boolean\'');
174
+ return;
175
+ }
176
+ if('enum' === type){
177
+ this.addEnumValues(props, column);
178
+ return;
179
+ }
180
+ if(type.includes('int')){
181
+ props.push('type: \'number\'');
182
+ return;
183
+ }
184
+ if('varchar' === type || 'char' === type){
185
+ return;
186
+ }
187
+ let jsType = TypeMapper.mapDbTypeToJsType(type);
188
+ if(jsType && 'string' !== jsType){
189
+ props.push('type: \''+jsType+'\'');
190
+ }
191
+ }
192
+
193
+ addEnumValues(props, column)
194
+ {
195
+ let enumValues = this.parseEnumValues(column.columnType);
196
+ if(0 === enumValues.length){
197
+ return;
198
+ }
199
+ let availableValues = [];
200
+ for(let i = 0; i < enumValues.length; i++){
201
+ availableValues.push('{value: '+(i+1)+', label: \''+enumValues[i]+'\'}');
202
+ }
203
+ props.push(
204
+ 'availableValues: [\n '+
205
+ availableValues.join(',\n ')+
206
+ '\n ]'
207
+ );
208
+ }
209
+
210
+ parseEnumValues(columnType)
211
+ {
212
+ if(!columnType){
213
+ return [];
214
+ }
215
+ let match = columnType.match(/^enum\('(.+)'\)$/i);
216
+ if(!match){
217
+ return [];
218
+ }
219
+ let valuesString = match[1];
220
+ return valuesString.split('\',\'');
221
+ }
222
+
223
+ addRequiredAttribute(props, column)
224
+ {
225
+ if(!column.nullable && !column.default){
226
+ props.push('isRequired: true');
227
+ }
228
+ }
229
+
230
+ getReferenceTable(column)
231
+ {
232
+ if(column.referencedTable){
233
+ return column.referencedTable;
234
+ }
235
+ let refTableName = column.name.replace('_id', '');
236
+ if(refTableName.includes('_')){
237
+ let parts = refTableName.split('_');
238
+ if(column.tableName && column.tableName === parts[0]){
239
+ refTableName = parts.slice(1).join('_');
240
+ }
241
+ }
242
+ return refTableName;
243
+ }
244
+
245
+ getShowPropertiesDeclaration(columns)
246
+ {
247
+ let passwordFields = this.getPasswordFields(columns);
248
+ if(0 === passwordFields.length){
249
+ return 'let showProperties = propertiesKeys;';
250
+ }
251
+ if(1 === passwordFields.length){
252
+ return 'let showProperties = [...propertiesKeys];\n showProperties.splice(showProperties.indexOf(\''+
253
+ passwordFields[0]+
254
+ '\'), 1);';
255
+ }
256
+ return 'let showProperties = sc.removeFromArray([...propertiesKeys], [\''+passwordFields.join('\', \'')+'\']);';
257
+ }
258
+
259
+ getPasswordFields(columns)
260
+ {
261
+ let passwordFields = [];
262
+ for(let columnName of Object.keys(columns)){
263
+ if('password' === columnName.toLowerCase()){
264
+ passwordFields.push(columnName);
265
+ }
266
+ }
267
+ return passwordFields;
268
+ }
269
+
270
+ getListPropertiesDeclaration(columns)
271
+ {
272
+ let fieldsToRemove = this.getFieldsToRemoveFromList(columns);
273
+ if(0 === fieldsToRemove.length){
274
+ return 'let listProperties = propertiesKeys;';
275
+ }
276
+ if(1 === fieldsToRemove.length){
277
+ return 'let listProperties = [...propertiesKeys];\n listProperties.splice(listProperties.indexOf(\''+
278
+ fieldsToRemove[0]+
279
+ '\'), 1);';
280
+ }
281
+ return 'let listProperties = sc.removeFromArray([...propertiesKeys], [\''+fieldsToRemove.join('\', \'')+'\']);';
282
+ }
283
+
284
+ }
285
+
286
+ module.exports.EntitiesGeneration = EntitiesGeneration;
@@ -0,0 +1,135 @@
1
+ /**
2
+ *
3
+ * Reldens - EntitiesTranslationsGeneration
4
+ *
5
+ */
6
+
7
+ const { FileHandler } = require('@reldens/server-utils');
8
+ const { Logger, sc } = require('@reldens/utils');
9
+ const { BaseGenerator } = require('./base-generator');
10
+
11
+ class EntitiesTranslationsGeneration extends BaseGenerator
12
+ {
13
+
14
+ constructor(props)
15
+ {
16
+ super();
17
+ this.entitiesTranslationsPath = sc.get(props, 'entitiesTranslationsPath', '');
18
+ this.templatePath = sc.get(props, 'templatePath', '');
19
+ }
20
+
21
+ generateEntitiesTranslationsFile(generatedEntities, existingEntities, isOverride)
22
+ {
23
+ if(isOverride){
24
+ return this.regenerateEntitiesTranslationsFile(generatedEntities, existingEntities);
25
+ }
26
+ return this.appendToEntitiesTranslationsFile(generatedEntities);
27
+ }
28
+
29
+ regenerateEntitiesTranslationsFile(generatedEntities, existingEntities)
30
+ {
31
+ if(!FileHandler.exists(this.templatePath)){
32
+ Logger.critical('Entities translations template file not found: '+this.templatePath);
33
+ return false;
34
+ }
35
+ let translationsTemplateContent = FileHandler.fetchFileContents(this.templatePath);
36
+ if(!translationsTemplateContent){
37
+ Logger.critical('Failed to read entities translations template file: '+this.templatePath);
38
+ return false;
39
+ }
40
+ let translationsContent = translationsTemplateContent.replace(
41
+ /{{labels}}/g,
42
+ this.getTranslationLabels(Object.assign({}, existingEntities, generatedEntities))
43
+ );
44
+ if(!FileHandler.writeFile(this.entitiesTranslationsPath, translationsContent)){
45
+ Logger.critical('Failed to write entities translations file: '+this.entitiesTranslationsPath);
46
+ return false;
47
+ }
48
+ Logger.info('Regenerated entities translations file: '+this.entitiesTranslationsPath);
49
+ return true;
50
+ }
51
+
52
+ appendToEntitiesTranslationsFile(generatedEntities)
53
+ {
54
+ if(0 === Object.keys(generatedEntities).length){
55
+ return true;
56
+ }
57
+ if(!FileHandler.exists(this.entitiesTranslationsPath)){
58
+ Logger.info('Entities translations file does not exist, creating new file.');
59
+ return this.regenerateEntitiesTranslationsFile(generatedEntities, {});
60
+ }
61
+ let existingContent = FileHandler.readFile(this.entitiesTranslationsPath);
62
+ if(!existingContent){
63
+ Logger.error('Could not read existing translations file.');
64
+ return false;
65
+ }
66
+ let newTranslations = [];
67
+ for(let tableName of Object.keys(generatedEntities)){
68
+ if(!existingContent.includes('\''+tableName+'\':')){
69
+ newTranslations.push(
70
+ '\''+tableName+'\': \''
71
+ +tableName.split('_').map(word => word.charAt(0).toUpperCase()+word.slice(1)).join(' ')+'\''
72
+ );
73
+ }
74
+ }
75
+ if(0 === newTranslations.length){
76
+ return true;
77
+ }
78
+ let normalizedContent = existingContent.replace(/\s+/g, ' ');
79
+ let labelsPattern = /labels\s*:\s*\{/;
80
+ let labelsMatch = normalizedContent.match(labelsPattern);
81
+ if(!labelsMatch){
82
+ Logger.error('Could not find labels object in translations file.');
83
+ return false;
84
+ }
85
+ let labelsStart = existingContent.indexOf(labelsMatch[0]);
86
+ let searchStart = labelsStart + labelsMatch[0].length;
87
+ let braceCount = 1;
88
+ let labelsEnd = -1;
89
+ for(let i = searchStart; i < existingContent.length; i++){
90
+ if('{' === existingContent[i]){
91
+ braceCount++;
92
+ }
93
+ if('}' === existingContent[i]){
94
+ braceCount--;
95
+ if(0 === braceCount){
96
+ labelsEnd = i;
97
+ break;
98
+ }
99
+ }
100
+ }
101
+ if(-1 === labelsEnd){
102
+ Logger.error('Could not find end of labels object.');
103
+ return false;
104
+ }
105
+ let beforeLabelsEnd = existingContent.substring(0, labelsEnd);
106
+ let contentBeforeEnd = beforeLabelsEnd.trimEnd();
107
+ let lastChar = contentBeforeEnd[contentBeforeEnd.length - 1];
108
+ if('{' !== lastChar && ',' !== lastChar){
109
+ beforeLabelsEnd = contentBeforeEnd + ',';
110
+ }
111
+ let updatedContent = beforeLabelsEnd + '\n ' + newTranslations.join(',\n ') + existingContent.substring(labelsEnd);
112
+ if(!FileHandler.writeFile(this.entitiesTranslationsPath, updatedContent)){
113
+ Logger.error('Failed to append to entities translations file: '+this.entitiesTranslationsPath);
114
+ return false;
115
+ }
116
+ Logger.info('Updated translations file with '+newTranslations.length+' new labels.');
117
+ return true;
118
+ }
119
+
120
+ getTranslationLabels(allEntities)
121
+ {
122
+ let labels = [];
123
+ for(let tableName of Object.keys(allEntities)){
124
+ labels.push(
125
+ '\''+tableName+'\': \''
126
+ +tableName.split('_').map(word => word.charAt(0).toUpperCase()+word.slice(1)).join(' ')
127
+ +'\''
128
+ );
129
+ }
130
+ return labels.join(',\n ');
131
+ }
132
+
133
+ }
134
+
135
+ module.exports.EntitiesTranslationsGeneration = EntitiesTranslationsGeneration;