@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.
- package/README.md +1 -1
- package/admin/assets/admin/filters.png +0 -0
- package/admin/assets/admin/list.png +0 -0
- package/admin/reldens-admin-client.css +830 -0
- package/admin/reldens-admin-client.js +272 -0
- package/admin/templates/dashboard.html +1 -0
- package/admin/templates/default-copyright.html +5 -0
- package/admin/templates/edit.html +25 -0
- package/admin/templates/fields/edit/button.html +3 -0
- package/admin/templates/fields/edit/checkbox.html +1 -0
- package/admin/templates/fields/edit/file.html +2 -0
- package/admin/templates/fields/edit/radio.html +1 -0
- package/admin/templates/fields/edit/select.html +5 -0
- package/admin/templates/fields/edit/text.html +1 -0
- package/admin/templates/fields/edit/textarea.html +1 -0
- package/admin/templates/fields/view/boolean.html +1 -0
- package/admin/templates/fields/view/image.html +4 -0
- package/admin/templates/fields/view/images.html +7 -0
- package/admin/templates/fields/view/link.html +1 -0
- package/admin/templates/fields/view/links.html +6 -0
- package/admin/templates/fields/view/text.html +1 -0
- package/admin/templates/layout.html +37 -0
- package/admin/templates/list-content.html +70 -0
- package/admin/templates/list.html +35 -0
- package/admin/templates/login.html +19 -0
- package/admin/templates/management.html +22 -0
- package/admin/templates/maps-wizard-maps-selection.html +85 -0
- package/admin/templates/maps-wizard.html +341 -0
- package/admin/templates/objects-import.html +143 -0
- package/admin/templates/pagination-link.html +1 -0
- package/admin/templates/sidebar-header.html +4 -0
- package/admin/templates/sidebar-item.html +3 -0
- package/admin/templates/sidebar.html +11 -0
- package/admin/templates/skills-import.html +201 -0
- package/admin/templates/view.html +23 -0
- package/bin/reldens-cms.js +19 -7
- package/index.js +2 -2
- package/install/index.html +5 -7
- package/lib/entities-loader.js +45 -0
- package/lib/{storefront.js → frontend.js} +10 -6
- package/lib/installer.js +150 -49
- package/lib/manager.js +65 -26
- package/migrations/default-user.sql +2 -1
- package/package.json +2 -2
- package/templates/.env.dist +11 -11
- package/templates/css/styles.css +1 -1
- package/templates/index.js.dist +32 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
|
143
|
-
|
|
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']
|
|
204
|
-
port: templateVariables['app-port']
|
|
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
|
-
|
|
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
|
-
|
|
219
|
-
FileHandler.createFolder(projectTemplatesPath);
|
|
220
|
-
}
|
|
327
|
+
FileHandler.createFolder(projectTemplatesPath);
|
|
221
328
|
let projectPublicPath = FileHandler.joinPaths(this.projectRoot, 'public');
|
|
222
|
-
|
|
223
|
-
FileHandler.createFolder(projectPublicPath);
|
|
224
|
-
}
|
|
329
|
+
FileHandler.createFolder(projectPublicPath);
|
|
225
330
|
let projectCssPath = FileHandler.joinPaths(projectPublicPath, 'css');
|
|
226
|
-
|
|
227
|
-
FileHandler.createFolder(projectCssPath);
|
|
228
|
-
}
|
|
331
|
+
FileHandler.createFolder(projectCssPath);
|
|
229
332
|
let projectJsPath = FileHandler.joinPaths(projectPublicPath, 'js');
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
FileHandler.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
FileHandler.
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
FileHandler.
|
|
249
|
-
|
|
250
|
-
|
|
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 || '
|
|
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 {
|
|
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.
|
|
42
|
+
this.frontend = false;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
loadConfigFromEnv()
|
|
40
46
|
{
|
|
47
|
+
let envVars = process.env;
|
|
41
48
|
return {
|
|
42
|
-
host:
|
|
43
|
-
port: Number(
|
|
44
|
-
adminPath:
|
|
45
|
-
adminSecret:
|
|
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:
|
|
48
|
-
host:
|
|
49
|
-
port: Number(
|
|
50
|
-
name:
|
|
51
|
-
user:
|
|
52
|
-
password:
|
|
53
|
-
driver:
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
|
198
|
+
async initializeFrontend()
|
|
161
199
|
{
|
|
162
|
-
this.
|
|
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.
|
|
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
|
-
|
|
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
|
+
"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.
|
|
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"
|
package/templates/.env.dist
CHANGED
|
@@ -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}}
|
package/templates/css/styles.css
CHANGED
|
@@ -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
|
+
});
|
package/templates/js/scripts.js
CHANGED