@reldens/cms 0.4.0 → 0.6.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.
Files changed (48) hide show
  1. package/README.md +1 -1
  2. package/admin/assets/admin/filters.png +0 -0
  3. package/admin/assets/admin/list.png +0 -0
  4. package/admin/reldens-admin-client.css +830 -0
  5. package/admin/reldens-admin-client.js +272 -0
  6. package/admin/templates/dashboard.html +1 -0
  7. package/admin/templates/default-copyright.html +5 -0
  8. package/admin/templates/edit.html +25 -0
  9. package/admin/templates/fields/edit/button.html +3 -0
  10. package/admin/templates/fields/edit/checkbox.html +1 -0
  11. package/admin/templates/fields/edit/file.html +2 -0
  12. package/admin/templates/fields/edit/radio.html +1 -0
  13. package/admin/templates/fields/edit/select.html +5 -0
  14. package/admin/templates/fields/edit/text.html +1 -0
  15. package/admin/templates/fields/edit/textarea.html +1 -0
  16. package/admin/templates/fields/view/boolean.html +1 -0
  17. package/admin/templates/fields/view/image.html +4 -0
  18. package/admin/templates/fields/view/images.html +7 -0
  19. package/admin/templates/fields/view/link.html +1 -0
  20. package/admin/templates/fields/view/links.html +6 -0
  21. package/admin/templates/fields/view/text.html +1 -0
  22. package/admin/templates/layout.html +37 -0
  23. package/admin/templates/list-content.html +70 -0
  24. package/admin/templates/list.html +35 -0
  25. package/admin/templates/login.html +19 -0
  26. package/admin/templates/management.html +22 -0
  27. package/admin/templates/maps-wizard-maps-selection.html +85 -0
  28. package/admin/templates/maps-wizard.html +341 -0
  29. package/admin/templates/objects-import.html +143 -0
  30. package/admin/templates/pagination-link.html +1 -0
  31. package/admin/templates/sidebar-header.html +4 -0
  32. package/admin/templates/sidebar-item.html +3 -0
  33. package/admin/templates/sidebar.html +11 -0
  34. package/admin/templates/skills-import.html +201 -0
  35. package/admin/templates/view.html +23 -0
  36. package/bin/reldens-cms.js +19 -7
  37. package/index.js +2 -2
  38. package/install/index.html +5 -7
  39. package/lib/entities-loader.js +45 -0
  40. package/lib/{storefront.js → frontend.js} +10 -6
  41. package/lib/installer.js +150 -49
  42. package/lib/manager.js +65 -26
  43. package/migrations/default-user.sql +2 -1
  44. package/package.json +2 -2
  45. package/templates/.env.dist +11 -11
  46. package/templates/css/styles.css +1 -1
  47. package/templates/index.js.dist +32 -0
  48. package/templates/js/scripts.js +1 -1
package/lib/installer.js CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  const { FileHandler, Encryptor } = require('@reldens/server-utils');
8
8
  const { DriversMap, EntitiesGenerator, PrismaSchemaGenerator } = require('@reldens/storage');
9
+ const { EntitiesLoader } = require('./entities-loader');
10
+ const { AdminEntitiesGenerator } = require('./admin-entities-generator');
9
11
  const { Logger, sc } = require('@reldens/utils');
10
12
  const mustache = require('mustache');
11
13
 
@@ -15,6 +17,7 @@ class Installer
15
17
  constructor(props)
16
18
  {
17
19
  this.app = sc.get(props, 'app', false);
20
+ this.appServer = sc.get(props, 'appServer', false);
18
21
  this.appServerFactory = sc.get(props, 'appServerFactory', false);
19
22
  this.projectRoot = sc.get(props, 'projectRoot', './');
20
23
  this.encoding = sc.get(props, 'encoding', 'utf8');
@@ -24,6 +27,11 @@ class Installer
24
27
  this.installerPath = FileHandler.joinPaths(this.modulePath, 'install');
25
28
  this.migrationsPath = FileHandler.joinPaths(this.modulePath, 'migrations');
26
29
  this.defaultTemplatesPath = FileHandler.joinPaths(this.modulePath, 'templates');
30
+ this.moduleAdminPath = FileHandler.joinPaths(this.modulePath, 'admin');
31
+ this.indexTemplatePath = FileHandler.joinPaths(this.defaultTemplatesPath, 'index.js.dist');
32
+ this.postInstallCallback = sc.get(props, 'postInstallCallback', false);
33
+ this.entitiesLoader = new EntitiesLoader({projectRoot: this.projectRoot});
34
+ this.adminEntitiesGenerator = new AdminEntitiesGenerator();
27
35
  }
