mastercontroller 1.2.12 → 1.2.14

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,12 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(rm:*)",
5
+ "Bash(mv:*)",
6
+ "Bash(node -e:*)",
7
+ "Bash(find:*)"
8
+ ],
9
+ "deny": [],
10
+ "ask": []
11
+ }
12
+ }
package/MasterAction.js CHANGED
@@ -1,19 +1,47 @@
1
1
 
2
- // version 0.0.22
2
+ // version 0.0.23
3
3
 
4
4
  var master = require('./MasterControl');
5
5
  var fileserver = require('fs');
6
6
  var toolClass = require('./MasterTools');
7
7
  var tempClass = require('./MasterTemplate');
8
+ // Templating helpers
8
9
  var temp = new tempClass();
9
10
  var tools = new toolClass();
10
11
 
12
+ // Node utils
13
+ var path = require('path');
14
+
15
+ // Vanilla Web Components SSR runtime (LinkeDOM) - executes connectedCallback() and upgrades
16
+ const compileWebComponentsHTML = require('./ssr/runtime-ssr.cjs');
17
+
18
+ // Enhanced error handling
19
+ const { handleTemplateError, sendErrorResponse } = require('./error/MasterBackendErrorHandler');
20
+ const { safeReadFile } = require('./error/MasterErrorMiddleware');
21
+ const { logger } = require('./error/MasterErrorLogger');
22
+
23
+ // Security - CSRF, validation, sanitization
24
+ const { generateCSRFToken, validateCSRFToken } = require('./security/SecurityMiddleware');
25
+ const { validator, validateRequestBody, sanitizeObject } = require('./security/MasterValidator');
26
+ const { sanitizeUserHTML, escapeHTML } = require('./security/MasterSanitizer');
27
+
11
28
  class MasterAction{
12
29
 
13
30
  getView(location, data){
14
31
  var actionUrl = master.root + location;
15
- var actionView = fileserver.readFileSync(actionUrl, 'utf8');
16
- return temp.htmlBuilder(actionView, data);
32
+ const fileResult = safeReadFile(fileserver, actionUrl);
33
+
34
+ if (!fileResult.success) {
35
+ const error = handleTemplateError(fileResult.error.originalError, actionUrl, data);
36
+ throw error;
37
+ }
38
+
39
+ try {
40
+ return temp.htmlBuilder(fileResult.content, data);
41
+ } catch (error) {
42
+ const mcError = handleTemplateError(error, actionUrl, data);
43
+ throw mcError;
44
+ }
17
45
  }
18
46
 
19
47
 
@@ -110,6 +138,16 @@ class MasterAction{
110
138
  this.params = tools.combineObjects(data, this.params);
111
139
  var func = master.viewList;
112
140
  this.params = tools.combineObjects(this.params, func);
141
+ // Prefer page.js module if present (no legacy .html file)
142
+ try {
143
+ const controller = this.__currentRoute.toController;
144
+ const action = this.__currentRoute.toAction;
145
+ const pageModuleAbs = path.join(master.root, 'app/views', controller, action, 'page.js');
146
+ if (fileserver.existsSync(pageModuleAbs)) {
147
+ if (this._renderPageModule(controller, action, data)) { return; }
148
+ }
149
+ } catch (_) {}
150
+
113
151
  var actionUrl = (location === undefined) ? this.__currentRoute.root + "/app/views/" + this.__currentRoute.toController + "/" + this.__currentRoute.toAction + ".html" : master.root + location;
114
152
  var actionView = fileserver.readFileSync(actionUrl, 'utf8');
115
153
  if(master.overwrite.isTemplate){
@@ -119,8 +157,21 @@ class MasterAction{
119
157
  masterView = temp.htmlBuilder(actionView, data);
120
158
  }
121
159
  if (!this.__requestObject.response._headerSent) {
122
- this.__requestObject.response.writeHead(200, {'Content-Type': 'text/html'});
123
- this.__requestObject.response.end(masterView);
160
+ const send = (htmlOut) => {
161
+ try {
162
+ this.__requestObject.response.writeHead(200, {'Content-Type': 'text/html'});
163
+ this.__requestObject.response.end(htmlOut);
164
+ } catch (e) {
165
+ // Fallback in case of double send
166
+ }
167
+ };
168
+ try {
169
+ Promise.resolve(compileWebComponentsHTML(masterView))
170
+ .then(send)
171
+ .catch(() => send(masterView));
172
+ } catch (_) {
173
+ send(masterView);
174
+ }
124
175
  }
125
176
  }
126
177
 
@@ -133,6 +184,18 @@ class MasterAction{
133
184
  }
134
185
  }
135
186
 
187
+ returnReact(data, location){
188
+
189
+ var masterView = null;
190
+ data = data === undefined ? {} : data;
191
+ this.params = this.params === undefined ? {} : this.params;
192
+ this.params = tools.combineObjects(data, this.params);
193
+ var func = master.viewList;
194
+ this.params = tools.combineObjects(this.params, func);
195
+ var html = master.reactView.compile(this.__currentRoute.toController, this.__currentRoute.toAction, this.__currentRoute.root);
196
+
197
+ }
198
+
136
199
  returnView(data, location){
137
200
 
138
201
  var masterView = null;
@@ -141,6 +204,16 @@ class MasterAction{
141
204
  this.params = tools.combineObjects(data, this.params);
142
205
  var func = master.viewList;
143
206
  this.params = tools.combineObjects(this.params, func);
207
+ // Prefer page.js module if present (no legacy .html file)
208
+ try {
209
+ const controller = this.__currentRoute.toController;
210
+ const action = this.__currentRoute.toAction;
211
+ const pageModuleAbs = path.join(master.root, 'app/views', controller, action, 'page.js');
212
+ if (fileserver.existsSync(pageModuleAbs)) {
213
+ if (this._renderPageModule(controller, action, data)) { return; }
214
+ }
215
+ } catch (_) {}
216
+
144
217
  var viewUrl = (location === undefined || location === "" || location === null) ? this.__currentRoute.root + "/app/views/" + this.__currentRoute.toController + "/" + this.__currentRoute.toAction + ".html" : master.root + location;
145
218
  var viewFile = fileserver.readFileSync(viewUrl,'utf8');
146
219
  var masterFile = fileserver.readFileSync(this.__currentRoute.root + "/app/views/layouts/master.html", 'utf8');
@@ -154,8 +227,21 @@ class MasterAction{
154
227
  }
155
228
 
156
229
  if (!this.__response._headerSent) {
157
- this.__response.writeHead(200, {'Content-Type': 'text/html'});
158
- this.__response.end(masterView);
230
+ const send = (htmlOut) => {
231
+ try {
232
+ this.__response.writeHead(200, {'Content-Type': 'text/html'});
233
+ this.__response.end(htmlOut);
234
+ } catch (e) {
235
+ // Fallback in case of double send
236
+ }
237
+ };
238
+ try {
239
+ Promise.resolve(compileWebComponentsHTML(masterView))
240
+ .then(send)
241
+ .catch(() => send(masterView));
242
+ } catch (_) {
243
+ send(masterView);
244
+ }
159
245
  }
160
246
 
161
247
  }
@@ -180,7 +266,7 @@ class MasterAction{
180
266
  return true;
181
267
  }
182
268
 
183
- // Enhanced returnJson that checks readiness first
269
+ // Enhanced returnJson that checks readiness first
184
270
  safeReturnJson(data){
185
271
  if (this.waitUntilReady()) {
186
272
  this.returnJson(data);
@@ -190,75 +276,213 @@ class MasterAction{
190
276
  return false;
191
277
  }
192
278
 
193
- // Serves binary files with proper headers and MIME types
194
- // options: {
195
- // contentType: string (auto-detected if not provided),
196
- // disposition: 'inline' | 'attachment' (default: 'attachment'),
197
- // filename: string (defaults to original filename)
198
- // }
199
- returnFile(filePath, options){
200
- options = options || {};
201
-
202
- // Default options
203
- var disposition = options.disposition || 'attachment';
204
- var filename = options.filename || filePath.split('/').pop();
205
- var contentType = options.contentType;
206
-
207
- // Auto-detect content type if not provided
208
- if (!contentType) {
209
- var ext = filePath.split('.').pop().toLowerCase();
210
- var mimeTypes = {
211
- 'pdf': 'application/pdf',
212
- 'jpg': 'image/jpeg',
213
- 'jpeg': 'image/jpeg',
214
- 'png': 'image/png',
215
- 'gif': 'image/gif',
216
- 'svg': 'image/svg+xml',
217
- 'zip': 'application/zip',
218
- 'csv': 'text/csv',
219
- 'txt': 'text/plain',
220
- 'xml': 'application/xml',
221
- 'json': 'application/json',
222
- 'mp4': 'video/mp4',
223
- 'mp3': 'audio/mpeg',
224
- 'wav': 'audio/wav',
225
- 'doc': 'application/msword',
226
- 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
227
- 'xls': 'application/vnd.ms-excel',
228
- 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
229
- 'ppt': 'application/vnd.ms-powerpoint',
230
- 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
231
- };
232
- contentType = mimeTypes[ext] || 'application/octet-stream';
233
- }
279
+ // Render using a page.js Web Component module when present
280
+ _renderPageModule(controller, action, data) {
281
+ try {
282
+ const pageModuleAbs = path.join(master.root, 'app/views', controller, action, 'page.js');
283
+ const layoutModuleAbs = path.join(master.root, 'app/views', 'layouts', 'master.js');
284
+ const stylesPath = '/app/assets/stylesheets/output.css';
285
+ const pageTag = `home-${action}-page`;
234
286
 
235
- try {
236
- // Read file as binary
237
- var fileBuffer = fileserver.readFileSync(filePath);
238
-
239
- // Build headers
240
- var headers = {
241
- 'Content-Type': contentType,
242
- 'Content-Length': fileBuffer.length,
243
- 'Content-Disposition': disposition + '; filename="' + filename + '"'
244
- };
287
+ const htmlDoc =
288
+ `<!DOCTYPE html>
289
+ <html lang="en">
290
+ <head>
291
+ <meta charset="utf-8"/>
292
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
293
+ <title>${controller}/${action}</title>
294
+ <link rel="stylesheet" href="${stylesPath}"/>
295
+ </head>
296
+ <body class="geist-variable antialiased">
297
+ <root-layout>
298
+ <${pageTag}></${pageTag}>
299
+ </root-layout>
300
+ <script type="module" src="/app/views/layouts/master.js"></script>
301
+ <script type="module" src="/app/views/${controller}/${action}/page.js"></script>
302
+ </body>
303
+ </html>`;
245
304
 
246
- // Send response
247
- if (!this.__response._headerSent) {
248
- this.__response.writeHead(200, headers);
249
- this.__response.end(fileBuffer);
250
- }
251
- } catch(error) {
252
- // Handle file not found or read errors
253
- if (!this.__response._headerSent) {
254
- this.__response.writeHead(404, {'Content-Type': 'text/plain'});
255
- this.__response.end('File not found: ' + filePath);
256
- }
257
- console.error('Error serving file:', error);
258
- }
259
- }
305
+ const send = (htmlOut) => {
306
+ try {
307
+ const res = this.__response || (this.__requestObject && this.__requestObject.response);
308
+ if (res && !res._headerSent) {
309
+ res.writeHead(200, { 'Content-Type': 'text/html' });
310
+ res.end(htmlOut);
311
+ }
312
+ } catch (_) {}
313
+ };
314
+
315
+ Promise
316
+ .resolve(require('./ssr/runtime-ssr.cjs')(htmlDoc, [layoutModuleAbs, pageModuleAbs]))
317
+ .then(send)
318
+ .catch(() => send(htmlDoc));
319
+ } catch (e) {
320
+ // Fallback to legacy view if something goes wrong
321
+ console.warn('[SSR] _renderPageModule failed:', e && e.message);
322
+ return false;
323
+ }
324
+ return true;
325
+ }
326
+
327
+ // Delegate to standard Enhance-based SSR only
328
+ returnWebComponent(data) {
329
+ this.returnView(data);
330
+ }
331
+
332
+ // ==================== Security Methods ====================
333
+
334
+ /**
335
+ * Generate CSRF token for forms
336
+ * Usage: const token = this.generateCSRFToken();
337
+ */
338
+ generateCSRFToken() {
339
+ const sessionId = this.__requestObject && this.__requestObject.session ? this.__requestObject.session.id : null;
340
+ return generateCSRFToken(sessionId);
341
+ }
342
+
343
+ /**
344
+ * Validate CSRF token from request
345
+ * Usage: if (!this.validateCSRF()) { return this.returnError(403, 'Invalid CSRF token'); }
346
+ */
347
+ validateCSRF(token = null) {
348
+ // Get token from parameter, header, or body
349
+ const csrfToken = token ||
350
+ this.__requestObject.headers['x-csrf-token'] ||
351
+ (this.__requestObject.body && this.__requestObject.body._csrf) ||
352
+ this.params._csrf;
353
+
354
+ if (!csrfToken) {
355
+ logger.warn({
356
+ code: 'MC_SECURITY_CSRF_MISSING',
357
+ message: 'CSRF token missing in request',
358
+ path: this.__requestObject.pathName
359
+ });
360
+ return false;
361
+ }
362
+
363
+ const validation = validateCSRFToken(csrfToken);
260
364
 
365
+ if (!validation.valid) {
366
+ logger.warn({
367
+ code: 'MC_SECURITY_CSRF_INVALID',
368
+ message: 'CSRF token validation failed',
369
+ path: this.__requestObject.pathName,
370
+ reason: validation.reason
371
+ });
372
+ return false;
373
+ }
374
+
375
+ return true;
376
+ }
377
+
378
+ /**
379
+ * Validate request body against schema
380
+ * Usage: const result = this.validateRequest({ email: { type: 'email' }, age: { type: 'integer', min: 18 } });
381
+ */
382
+ validateRequest(schema = {}) {
383
+ const body = this.__requestObject.body || this.params || {};
384
+ const result = validateRequestBody(body, schema);
385
+
386
+ if (!result.valid) {
387
+ logger.warn({
388
+ code: 'MC_VALIDATION_REQUEST_FAILED',
389
+ message: 'Request validation failed',
390
+ path: this.__requestObject.pathName,
391
+ errors: result.errors
392
+ });
393
+ }
394
+
395
+ return result;
396
+ }
397
+
398
+ /**
399
+ * Sanitize user input (HTML)
400
+ * Usage: const clean = this.sanitizeInput(userInput);
401
+ */
402
+ sanitizeInput(input) {
403
+ if (typeof input === 'string') {
404
+ return sanitizeUserHTML(input);
405
+ } else if (typeof input === 'object' && input !== null) {
406
+ return sanitizeObject(input);
407
+ }
408
+ return input;
409
+ }
410
+
411
+ /**
412
+ * Escape HTML for display
413
+ * Usage: const safe = this.escapeHTML(userContent);
414
+ */
415
+ escapeHTML(text) {
416
+ return escapeHTML(text);
417
+ }
418
+
419
+ /**
420
+ * Validate single field
421
+ * Usage: const result = this.validate(email, { type: 'email' });
422
+ */
423
+ validate(value, rules = {}) {
424
+ switch (rules.type) {
425
+ case 'string':
426
+ return validator.validateString(value, rules);
427
+ case 'integer':
428
+ return validator.validateInteger(value, rules);
429
+ case 'email':
430
+ return validator.validateEmail(value, rules);
431
+ case 'url':
432
+ return validator.validateURL(value, rules);
433
+ case 'uuid':
434
+ return validator.validateUUID(value, rules);
435
+ default:
436
+ return { valid: true, value };
437
+ }
438
+ }
439
+
440
+ /**
441
+ * Check if request is secure (HTTPS)
442
+ */
443
+ isSecure() {
444
+ const req = this.__requestObject.request || this.__requestObject;
445
+ return req.connection.encrypted || req.headers['x-forwarded-proto'] === 'https';
446
+ }
447
+
448
+ /**
449
+ * Require HTTPS for this action
450
+ * Usage: if (!this.requireHTTPS()) return;
451
+ */
452
+ requireHTTPS() {
453
+ if (!this.isSecure()) {
454
+ logger.warn({
455
+ code: 'MC_SECURITY_HTTPS_REQUIRED',
456
+ message: 'HTTPS required but request is HTTP',
457
+ path: this.__requestObject.pathName
458
+ });
459
+
460
+ const httpsUrl = `https://${this.__requestObject.request.headers.host}${this.__requestObject.pathName}`;
461
+ this.redirectTo(httpsUrl);
462
+ return false;
463
+ }
464
+ return true;
465
+ }
466
+
467
+ /**
468
+ * Return error response with proper status
469
+ * Usage: this.returnError(400, 'Invalid input');
470
+ */
471
+ returnError(statusCode, message, details = {}) {
472
+ const res = this.__response || (this.__requestObject && this.__requestObject.response);
473
+
474
+ if (res && !res._headerSent) {
475
+ res.writeHead(statusCode, { 'Content-Type': 'application/json' });
476
+ res.end(JSON.stringify({
477
+ error: true,
478
+ statusCode,
479
+ message,
480
+ ...details
481
+ }));
482
+ }
483
+ }
261
484
 
262
485
  }
263
486
 
487
+
264
488
  master.extendController(MasterAction);
package/MasterControl.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // MasterControl - by Alexander rich
2
- // version 1.0.247
2
+ // version 1.0.251
3
3
 
4
4
  var url = require('url');
5
5
  var fileserver = require('fs');
@@ -11,6 +11,47 @@ var url = require('url');
11
11
  var path = require('path');
12
12
  var globSearch = require("glob");
13
13
 
14
+ // Enhanced error handling - setup global handlers
15
+ const { setupGlobalErrorHandlers } = require('./error/MasterErrorMiddleware');
16
+ const { logger } = require('./error/MasterErrorLogger');
17
+
18
+ // Security - Initialize security features
19
+ const { security, securityHeaders } = require('./security/SecurityMiddleware');
20
+ const { csp } = require('./security/CSPConfig');
21
+ const { session } = require('./security/SessionSecurity');
22
+
23
+ // Initialize global error handling
24
+ setupGlobalErrorHandlers();
25
+
26
+ // Log framework start
27
+ logger.info({
28
+ code: 'MC_INFO_FRAMEWORK_START',
29
+ message: 'MasterController framework initializing',
30
+ context: {
31
+ version: '1.0.247',
32
+ nodeVersion: process.version,
33
+ platform: process.platform,
34
+ env: process.env.NODE_ENV || 'development'
35
+ }
36
+ });
37
+
38
+ // Log security status
39
+ const isProduction = process.env.NODE_ENV === 'production';
40
+ logger.info({
41
+ code: 'MC_INFO_SECURITY_INITIALIZED',
42
+ message: 'Security features initialized',
43
+ context: {
44
+ environment: isProduction ? 'production' : 'development',
45
+ features: {
46
+ securityHeaders: true,
47
+ csp: csp.enabled,
48
+ csrf: security.csrfEnabled,
49
+ rateLimit: security.rateLimitEnabled,
50
+ sessionSecurity: true
51
+ }
52
+ }
53
+ });
54
+
14
55
 
15
56
  class MasterControl {
16
57
  controllerList = {}
@@ -152,23 +193,26 @@ class MasterControl {
152
193
  component(folderLocation, innerFolder){
153
194
 
154
195
  var rootFolderLocation = path.join(this.root, folderLocation, innerFolder);
155
- var files = globSearch.sync("**/*config.js", { cwd: rootFolderLocation, absolute: true });
156
- if(files && files.length > 0){
157
- require(files[0]);
196
+
197
+ // Structure is always: {rootFolderLocation}/config/initializers/config.js
198
+ var configPath = path.join(rootFolderLocation, 'config', 'initializers', 'config.js');
199
+ if(fs.existsSync(configPath)){
200
+ require(configPath);
158
201
  }else{
159
- this.error.log(`Cannot find config file under ${rootFolderLocation}`, "error");
202
+ this.error.log(`Cannot find config file at ${configPath}`, "error");
160
203
  }
161
- var routeFiles = globSearch.sync("**/*routes.js", { cwd: rootFolderLocation, absolute: true });
162
- var route = routeFiles && routeFiles.length > 0 ? routeFiles[0] : null;
204
+
205
+ // Structure is always: {rootFolderLocation}/config/routes.js
206
+ var routePath = path.join(rootFolderLocation, 'config', 'routes.js');
163
207
  var routeObject = {
164
208
  isComponent : true,
165
209
  root : rootFolderLocation
166
210
  }
167
211
  this.router.setup(routeObject);
168
- if(route){
169
- require(route);
212
+ if(fs.existsSync(routePath)){
213
+ require(routePath);
170
214
  }else{
171
- this.error.log(`Cannot find routes file under ${rootFolderLocation}`, "error");
215
+ this.error.log(`Cannot find routes file at ${routePath}`, "error");
172
216
  }
173
217
  }
174
218
 
@@ -203,6 +247,26 @@ class MasterControl {
203
247
  setupServer(type, credentials ){
204
248
  try {
205
249
  var $that = this;
250
+ // Auto-load internal master tools so services (request, error, router, etc.) are available
251
+ // before user config initializes them.
252
+ try {
253
+ $that.addInternalTools([
254
+ 'MasterAction',
255
+ 'MasterActionFilters',
256
+ 'MasterRouter',
257
+ 'MasterRequest',
258
+ 'MasterError',
259
+ 'MasterCors',
260
+ 'MasterSession',
261
+ 'MasterSocket',
262
+ 'MasterHtml',
263
+ 'MasterTemplate',
264
+ 'MasterTools',
265
+ 'TemplateOverwrite'
266
+ ]);
267
+ } catch (e) {
268
+ console.error('[MasterControl] Failed to load internal tools:', e && e.message);
269
+ }
206
270
  if(type === "http"){
207
271
  $that.serverProtocol = "http";
208
272
  return http.createServer(async function(req, res) {
@@ -399,16 +463,25 @@ class MasterControl {
399
463
  return;
400
464
  }
401
465
 
466
+ // Apply CORS headers to ALL non-OPTIONS requests
467
+ try {
468
+ if (this.cors && typeof this.cors.load === 'function') {
469
+ this.cors.load({ request: req, response: res });
470
+ }
471
+ } catch (e) {
472
+ console.warn('CORS load failed for non-OPTIONS request:', e.message);
473
+ }
474
+
402
475
  // parse URL
403
476
  const parsedUrl = url.parse(req.url);
404
477
  // extract URL path
405
478
  let pathname = `.${parsedUrl.pathname}`;
406
-
479
+
407
480
  // based on the URL path, extract the file extension. e.g. .js, .doc, ...
408
481
  const ext = path.parse(pathname).ext;
409
-
482
+
410
483
  // handle simple preflight configuration - might need a complex approch for all scenarios
411
-
484
+
412
485
 
413
486
  // if extension exist then its a file.
414
487
  if(ext === ""){
@@ -471,16 +544,18 @@ class MasterControl {
471
544
 
472
545
  startMVC(foldername){
473
546
  var rootFolderLocation = path.join(this.root, foldername);
474
- var files = globSearch.sync("**/*routes.js", { cwd: rootFolderLocation, absolute: true });
547
+
548
+ // Structure is always: {rootFolderLocation}/routes.js
549
+ var routePath = path.join(rootFolderLocation, 'routes.js');
475
550
  var route = {
476
- isComponent : false,
551
+ isComponent : false,
477
552
  root : `${this.root}`
478
553
  }
479
554
  this.router.setup(route);
480
- if(files && files.length > 0){
481
- require(files[0]);
555
+ if(fs.existsSync(routePath)){
556
+ require(routePath);
482
557
  }else{
483
- master.error.log(`Cannot find routes file under ${rootFolderLocation}`, "error");
558
+ this.error.log(`Cannot find routes file at ${routePath}`, "error");
484
559
  }
485
560
  }
486
561
 
@@ -488,8 +563,26 @@ class MasterControl {
488
563
  // builds and calls all the required tools to have master running completely
489
564
  addInternalTools(requiredList){
490
565
  if(requiredList.constructor === Array){
566
+ // Map module names to their new organized paths
567
+ const modulePathMap = {
568
+ 'MasterError': './error/MasterError',
569
+ 'MasterAction': './MasterAction',
570
+ 'MasterActionFilters': './MasterActionFilters',
571
+ 'MasterRouter': './MasterRouter',
572
+ 'MasterRequest': './MasterRequest',
573
+ 'MasterCors': './MasterCors',
574
+ 'MasterSession': './MasterSession',
575
+ 'MasterSocket': './MasterSocket',
576
+ 'MasterHtml': './MasterHtml',
577
+ 'MasterTemplate': './MasterTemplate',
578
+ 'MasterTools': './MasterTools',
579
+ 'TemplateOverwrite': './TemplateOverwrite'
580
+ };
581
+
491
582
  for(var i = 0; i < requiredList.length; i++){
492
- require('./' + requiredList[i]);
583
+ const moduleName = requiredList[i];
584
+ const modulePath = modulePathMap[moduleName] || './' + moduleName;
585
+ require(modulePath);
493
586
  }
494
587
  }
495
588
  }