@reldens/cms 0.5.0 → 0.7.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 (55) 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/pagination-link.html +1 -0
  28. package/admin/templates/sidebar-header.html +4 -0
  29. package/admin/templates/sidebar-item.html +3 -0
  30. package/admin/templates/sidebar.html +11 -0
  31. package/admin/templates/view.html +23 -0
  32. package/bin/reldens-cms.js +20 -8
  33. package/index.js +2 -2
  34. package/install/index.html +0 -7
  35. package/install/success.html +30 -0
  36. package/lib/admin-manager.js +1 -1
  37. package/lib/admin-templates-loader.js +37 -0
  38. package/lib/admin-translations.js +4 -218
  39. package/lib/allowed-extensions.js +11 -0
  40. package/lib/entities-loader.js +42 -0
  41. package/lib/{storefront.js → frontend.js} +14 -19
  42. package/lib/installer.js +137 -52
  43. package/lib/loaded-entities-processor.js +30 -0
  44. package/lib/manager.js +135 -37
  45. package/lib/mime-types.js +35 -0
  46. package/lib/templates-list.js +0 -9
  47. package/lib/templates-to-path-mapper.js +28 -0
  48. package/migrations/default-user.sql +2 -1
  49. package/package.json +2 -2
  50. package/templates/.env.dist +11 -11
  51. package/templates/assets/web/loading.gif +0 -0
  52. package/templates/assets/web/reldens-your-logo-mage.png +0 -0
  53. package/templates/css/styles.css +1 -1
  54. package/templates/index.js.dist +32 -0
  55. package/templates/js/scripts.js +1 -1
package/index.js CHANGED
@@ -6,10 +6,10 @@
6
6
 
7
7
  const { Manager } = require('./lib/manager');
8
8
  const { Installer } = require('./lib/installer');
9
- const { Storefront } = require('./lib/storefront');
9
+ const { Frontend } = require('./lib/frontend');
10
10
 
11
11
  module.exports = {
12
12
  Manager,
13
13
  Installer,
14
- Storefront
14
+ Frontend
15
15
  };
@@ -34,13 +34,6 @@
34
34
  <p class="error installation-process-failed">There was an error during the installation process.</p>
35
35
  </div>
36
36
  <h3 class="form-title">- Database Configuration -</h3>
37
- <div class="db-basic-config-notice">
38
- <span>Default configuration:</span>
39
- <ul>
40
- <li>Client: mysql - Port: 3306</li>
41
- <li>Database Driver: prisma</li>
42
- </ul>
43
- </div>
44
37
  <div class="input-box db-storage-driver">
45
38
  <label for="db-storage-driver">Storage Driver</label>
46
39
  <select name="db-storage-driver" id="db-storage-driver" class="required" required>
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Reldens CMS - Installation</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
6
+ <link rel="stylesheet" href="/install-assets/css/installer.css">
7
+ <script src="/install-assets/js/installer.js"></script>
8
+ </head>
9
+ <body>
10
+ <div class="wrapper">
11
+ <div class="header">
12
+ <h1 class="title">
13
+ <strong>Reldens CMS</strong> - Installation
14
+ </h1>
15
+ </div>
16
+ <div class="content">
17
+ <div class="forms-container">
18
+ <div class="row">
19
+ Installation completed!
20
+ </div>
21
+ </div>
22
+ </div>
23
+ <div class="footer">
24
+ <div class="copyright">
25
+ &copy; 2025 Reldens CMS
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </body>
30
+ </html>
@@ -54,7 +54,7 @@ class AdminManager
54
54
 
55
55
  async setupAdmin()