28
36
 
29
37
  isInstalled()
@@ -31,7 +39,7 @@ class Installer
31
39
  return FileHandler.exists(this.installLockPath);
32
40
  }
33
41
 
34
- async prepareSetup(app, appServerFactory)
42
+ async prepareSetup(app, appServer, appServerFactory)
35
43
  {
36
44
  if(!app){
37
45
  Logger.error('Missing app on prepareSetup for Installer.');
@@ -43,6 +51,7 @@ class Installer
43
51
  }
44
52
  this.app = app;
45
53
  this.appServerFactory = appServerFactory;
54
+ this.appServer = appServer;
46
55
  app.use('/install-assets', appServerFactory.applicationFramework.static(this.installerPath, {index: false}));
47
56
  app.use(appServerFactory.session({
48
57
  secret: Encryptor.generateSecretKey(),
@@ -63,17 +72,44 @@ class Installer
63
72
  if(this.isInstalled()){
64
73
  return next();
65
74
  }
66
- if('' === req._parsedUrl.pathname || '/' === req._parsedUrl.pathname){
75
+ let urlPath = req._parsedUrl.pathname;
76
+ if('' === urlPath || '/' === urlPath){
67
77
  let installerIndexPath = FileHandler.joinPaths(this.installerPath, 'index.html');
68
78
  if(!FileHandler.exists(installerIndexPath)){
69
79
  return res.status(500).send('Installer template not found.');
70
80
  }
71
81
  let content = FileHandler.readFile(installerIndexPath);
72
- return res.send(mustache.render(content, req.session?.templateVariables || this.fetchDefaults()));
82
+ let contentParams = req.session?.templateVariables || this.fetchDefaults();
83
+ let errorParam = req.query?.error;
84
+ if(errorParam){
85
+ contentParams.errorMessage = this.getErrorMessage(errorParam);
86
+ }
87
+ return res.send(mustache.render(content, contentParams));
88
+ }
89
+ if('/install' !== urlPath){
90
+ return res.redirect('/');
73
91
  }
74
92
  next();
75
93
  }
76
94
 
95
+ getErrorMessage(errorCode)
96
+ {
97
+ let errorMessages = {
98
+ 'invalid-driver': 'Invalid storage driver selected.',
99
+ 'connection-failed': 'Database connection failed. Please check your credentials.',
100
+ 'raw-query-not-found': 'Query method not found in driver.',
101
+ 'sql-file-not-found': 'SQL installation file not found.',
102
+ 'sql-tables-creation-failed': 'Failed to create database tables.',
103
+ 'sql-default-user-error': 'Failed to create default user.',
104
+ 'installation-entities-generation-failed': 'Failed to generate entities.',
105
+ 'installation-process-failed': 'Installation process failed.',
106
+ 'installation-entities-callback-failed': 'Failed to process entities for callback.',
107
+ 'configuration-error': 'Configuration error while completing installation.',
108
+ 'already-installed': 'The application is already installed.'
109
+ };
110
+ return errorMessages[errorCode] || 'An unknown error occurred during installation.';
111
+ }
112
+
77
113
  async executeInstallProcess(req, res)
78
114
  {
79
115
  if(this.isInstalled()){
@@ -117,30 +153,71 @@ class Installer
117
153
  Logger.error('SQL installation file not found.');
118
154
  return res.redirect('/?error=sql-file-not-found');
119
155
  }
120
- await this.executeQueryFile(dbDriver, installSqlPath);
156
+ let queryTablesResult = await this.executeQueryFile(dbDriver, installSqlPath);
157
+ if(!queryTablesResult){
158
+ Logger.error('Tables creation failed.');
159
+ return res.redirect('/?error=sql-tables-creation-failed');
160
+ }
121
161
  Logger.info('Installed tables.');
122
162
  let defaultUserSqlPath = FileHandler.joinPaths(this.migrationsPath, 'default-user.sql');
123
163
  try {
124
164
  if(FileHandler.exists(defaultUserSqlPath)){
125
- await this.executeQueryFile(dbDriver, defaultUserSqlPath);
165
+ let queryUserResult = await this.executeQueryFile(dbDriver, defaultUserSqlPath);
166
+ if(!queryUserResult){
167
+ Logger.error('Default user creation failed.', queryUserResult);
168
+ return res.redirect('/?error=sql-default-user-error');
169
+ }
126
170
  Logger.info('Created default user.');
127
171
  }
128
- await this.generateEntities(dbDriver);
172
+ let entitiesGenerationResult = await this.generateEntities(dbDriver);
173
+ if(!entitiesGenerationResult){
174
+ Logger.error('Entities generation error.');
175
+ return res.redirect('/?error=installation-entities-generation-failed');
176
+ }
129
177
  Logger.info('Generated entities.');
130
178
  } catch (error) {
131
179
  Logger.error('Installation error: '+error.message);
132
180
  return res.redirect('/?error=installation-process-failed');
133
181
  }
134
- if('' === templateVariables['app-admin-path']){
135
- templateVariables['app-admin-path'] = '/reldens-admin';
136
- }
137
182
  try {
138
183
  await this.createEnvFile(templateVariables);
139
- await this.createLockFile();
140
184
  await this.prepareProjectDirectories();
185
+ await this.copyAdminDirectory();
186
+ await this.createIndexJsFile(templateVariables);
187
+ if(sc.isFunction(this.postInstallCallback)){
188
+ let loadedEntities = this.entitiesLoader.loadEntities(selectedDriver);
189
+ if(loadedEntities.rawRegisteredEntities){
190
+ dbDriver.rawEntities = {};
191
+ let entityNames = Object.keys(loadedEntities.rawRegisteredEntities);
192
+ for(let i = 0; i < entityNames.length; i++){
193
+ let entityName = entityNames[i];
194
+ dbDriver.rawEntities[entityName] = loadedEntities.rawRegisteredEntities[entityName];
195
+ }
196
+ await dbDriver.generateEntities();
197
+ let adminEntities = this.adminEntitiesGenerator.generate(
198
+ loadedEntities.rawRegisteredEntities,
199
+ dbDriver.entityManager.entities
200
+ );
201
+ if(this.appServer && sc.isFunction(this.appServer.close)){
202
+ await this.appServer.close();
203
+ }
204
+ Logger.debug('Running postInstallCallback.');
205
+ await this.postInstallCallback({
206
+ entities: adminEntities,
207
+ rawEntities: loadedEntities.rawRegisteredEntities,
208
+ entitiesConfig: loadedEntities.entitiesConfig || {},
209
+ entitiesTranslations: loadedEntities.entitiesTranslations || {}
210
+ });
211
+ }
212
+ }
213
+ await this.createLockFile();
141
214
  Logger.info('Installation successful!');
142
- let adminPath = templateVariables['app-admin-path'];
143
- return res.redirect(adminPath);
215
+ let successContent = 'Installation successful! Run "node ." to start your CMS.';
216
+ let successFileContent = FileHandler.readFile(FileHandler.joinPaths(this.installerPath, 'success.html'));
217
+ if(successFileContent){
218
+ successContent = mustache.render(successFileContent, {adminPath: templateVariables['app-admin-path']});
219
+ }
220
+ return res.send(successContent);
144
221
  } catch (error) {
145
222
  Logger.error('Configuration error: '+error.message);
146
223
  return res.redirect('/?error=configuration-error');
@@ -200,56 +277,80 @@ class Installer
200
277
  dbDriver: templateVariables['db-storage-driver'],
201
278
  adminPath: templateVariables['app-admin-path'],
202
279
  adminSecret: Encryptor.generateSecretKey(),
203
- host: templateVariables['app-host'] || 'http://localhost',
204
- port: templateVariables['app-port'] || '3000'
280
+ host: templateVariables['app-host'],
281
+ port: templateVariables['app-port']
205
282
  });
206
283
  return FileHandler.writeFile(this.envFilePath, envContent);
207
284
  }
208
285
 
286
+ async createIndexJsFile(templateVariables)
287
+ {
288
+ if(!FileHandler.exists(this.indexTemplatePath)){
289
+ Logger.error('Index.js template not found: '+this.indexTemplatePath);
290
+ return false;
291
+ }
292
+ let indexTemplate = FileHandler.readFile(this.indexTemplatePath);
293
+ let driverKey = templateVariables['db-storage-driver'];
294
+ let indexContent = mustache.render(indexTemplate, {driverKey});
295
+ let indexFilePath = FileHandler.joinPaths(this.projectRoot, 'index.js');
296
+ if(FileHandler.exists(indexFilePath)){
297
+ Logger.info('Index.js file already exists, the CMS installer will not override the existent one.');
298
+ return true;
299
+ }
300
+ return FileHandler.writeFile(indexFilePath, indexContent);
301
+ }
302
+
209
303
  async createLockFile()
210
304
  {
211
- return FileHandler.writeFile(this.installLockPath,
212
- 'Installation completed on '+new Date().toISOString());
305
+ return FileHandler.writeFile(this.installLockPath, 'Installation completed on '+new Date().toISOString());
306
+ }
307
+
308
+ async copyAdminDirectory()
309
+ {
310
+ let projectAdminPath = FileHandler.joinPaths(this.projectRoot, 'admin');
311
+ if(FileHandler.exists(projectAdminPath)){
312
+ Logger.info('Admin folder already exists in project root.');
313
+ return true;
314
+ }
315
+ if(!FileHandler.exists(this.moduleAdminPath)){
316
+ Logger.error('Admin folder not found in module path: '+this.moduleAdminPath);
317
+ return false;
318
+ }
319
+ FileHandler.copyFolderSync(this.moduleAdminPath, projectAdminPath);
320
+ Logger.info('Admin folder copied to project root.');
321
+ return true;
213
322
  }
214
323
 
215
324
  async prepareProjectDirectories()
216
325
  {
217
326
  let projectTemplatesPath = FileHandler.joinPaths(this.projectRoot, 'templates');
218
- if(!FileHandler.exists(projectTemplatesPath)){
219
- FileHandler.createFolder(projectTemplatesPath);
220
- }
327
+ FileHandler.createFolder(projectTemplatesPath);
221
328
  let projectPublicPath = FileHandler.joinPaths(this.projectRoot, 'public');
222
- if(!FileHandler.exists(projectPublicPath)){
223
- FileHandler.createFolder(projectPublicPath);
224
- }
329
+ FileHandler.createFolder(projectPublicPath);
225
330
  let projectCssPath = FileHandler.joinPaths(projectPublicPath, 'css');
226
- if(!FileHandler.exists(projectCssPath)){
227
- FileHandler.createFolder(projectCssPath);
228
- }
331
+ FileHandler.createFolder(projectCssPath);
229
332
  let projectJsPath = FileHandler.joinPaths(projectPublicPath, 'js');
230
- if(!FileHandler.exists(projectJsPath)){
231
- FileHandler.createFolder(projectJsPath);
232
- }
233
- let defaultPagePath = FileHandler.joinPaths(this.defaultTemplatesPath, 'page.html');
234
- let defaultNotFoundPath = FileHandler.joinPaths(this.defaultTemplatesPath, '404.html');
235
- let defaultLayoutPath = FileHandler.joinPaths(this.defaultTemplatesPath, 'layout.html');
236
- if(FileHandler.exists(defaultPagePath)){
237
- FileHandler.copyFile(defaultPagePath, FileHandler.joinPaths(projectTemplatesPath, 'page.html'));
238
- }
239
- if(FileHandler.exists(defaultNotFoundPath)){
240
- FileHandler.copyFile(defaultNotFoundPath, FileHandler.joinPaths(projectTemplatesPath, '404.html'));
241
- }
242
- if(FileHandler.exists(defaultLayoutPath)){
243
- FileHandler.copyFile(defaultLayoutPath, FileHandler.joinPaths(projectTemplatesPath, 'layout.html'));
244
- }
245
- let defaultCssPath = FileHandler.joinPaths(this.defaultTemplatesPath, 'css', 'styles.css');
246
- let defaultJsPath = FileHandler.joinPaths(this.defaultTemplatesPath, 'js', 'scripts.js');
247
- if(FileHandler.exists(defaultCssPath)){
248
- FileHandler.copyFile(defaultCssPath, FileHandler.joinPaths(projectCssPath, 'styles.css'));
249
- }
250
- if(FileHandler.exists(defaultJsPath)){
251
- FileHandler.copyFile(defaultJsPath, FileHandler.joinPaths(projectJsPath, 'scripts.js'));
252
- }
333
+ FileHandler.createFolder(projectJsPath);
334
+ FileHandler.copyFile(
335
+ FileHandler.joinPaths(this.defaultTemplatesPath, 'page.html'),
336
+ FileHandler.joinPaths(projectTemplatesPath, 'page.html')
337
+ );
338
+ FileHandler.copyFile(
339
+ FileHandler.joinPaths(this.defaultTemplatesPath, '404.html'),
340
+ FileHandler.joinPaths(projectTemplatesPath, '404.html')
341
+ );
342
+ FileHandler.copyFile(
343
+ FileHandler.joinPaths(this.defaultTemplatesPath, 'layout.html'),
344
+ FileHandler.joinPaths(projectTemplatesPath, 'layout.html')
345
+ );
346
+ FileHandler.copyFile(
347
+ FileHandler.joinPaths(this.defaultTemplatesPath, 'css', 'styles.css'),
348
+ FileHandler.joinPaths(projectCssPath, 'styles.css')
349
+ );
350
+ FileHandler.copyFile(
351
+ FileHandler.joinPaths(this.defaultTemplatesPath, 'js', 'scripts.js'),
352
+ FileHandler.joinPaths(projectJsPath, 'scripts.js')
353
+ );
253
354
  return true;
254
355
  }
255
356
 
@@ -257,7 +358,7 @@ class Installer
257
358
  {
258
359
  return {
259
360
  'app-host': process.env.RELDENS_CMS_HOST || 'http://localhost',
260
- 'app-port': process.env.RELDENS_CMS_PORT || '3000',
361
+ 'app-port': process.env.RELDENS_CMS_PORT || '8000',
261
362
  'app-admin-path': process.env.RELDENS_CMS_ADMIN_PATH || '/reldens-admin',
262
363
  'db-storage-driver': 'prisma',
263
364
  'db-client': process.env.RELDENS_CMS_DB_CLIENT || 'mysql',
package/lib/manager.js CHANGED
@@ -8,13 +8,14 @@ const { AppServerFactory, FileHandler, Encryptor } = require('@reldens/server-ut
8
8
  const { DriversMap } = require('@reldens/storage');
9
9
  const { AdminManager } = require('./admin-manager');
10
10
  const { Installer } = require('./installer');
11
- const { Storefront } = require('./storefront');
12
- const { Logger, sc } = require('@reldens/utils');
11
+ const { Frontend } = require('./frontend');
12
+ const { EventsManagerSingleton, Logger, sc } = require('@reldens/utils');
13
13
  const dotenv = require('dotenv');
14
14
  const mustache = require('mustache');
15
15
 
16
16
  class Manager
17
17
  {
18
+
18
19
  constructor(props = {})
19
20
  {
20
21
  this.projectRoot = sc.get(props, 'projectRoot', './');
@@ -23,34 +24,40 @@ class Manager
23
24
  dotenv.config({path: this.envFilePath});
24
25
  this.config = this.loadConfigFromEnv();
25
26
  this.entities = sc.get(props, 'entities', {});
27
+ this.rawEntities = sc.get(props, 'rawEntities', {});
28
+ this.entitiesConfig = sc.get(props, 'entitiesConfig', {});
29
+ this.entitiesTranslations = sc.get(props, 'entitiesTranslations', {});
26
30
  this.authenticationMethod = sc.get(props, 'authenticationMethod', 'db-users');
27
31
  this.authenticationCallback = sc.get(props, 'authenticationCallback', false);
32
+ this.events = sc.get(props, 'events', EventsManagerSingleton);
28
33
  this.appServerFactory = new AppServerFactory();
29
34
  this.installer = new Installer({
30
- projectRoot: this.projectRoot
35
+ projectRoot: this.projectRoot,
36
+ postInstallCallback: this.initializeCmsAfterInstall.bind(this)
31
37
  });
32
38
  this.dataServer = false;
33
39
  this.app = false;
34
40
  this.appServer = false;
35
41
  this.adminManager = false;
36
- this.storefront = false;
42
+ this.frontend = false;
37
43
  }
38
44
 
39
45
  loadConfigFromEnv()
40
46
  {
47
+ let envVars = process.env;
41
48
  return {
42
- host: process.env.RELDENS_CMS_HOST || 'http://localhost',
43
- port: Number(process.env.RELDENS_CMS_PORT || 3000),
44
- adminPath: process.env.RELDENS_CMS_ADMIN_PATH || '/reldens-admin',
45
- adminSecret: process.env.RELDENS_CMS_ADMIN_SECRET || '',
49
+ host: sc.get(envVars, 'RELDENS_CMS_HOST', 'http://localhost'),
50
+ port: Number(sc.get(envVars, 'RELDENS_CMS_PORT', 8000)),
51
+ adminPath: sc.get(envVars, 'RELDENS_CMS_ADMIN_PATH', '/reldens-admin'),
52
+ adminSecret: sc.get(envVars, 'RELDENS_CMS_ADMIN_SECRET', ''),
46
53
  database: {
47
- client: process.env.RELDENS_CMS_DB_CLIENT || 'mysql',
48
- host: process.env.RELDENS_CMS_DB_HOST || 'localhost',
49
- port: Number(process.env.RELDENS_CMS_DB_PORT || 3306),
50
- name: process.env.RELDENS_CMS_DB_NAME || 'reldens_cms',
51
- user: process.env.RELDENS_CMS_DB_USER || '',
52
- password: process.env.RELDENS_CMS_DB_PASSWORD || '',
53
- driver: process.env.RELDENS_CMS_DB_DRIVER || 'prisma'
54
+ client: sc.get(envVars, 'RELDENS_CMS_DB_CLIENT', 'mysql'),
55
+ host: sc.get(envVars, 'RELDENS_CMS_DB_HOST', 'localhost'),
56
+ port: Number(sc.get(envVars, 'RELDENS_CMS_DB_PORT', 3306)),
57
+ name: sc.get(envVars, 'RELDENS_CMS_DB_NAME', 'reldens_cms'),
58
+ user: sc.get(envVars, 'RELDENS_CMS_DB_USER', ''),
59
+ password: sc.get(envVars, 'RELDENS_CMS_DB_PASSWORD', ''),
60
+ driver: sc.get(envVars, 'RELDENS_CMS_DB_DRIVER', 'prisma')
54
61
  }
55
62
  };
56
63
  }
@@ -71,7 +78,7 @@ class Manager
71
78
  this.appServer = createdAppServer.appServer;
72
79
  if(!this.isInstalled()){
73
80
  Logger.info('CMS not installed, preparing setup');
74
- await this.installer.prepareSetup(this.app, this.appServerFactory);
81
+ await this.installer.prepareSetup(this.app, this.appServer, this.appServerFactory);
75
82
  await this.appServer.listen(this.config.port);
76
83
  Logger.info('Installer running on '+this.config.host+':'+this.config.port);
77
84
  return true;
@@ -79,7 +86,7 @@ class Manager
79
86
  try {
80
87
  await this.initializeDataServer();
81
88
  await this.initializeAdminManager();
82
- await this.initializeStorefront();
89
+ await this.initializeFrontend();
83
90
  await this.appServer.listen(this.config.port);
84
91
  Logger.info('CMS running on '+this.config.host+':'+this.config.port);
85
92
  return true;
@@ -89,6 +96,32 @@ class Manager
89
96
  }
90
97
  }
91
98
 
99
+ async initializeCmsAfterInstall(entitiesData)
100
+ {
101
+ try {
102
+ if(entitiesData){
103
+ this.entities = sc.get(entitiesData, 'entities', this.entities);
104
+ this.rawEntities = sc.get(entitiesData, 'rawEntities', this.rawEntities);
105
+ this.entitiesConfig = sc.get(entitiesData, 'entitiesConfig', this.entitiesConfig);
106
+ this.entitiesTranslations = sc.get(entitiesData, 'entitiesTranslations', this.entitiesTranslations);
107
+ }
108
+ this.config = this.loadConfigFromEnv();
109
+ if(this.appServerFactory.error.message){
110
+ Logger.critical('App server creation failed: '+this.appServerFactory.error.message);
111
+ return false;
112
+ }
113
+ await this.initializeDataServer();
114
+ await this.initializeAdminManager();
115
+ await this.initializeFrontend();
116
+ await this.appServer.listen(this.config.port);
117
+ Logger.info('CMS initialized after installation on '+this.config.host+':'+this.config.port);
118
+ return true;
119
+ } catch (error) {
120
+ Logger.critical('Failed to initialize CMS after installation: '+error.message);
121
+ return false;
122
+ }
123
+ }
124
+
92
125
  async initializeDataServer()
93
126
  {
94
127
  let dbConfig = {
@@ -99,15 +132,18 @@ class Manager
99
132
  database: this.config.database.name,
100
133
  user: this.config.database.user,
101
134
  password: this.config.database.password
102
- }
135
+ },
136
+ rawEntities: this.rawEntities
103
137
  };
104
138
  let DriverClass = DriversMap[this.config.database.driver];
105
139
  if(!DriverClass){
106
- throw new Error('Invalid database driver: '+this.config.database.driver);
140
+ Logger.critical('Invalid database driver: '+this.config.database.driver);
141
+ return false;
107
142
  }
108
143
  this.dataServer = new DriverClass(dbConfig);
109
144
  if(!await this.dataServer.connect()){
110
- throw new Error('Failed to connect to database');
145
+ Logger.critical('Failed to connect to database.');
146
+ return false;
111
147
  }
112
148
  await this.dataServer.generateEntities();
113
149
  return true;
@@ -133,7 +169,7 @@ class Manager
133
169
  };
134
170
  }
135
171
  let adminConfig = {
136
- events: false,
172
+ events: this.events,
137
173
  renderCallback: this.renderCallback.bind(this),
138
174
  dataServer: this.dataServer,
139
175
  authenticationCallback,
@@ -142,7 +178,9 @@ class Manager
142
178
  secret: this.config.adminSecret,
143
179
  rootPath: this.config.adminPath,
144
180
  adminRoleId: 99,
145
- entities: this.entities
181
+ entities: this.entities,
182
+ entitiesConfig: this.entitiesConfig,
183
+ translations: this.entitiesTranslations
146
184
  };
147
185
  this.adminManager = new AdminManager(adminConfig);
148
186
  await this.adminManager.setupAdmin();
@@ -157,14 +195,15 @@ class Manager
157
195
  return mustache.render(template, params);
158
196
  }
159
197
 
160
- async initializeStorefront()
198
+ async initializeFrontend()
161
199
  {
162
- this.storefront = new Storefront({
200
+ this.frontend = new Frontend({
163
201
  app: this.app,
164
202
  dataServer: this.dataServer,
165
- projectRoot: this.projectRoot
203
+ projectRoot: this.projectRoot,
204
+ appServerFactory: this.appServerFactory
166
205
  });
167
- return await this.storefront.initialize();
206
+ return await this.frontend.initialize();
168
207
  }
169
208
  }
170
209
 
@@ -1,8 +1,9 @@
1
1
 
2
2
  -- Default admin user:
3
3
 
4
- INSERT IGNORE INTO `users` (`email`, `username`, `password`, `role_id`, `status`)
4
+ REPLACE INTO `users` (`id`, `email`, `username`, `password`, `role_id`, `status`)
5
5
  VALUES (
6
+ 1,
6
7
  'root@cms-admin.com',
7
8
  'root',
8
9
  'd35ed1c81c3ff00de15309fe40a90c32:a39a9231a69fefef274c13c1780a7447672a5fee8250ce22a51bb20275039dda63a54faa1e5fd775becb3ac424f571d5b996001305bb7d63e038111dce08d45b',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@reldens/cms",
3
3
  "scope": "@reldens",
4
- "version": "0.4.0",
4
+ "version": "0.6.0",
5
5
  "description": "Reldens - CMS",
6
6
  "author": "Damian A. Pastorini",
7
7
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@reldens/server-utils": "^0.16.0",
36
- "@reldens/storage": "^0.37.0",
36
+ "@reldens/storage": "^0.43.0",
37
37
  "@reldens/utils": "^0.47.0",
38
38
  "dotenv": "^16.5.0",
39
39
  "mustache": "^4.2.0"
@@ -1,16 +1,16 @@
1
1
  # Database Configuration
2
- RELDENS_CMS_DB_CLIENT={{dbClient}}
3
- RELDENS_CMS_DB_HOST={{dbHost}}
4
- RELDENS_CMS_DB_PORT={{dbPort}}
5
- RELDENS_CMS_DB_NAME={{dbName}}
6
- RELDENS_CMS_DB_USER={{dbUser}}
7
- RELDENS_CMS_DB_PASSWORD={{dbPassword}}
8
- RELDENS_CMS_DB_DRIVER={{dbDriver}}
2
+ RELDENS_CMS_DB_CLIENT={{&dbClient}}
3
+ RELDENS_CMS_DB_HOST={{&dbHost}}
4
+ RELDENS_CMS_DB_PORT={{&dbPort}}
5
+ RELDENS_CMS_DB_NAME={{&dbName}}
6
+ RELDENS_CMS_DB_USER={{&dbUser}}
7
+ RELDENS_CMS_DB_PASSWORD={{&dbPassword}}
8
+ RELDENS_CMS_DB_DRIVER={{&dbDriver}}
9
9
 
10
10
  # Admin Panel Configuration
11
- RELDENS_CMS_ADMIN_PATH={{adminPath}}
12
- RELDENS_CMS_ADMIN_SECRET={{adminSecret}}
11
+ RELDENS_CMS_ADMIN_PATH={{&adminPath}}
12
+ RELDENS_CMS_ADMIN_SECRET={{&adminSecret}}
13
13
 
14
14
  # Server Configuration
15
- RELDENS_CMS_HOST={{host}}
16
- RELDENS_CMS_PORT={{port}}
15
+ RELDENS_CMS_HOST={{&host}}
16
+ RELDENS_CMS_PORT={{&port}}
@@ -1,4 +1,4 @@
1
- /* Storefront styles */
1
+ /* Frontend styles */
2
2
  body {
3
3
  font-family: 'Open Sans', sans-serif;
4
4
  line-height: 1.6;
@@ -0,0 +1,32 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS
4
+ *
5
+ */
6
+
7
+ const { Manager } = require('@reldens/cms');
8
+ const { Logger } = require('@reldens/utils');
9
+ const { rawRegisteredEntities, entitiesConfig, entitiesTranslations } = require('./generated-entities/models/{{driverKey}}/registered-models-{{driverKey}}');
10
+
11
+ let args = process.argv.slice(2);
12
+ let projectRoot = args[0] || process.cwd();
13
+
14
+ let manager = new Manager({
15
+ projectRoot,
16
+ entities: rawRegisteredEntities,
17
+ entitiesConfig,
18
+ entitiesTranslations
19
+ });
20
+ Logger.debug('Reldens CMS Manager instance created.', {configuration: manager.config});
21
+
22
+ manager.start().then((result) => {
23
+ if(!result){
24
+ Logger.info('Reldens CMS started by command failed.');
25
+ return false;
26
+ }
27
+ Logger.info('Reldens CMS started by command.');
28
+ return true;
29
+ }).catch((error) => {
30
+ Logger.error('Failed to start CMS: '+error.message);
31
+ process.exit();
32
+ });
@@ -1,4 +1,4 @@
1
- // Storefront JavaScript
1
+ // Frontend JavaScript
2
2
  document.addEventListener('DOMContentLoaded', function() {
3
3
  // Add active class to current navigation item
4
4
  const currentPath = window.location.pathname;