56
56
  {
57
- if (this.validator instanceof ValidatorInterface && !this.validator.validate(this)){
57
+ if(this.validator instanceof ValidatorInterface && !this.validator.validate(this)){
58
58
  return false;
59
59
  }
60
60
  this.resourcesByReference = {};
@@ -0,0 +1,37 @@
1
+ /**
2
+ *
3
+ * Reldens - AdminTemplatesLoader
4
+ *
5
+ */
6
+
7
+ const { Logger, sc } = require('@reldens/utils');
8
+ const { FileHandler } = require('@reldens/server-utils');
9
+
10
+ class AdminTemplatesLoader
11
+ {
12
+
13
+ async fetchAdminFilesContents(adminTemplates)
14
+ {
15
+ let adminFilesContents = {};
16
+ for(let template of Object.keys(adminTemplates)){
17
+ let templateData = adminTemplates[template];
18
+ if(sc.isObject(templateData)){
19
+ let subFoldersContents = await this.fetchAdminFilesContents(templateData);
20
+ if(!subFoldersContents){
21
+ return false;
22
+ }
23
+ adminFilesContents[template] = subFoldersContents;
24
+ continue;
25
+ }
26
+ if(!FileHandler.isFile(templateData)){
27
+ Logger.critical('Admin template file not found.', template);
28
+ return false;
29
+ }
30
+ adminFilesContents[template] = await FileHandler.fetchFileContents(templateData);
31
+ }
32
+ return adminFilesContents;
33
+ }
34
+
35
+ }
36
+
37
+ module.exports.AdminTemplatesLoader = new AdminTemplatesLoader();
@@ -12,8 +12,8 @@ class AdminTranslations
12
12
  // @TODO - BETA - Fix translations, use snippets, include new snippets under the basic config script.
13
13
  let adminTranslations = {
14
14
  messages: {
15
- loginWelcome: 'Administration Panel - Login',
16
- reldensTitle: 'Reldens - Administration Panel',
15
+ loginWelcome: 'CMS - Login',
16
+ reldensTitle: 'Reldens - CMS',
17
17
  reldensSlogan: 'You can do it',
18
18
  reldensDiscordTitle: 'Join our Discord server!',
19
19
  reldensDiscordText: 'Talk with the creators and other Reldens users',
@@ -24,229 +24,15 @@ class AdminTranslations
24
24
  reldensLoading: 'Loading...'
25
25
  },
26
26
  labels: {
27
- navigation: 'Reldens - Administration Panel',
27
+ navigation: 'Reldens - CMS',
28
28
  adminVersion: 'Admin: {{version}}',
29
29
  loginWelcome: 'Reldens',
30
30
  pages: 'Server Management',
31
31
  management: 'Management',
32
- mapsWizard: 'Maps Generation and Import',
33
- objectsImport: 'Objects Import',
34
- skillsImport: 'Skills Import',
35
32
  shuttingDown: 'Server is shutting down in:',
36
33
  submitShutdownLabel: 'Shutdown Server',
37
34
  submitCancelLabel: 'Cancel Server Shutdown',
38
- },
39
- active_from: 'Active From',
40
- active_to: 'Active To',
41
- ads_id: 'Ads ID',
42
- ads_type: 'Ads Type',
43
- affectedProperty: 'Affected Property',
44
- aimProperties: 'Aim Properties',
45
- allowEffectBelowZero: 'Allow Effect Below Zero',
46
- allowSelfTarget: 'Allow Self Target',
47
- also_show_in_type: 'Also Show In Type',
48
- animationData: 'Animation Data',
49
- animationKey: 'Animation Key',
50
- applyDirectDamage: 'Apply Direct Damage',
51
- asset_file: 'Asset File',
52
- asset_key: 'Asset Key',
53
- asset_type: 'Asset Type',
54
- attackProperties: 'Attack Properties',
55
- audio_id: 'Audio ID',
56
- audio_key: 'Audio Key',
57
- autoFillExperienceMultiplier: 'Auto Fill Experience Multiplier',
58
- autoFillRanges: 'Auto Fill Ranges',
59
- autoValidation: 'Auto Validation',
60
- auto_remove_requirement: 'Auto Remove Requirement',
61
- banner_data: 'Banner Data',
62
- base_value: 'Base Value',
63
- bottom: 'Bottom',
64
- castTime: 'Cast Time',
65
- category_id: 'Category ID',
66
- category_key: 'Category Key',
67
- category_label: 'Category Label',
68
- chat_player_id: 'Chat Player ID',
69
- chat_private_player_id: 'Chat Private Player',
70
- chat_room: 'Chat Room',
71
- chat_type: 'Chat Type',
72
- clan_id: 'Clan ID',
73
- classKey: 'Class Key',
74
- class_path: 'Class Path',
75
- class_path_id: 'Class Path ID',
76
- class_path_level: 'Level Key',
77
- class_path_level_skill: 'Skill',
78
- class_path_owner: 'Class Path Owner',
79
- class_type: 'Class Type',
80
- client_key: 'Client Key',
81
- client_params: 'Client Params',
82
- code: 'Code',
83
- conditional: 'Conditional',
84
- config: 'Config',
85
- country_code: 'Country Code',
86
- created_at: 'Created At',
87
- criticalAffected: 'Critical Affected',
88
- criticalChance: 'Critical Chance',
89
- criticalFixedValue: 'Critical FixedValue',
90
- criticalMultiplier: 'Critical Multiplier',
91
- currentExp: 'Current Exp',
92
- currentLevel: 'Current Level',
93
- customData: 'Custom Data',
94
- damageAffected: 'Damage Affected',
95
- defenseProperties: 'Defense Properties',
96
- description: 'Description',
97
- dir: 'Dir',
98
- direction: 'Direction',
99
- drop_quantity: 'Drop Quantity',
100
- drop_rate: 'Drop Rate',
101
- dodgeFullEnabled: 'Dodge Full Enabled',
102
- dodgeOverAimSuccess: 'Dodge Over Aim Success',
103
- dodgeProperties: 'Dodge Properties',
104
- duration: 'Duration',
105
- email: 'Email',
106
- enabled: 'Enabled',
107
- ended_at: 'Ended At',
108
- event_data: 'Event Data',
109
- event_key: 'Event Key',
110
- experience: 'Experience',
111
- execTimeOut: 'Exec Time Out',
112
- extra_params: 'Extra Params',
113
- file: 'File',
114
- files_name: 'Files Name',
115
- from_room_id: 'From Room ID',
116
- group_id: 'Group ID',
117
- handler_key: 'Handler Key',
118
- has_drop_body: 'Has Drop Body',
119
- height: 'Height',
120
- hitDamage: 'Hit Damage',
121
- id: 'ID',
122
- instances_limit: 'Instances Limit',
123
- is_active: 'Is Active',
124
- is_default: 'Is Default',
125
- is_enabled: 'Is Enabled',
126
- is_unique: 'Is Unique',
127
- item_id: 'Item ID',
128
- item_key: 'Item Key',
129
- items_limit: 'Items Limit',
130
- key: 'Key',
131
- kill_npc_id: 'Kill NPC ID',
132
- kill_player_id: 'Kill Player ID',
133
- kill_time: 'Kill Time',
134
- label: 'Label',
135
- label_level: 'Label Level',
136
- language_code: 'Language Code',
137
- last_npc_kill_time: 'Last NPC Kill Time',
138
- last_player_kill_time: 'Last Player Kill Time',
139
- layer: 'Layer',
140
- layer_name: 'Layer Name',
141
- level: 'Level',
142
- level_id: 'Level ID',
143
- level_owner: 'Level Owner',
144
- level_set: 'Level Set',
145
- level_set_id: 'Level Set ID',
146
- levels_set_id: 'Levels Set ID',
147
- limit_per_item: 'Limit Per Item',
148
- locale: 'Locale',
149
- locale_id: 'Locale ID',
150
- login_count: 'Login Count',
151
- login_date: 'Login Date',
152
- logout_date: 'Logout Date',
153
- map_filename: 'Map Filename',
154
- marker_key: 'Marker Key',
155
- maxProperty: 'Max Property',
156
- maxValue: 'Max Value',
157
- message: 'Message',
158
- message_time: 'Message Time',
159
- message_type: 'Message Type',
160
- magnitude: 'Magnitude',
161
- minProperty: 'Min Property',
162
- minValue: 'Min Value',
163
- modifier_id: 'Modifier ID',
164
- name: 'Name',
165
- next_room_id: 'Next Room ID',
166
- npcs_kills_count: 'NPCs Kills Count',
167
- objectHeight: 'Object Height',
168
- objectWidth: 'Object Width',
169
- object_asset_id: 'Object Asset ID',
170
- object_class_key: 'Object Class Key',
171
- object_id: 'Object ID',
172
- obtained_score: 'Obtained Score',
173
- operation: 'Operation',
174
- owner_id: 'Owner ID',
175
- parent_group: 'Parent Group',
176
- parent_skill: 'Parent Skill',
177
- path: 'Path',
178
- password: 'Password',
179
- player_id: 'Player ID',
180
- played_time: 'Played Time',
181
- players_kill_count: 'Players Kills Count',
182
- players_kills_count: 'Players Kills Count',
183
- points: 'Points',
184
- position: 'Position',
185
- position_bottom: 'Position Bottom',
186
- position_left: 'Position Left',
187
- position_right: 'Position Right',
188
- position_top: 'Position Top',
189
- private_params: 'Private Params',
190
- private_player_id: 'Private Player ID',
191
- property_key: 'Property Key',
192
- provider_id: 'Provider ID',
193
- qty: 'Qty',
194
- qty_limit: 'Qty Limit',
195
- range: 'Range',
196
- rangeAutomaticValidation: 'Range Automatic Validation',
197
- rangePropertyX: 'Range Property X',
198
- rangePropertyY: 'Range Property Y',
199
- rangeTargetPropertyX: 'Range Target Property X',
200
- rangeTargetPropertyY: 'Range Target Property Y',
201
- remaining_uses: 'Remaining Uses',
202
- required_experience: 'Required Experience',
203
- required_item_key: 'Required Item Key',
204
- required_quantity: 'Required Quantity',
205
- respawn_time: 'Respawn Time',
206
- replay: 'Replay',
207
- reward_item_is_required: 'Reward Item Is Required',
208
- reward_item_key: 'Reward Item Key',
209
- reward_quantity: 'Reward Quantity',
210
- rewards_events_id: 'Rewards Events ID',
211
- role_id: 'Role ID',
212
- room_class_key: 'Room Class Key',
213
- room_id: 'Room ID',
214
- scene_images: 'Scene Images',
215
- scope: 'Scope',
216
- server_url: 'Server URL',
217
- show_in_general: 'Show In General',
218
- show_tab: 'Show Tab',
219
- single_audio: 'Single Audio',
220
- skill: 'Skill',
221
- skillDelay: 'Skill Delay',
222
- skill_id: 'Skill ID',
223
- sort: 'Sort',
224
- start: 'Start',
225
- started_at: 'Started At',
226
- state: 'State',
227
- stat_id: 'Stat ID',
228
- status: 'Status',
229
- target_id: 'Target ID',
230
- target_key: 'Target Key',
231
- target_label: 'Target Label',
232
- tile_index: 'Tile Index',
233
- title: 'Title',
234
- top: 'Top',
235
- total_score: 'Total Score',
236
- type: 'Type',
237
- type_id: 'Type ID',
238
- updated_at: 'Updated At',
239
- useTimeOut: 'Use Time Out',
240
- user_id: 'User ID',
241
- username: 'Username',
242
- usesLimit: 'Uses Limit',
243
- uses_limit: 'Uses Limit',
244
- validateTargetOnHit: 'Validate Target On Hit',
245
- value: 'Value',
246
- was_given: 'Was Given',
247
- width: 'Width',
248
- x: 'X',
249
- y: 'Y'
35
+ }
250
36
  };
251
37
  for(let i of Object.keys(translations)){
252
38
  if(!adminTranslations[i]){
@@ -0,0 +1,11 @@
1
+ /**
2
+ *
3
+ * Reldens - AllowedExtensions
4
+ *
5
+ */
6
+
7
+ module.exports.AllowedExtensions = {
8
+ audio: ['.aac', '.mid', '.midi', '.mp3', '.ogg', '.oga', '.opus', '.wav', '.weba', '.3g2'],
9
+ image: ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp'],
10
+ text: ['.json', '.jsonld', '.txt']
11
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ *
3
+ * Reldens - EntitiesLoader
4
+ *
5
+ */
6
+
7
+ const { LoadedEntitiesProcessor } = require('./loaded-entities-processor');
8
+ const { FileHandler } = require('@reldens/server-utils');
9
+ const { Logger, sc } = require('@reldens/utils');
10
+
11
+ class EntitiesLoader
12
+ {
13
+
14
+ constructor(props)
15
+ {
16
+ this.projectRoot = sc.get(props, 'projectRoot', './');
17
+ this.generatedEntitiesModelsFolder = FileHandler.joinPaths(this.projectRoot, 'generated-entities', 'models');
18
+ }
19
+
20
+ loadEntities(driverKey)
21
+ {
22
+ let entitiesPath = FileHandler.joinPaths(
23
+ this.generatedEntitiesModelsFolder,
24
+ driverKey,
25
+ 'registered-models-'+driverKey+'.js'
26
+ );
27
+ if(!FileHandler.exists(entitiesPath)){
28
+ Logger.warning('Entities file not found: ' + entitiesPath);
29
+ return {};
30
+ }
31
+ try {
32
+ let {rawRegisteredEntities, entitiesConfig, entitiesTranslations} = require(entitiesPath);
33
+ return LoadedEntitiesProcessor.process(rawRegisteredEntities, entitiesTranslations, entitiesConfig);
34
+ } catch(error){
35
+ Logger.error('Failed to load generated entities: ' + error.message);
36
+ }
37
+ return {};
38
+ }
39
+
40
+ }
41
+
42
+ module.exports.EntitiesLoader = EntitiesLoader;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  *
3
- * Reldens - CMS - Storefront
3
+ * Reldens - CMS - Frontend
4
4
  *
5
5
  */
6
6
 
@@ -8,17 +8,17 @@ const { FileHandler } = require('@reldens/server-utils');
8
8
  const { Logger, sc } = require('@reldens/utils');
9
9
  const mustache = require('mustache');
10
10
 
11
- class Storefront
11
+ class Frontend
12
12
  {
13
13
 
14
14
  constructor(props)
15
15
  {
16
16
  this.app = sc.get(props, 'app', false);
17
+ this.appServerFactory = sc.get(props, 'appServerFactory', false);
17
18
  this.dataServer = sc.get(props, 'dataServer', false);
18
19
  this.projectRoot = sc.get(props, 'projectRoot', './');
19
20
  this.templatesPath = FileHandler.joinPaths(this.projectRoot, 'templates');
20
21
  this.publicPath = FileHandler.joinPaths(this.projectRoot, 'public');
21
- this.encoding = sc.get(props, 'encoding', 'utf8');
22
22
  this.error = false;
23
23
  }
24
24
 
@@ -45,11 +45,14 @@ class Storefront
45
45
 
46
46
  setupStaticAssets()
47
47
  {
48
- if(!this.app || !this.publicPath){
48
+ if(!this.app || !this.appServerFactory || !this.publicPath){
49
49
  return false;
50
50
  }
51
- this.app.use(this.app._router.constructor.static(this.publicPath));
52
- return true;
51
+ if(this.appServerFactory && this.appServerFactory.applicationFramework){
52
+ this.app.use(this.appServerFactory.applicationFramework.static(this.publicPath));
53
+ return true;
54
+ }
55
+ return false;
53
56
  }
54
57
 
55
58
  async handleRequest(req, res)
@@ -160,9 +163,7 @@ class Storefront
160
163
  return await this.renderNotFoundPage(res);
161
164
  }
162
165
  }
163
- let template = FileHandler.readFile(templatePath, {
164
- encoding: this.encoding
165
- }).toString();
166
+ let template = FileHandler.readFile(templatePath).toString();
166
167
  let data = {
167
168
  ...route,
168
169
  ...content,
@@ -181,9 +182,7 @@ class Storefront
181
182
  return await this.renderNotFoundPage(res);
182
183
  }
183
184
  }
184
- let template = FileHandler.readFile(templatePath, {
185
- encoding: this.encoding
186
- }).toString();
185
+ let template = FileHandler.readFile(templatePath).toString();
187
186
  let data = {
188
187
  ...entity,
189
188
  title: entity.title || entity.name || entityName,
@@ -195,9 +194,7 @@ class Storefront
195
194
 
196
195
  async renderTemplateOnly(res, templatePath)
197
196
  {
198
- let template = FileHandler.readFile(templatePath, {
199
- encoding: this.encoding
200
- }).toString();
197
+ let template = FileHandler.readFile(templatePath).toString();
201
198
  let data = {
202
199
  title: 'Page Title',
203
200
  current_year: new Date().getFullYear()
@@ -212,9 +209,7 @@ class Storefront
212
209
  if(!FileHandler.exists(templatePath)){
213
210
  return res.status(404).send('Page not found');
214
211
  }
215
- let template = FileHandler.readFile(templatePath, {
216
- encoding: this.encoding
217
- }).toString();
212
+ let template = FileHandler.readFile(templatePath).toString();
218
213
  let data = {
219
214
  title: '404 - Page Not Found',
220
215
  current_year: new Date().getFullYear()
@@ -225,4 +220,4 @@ class Storefront
225
220
 
226
221
  }
227
222
 
228
- module.exports.Storefront = Storefront;
223
+ module.exports.Frontend = Frontend;