@reldens/cms 0.47.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,98 @@
1
+ # Advanced Usage Guide
2
+
3
+ ## Template Reloading for Development
4
+
5
+ ```javascript
6
+ const isDevelopment = process.env.NODE_ENV === 'development';
7
+
8
+ const cms = new Manager({
9
+ reloadTime: isDevelopment ? -1 : 0,
10
+ cache: !isDevelopment,
11
+ entityAccess: {
12
+ articles: { public: true, operations: ['read'] },
13
+ cmsPages: { public: true, operations: ['read'] }
14
+ }
15
+ });
16
+ ```
17
+
18
+ **Development Workflow with Template Reloading:**
19
+
20
+ 1. Set `reloadTime: -1` for instant template updates
21
+ 2. Edit admin templates in `admin/templates/` - changes appear immediately
22
+ 3. Edit frontend templates in `templates/` - changes appear on next page load
23
+ 4. No server restart needed for template changes
24
+ 5. Switch to `reloadTime: 0` in production for optimal performance
25
+
26
+ ## Event System
27
+
28
+ The CMS provides hooks for customization through event listeners:
29
+
30
+ ```javascript
31
+ cms.events.on('reldens.afterVariablesCreated', (eventData) => {
32
+ eventData.variables.customData = {
33
+ timestamp: Date.now(),
34
+ version: '1.0.0'
35
+ };
36
+ });
37
+
38
+ cms.events.on('reldens.beforeContentProcess', (eventData) => {
39
+ eventData.content = eventData.content.replace(/\[custom\]/g, 'Custom Value');
40
+ });
41
+
42
+ cms.events.on('reldens.afterContentProcess', (eventData) => {
43
+ eventData.processedContent += '\n<!-- Processed at '+new Date()+' -->';
44
+ });
45
+
46
+ cms.events.on('reldens.templateReloader.templatesChanged', (eventData) => {
47
+ console.log('Templates changed:', eventData.changedFiles);
48
+ });
49
+
50
+ cms.events.on('reldens.dynamicForm.afterSave', (eventData) => {
51
+ console.log('Form submission received:', eventData.result.id);
52
+ });
53
+ ```
54
+
55
+ ## Custom Authentication
56
+
57
+ ```javascript
58
+ const customAuth = async (email, password, roleId) => {
59
+ let user = await yourAuthService.authenticate(email, password);
60
+ return user && user.role_id === roleId ? user : false;
61
+ };
62
+
63
+ const cms = new Manager({
64
+ authenticationMethod: 'custom',
65
+ authenticationCallback: customAuth
66
+ });
67
+ ```
68
+
69
+ ## File Upload Configuration
70
+
71
+ ```javascript
72
+ const uploadConfig = {
73
+ mimeTypes: {
74
+ image: ['image/jpeg', 'image/png', 'image/webp'],
75
+ document: ['application/pdf', 'text/plain']
76
+ },
77
+ allowedExtensions: {
78
+ image: ['.jpg', '.jpeg', '.png', '.webp'],
79
+ document: ['.pdf', '.txt']
80
+ }
81
+ };
82
+
83
+ const cms = new Manager(uploadConfig);
84
+ ```
85
+
86
+ ## Event Hooks
87
+
88
+ ```javascript
89
+ cms.events.on('reldens.setupAdminRoutes', ({adminManager}) => {
90
+ adminManager.adminRouter.get('/custom', (req, res) => {
91
+ res.send('Custom admin page');
92
+ });
93
+ });
94
+
95
+ cms.events.on('adminEntityExtraData', ({entitySerializedData, entity}) => {
96
+ entitySerializedData.customField = 'Custom Value';
97
+ });
98
+ ```
@@ -0,0 +1,146 @@
1
+ # API Reference
2
+
3
+ ## Manager Class
4
+
5
+ - `start()` - Initialize and start the CMS
6
+ - `isInstalled()` - Check if CMS is installed
7
+ - `initializeServices()` - Initialize all services
8
+ - `validateProvidedServer()` - Validate provided server instance
9
+ - `validateProvidedDataServer()` - Validate provided data server
10
+ - `validateProvidedAdminManager()` - Validate provided admin manager
11
+ - `validateProvidedFrontend()` - Validate provided frontend
12
+ - `buildAppServerConfiguration()` - Build server configuration
13
+ - `initializeCmsAfterInstall(props)` - Post-installation callback
14
+
15
+ ## Installer Class
16
+
17
+ - `isInstalled()` - Check installation status
18
+ - `configureAppServerRoutes(app, appServer, appServerFactory, renderEngine)` - Setup installer routes
19
+ - `executeInstallProcess(req, res)` - Complete installation process
20
+ - `runSubprocessInstallation(dbConfig, templateVariables)` - Handle subprocess operations
21
+ - `checkAndInstallPackages(requiredPackages)` - Check and install dependencies
22
+ - `generateEntities(server, isOverride, isInstallationMode, isDryPrisma, dbConfig)` - Generate entities
23
+ - `createEnvFile(templateVariables)` - Create environment configuration
24
+ - `copyAdminDirectory()` - Copy admin assets and templates
25
+
26
+ ## Frontend Architecture Classes
27
+
28
+ ### Frontend Class (Orchestrator)
29
+
30
+ - `initialize()` - Set up frontend routes and templates
31
+ - `handleRequest(req, res)` - Main request handler
32
+ - `renderRoute(route, domain, res, req)` - Route-based rendering
33
+ - `setupStaticAssets()` - Configure static asset serving
34
+
35
+ ### TemplateResolver Class
36
+
37
+ - `findTemplatePath(templateName, domain)` - Template discovery with domain fallback
38
+ - `findLayoutPath(layoutName, domain)` - Layout path resolution
39
+ - `findTemplateByPath(path, domain)` - Template lookup by URL path
40
+ - `resolveDomainToFolder(domain)` - Domain to folder mapping
41
+ - `resolveDomainToSiteKey(domain)` - Domain to site key mapping
42
+
43
+ ### TemplateCache Class
44
+
45
+ - `loadPartials()` - Load and cache template partials
46
+ - `setupDomainTemplates()` - Initialize domain-specific templates
47
+ - `getPartialsForDomain(domain)` - Get domain-specific partials with fallback
48
+
49
+ ### TemplateReloader Class
50
+
51
+ - `checkAndReloadAdminTemplates()` - Check and reload admin templates when changed
52
+ - `checkAndReloadFrontendTemplates()` - Check and reload frontend templates when changed
53
+ - `trackTemplateFiles(templatesPaths)` - Start tracking template files for changes
54
+ - `shouldReloadAdminTemplates(mappedAdminTemplates)` - Check if admin templates need reloading
55
+ - `shouldReloadFrontendTemplates(templatesPath, templateExtensions)` - Check if frontend templates need reloading
56
+ - `handleAdminTemplateReload(adminManager)` - Complete admin template reload process
57
+ - `handleFrontendTemplateReload(templateCache, templateResolver)` - Complete frontend template reload process
58
+
59
+ ### RequestProcessor Class
60
+
61
+ - `findRouteByPath(path, domain)` - Database route lookup
62
+ - `handleRouteRedirect(route, res)` - Handle route redirects
63
+ - `getDomainFromRequest(req)` - Extract domain from request
64
+ - `buildCacheKey(path, req)` - Generate cache keys
65
+
66
+ ### ContentRenderer Class
67
+
68
+ - `renderWithTemplateContent(content, data, domain, req, route)` - Main content rendering
69
+ - `generateRouteContent(route, domain, req)` - Route-based content generation
70
+ - `generateTemplateContent(templatePath, domain, req, data)` - Template-based content generation
71
+ - `fetchMetaFields(data)` - Process meta fields for templates
72
+
73
+ ### EntityAccessManager Class
74
+
75
+ - `loadEntityAccessRules()` - Load entity access configuration
76
+ - `isEntityAccessible(entityName)` - Check entity accessibility
77
+ - `findEntityByPath(path)` - Entity lookup by URL path
78
+
79
+ ### ResponseManager Class
80
+
81
+ - `renderWithCacheHandler(contentGenerator, errorHandler, responseHandler, domain, res, path, req)` - Generic cached response handler
82
+ - `renderNotFound(domain, res, req)` - 404 error handling
83
+
84
+ ### SearchRequestHandler Class
85
+
86
+ - `handleSearchRequest(req, res)` - Process search requests with template data support
87
+
88
+ ## TemplateEngine Class
89
+
90
+ - `render(template, data, partials, domain, req, route, currentEntityData)` - Main template rendering with enhanced context
91
+ - `processAllTemplateFunctions(template, domain, req, systemVariables)` - Process all template functions
92
+ - `buildEnhancedRenderData(data, systemVariables, currentEntityData)` - Build template context with system variables
93
+
94
+ ## SystemVariablesProvider Class
95
+
96
+ - `buildSystemVariables(req, route, domain)` - Create system variables for templates
97
+ - `buildCurrentRequestData(req, domain)` - Build request context
98
+ - `buildCurrentRouteData(route)` - Build route context
99
+ - `buildCurrentDomainData(domain)` - Build domain context
100
+
101
+ ## Search Classes
102
+
103
+ - `Search.parseSearchParameters(query)` - Parse search query parameters including templateData
104
+ - `Search.executeSearch(config)` - Execute search with configuration
105
+ - `SearchRenderer.renderSearchResults(searchResults, config, domain, req)` - Render search results with template data
106
+
107
+ ## Forms System Classes
108
+
109
+ ### DynamicForm Class
110
+
111
+ - `validateFormSubmission(formKey, submittedValues, req)` - Validate form submission
112
+ - `getFormConfig(formKey)` - Load form configuration from database
113
+ - `validateHoneypot(submittedValues)` - Check honeypot field for bots
114
+ - `validateFields(fieldsSchema, submittedValues)` - Schema-based field validation
115
+ - `prepareSubmittedValues(submittedValues, fieldsSchema)` - Process and normalize values
116
+ - `saveFormSubmission(formConfig, preparedValues)` - Save to database
117
+
118
+ ### DynamicFormRenderer Class
119
+
120
+ - `renderForm(formConfig, fieldsToRender, domain, req, attributes)` - Render complete form
121
+ - `renderFormFields(fieldsToRender, domain, req)` - Render field set
122
+ - `renderFormField(field, domain, submittedValues, errors)` - Render individual field
123
+ - `loadFormTemplate(templateName, domain)` - Load form template with domain fallback
124
+ - `findFormTemplate(templateName, domain)` - Template discovery for forms
125
+
126
+ ### DynamicFormRequestHandler Class
127
+
128
+ - `handleFormSubmission(req, res)` - Process POST form submissions
129
+ - `handleBadRequest(res, message)` - Handle validation errors
130
+ - `handleSuccessResponse(req, res, formKey, result)` - Handle successful submissions
131
+ - `buildErrorRedirectPath(req, error, formKey)` - Build error redirect URLs
132
+ - `buildSuccessRedirectPath(successRedirect, formKey)` - Build success redirect URLs
133
+
134
+ ### FormsTransformer Class
135
+
136
+ - `transform(template, domain, req, systemVariables, enhancedData)` - Process cmsForm tags
137
+ - `findAllFormTags(template)` - Find cmsForm tags in template
138
+ - `parseFormAttributes(fullTag)` - Parse tag attributes
139
+ - `parseFieldsFilter(attributes, formConfig)` - Filter fields based on attributes
140
+
141
+ ## AdminManager Class
142
+
143
+ - `setupAdmin()` - Initialize admin panel
144
+ - `generateListRouteContent()` - Entity list pages
145
+ - `generateEditRouteContent()` - Entity edit forms
146
+ - `processSaveEntity()` - Handle form submissions
@@ -0,0 +1,126 @@
1
+ # Configuration Guide
2
+
3
+ ## Environment Variables
4
+
5
+ ```env
6
+ RELDENS_APP_HOST=http://localhost
7
+ RELDENS_APP_PORT=8080
8
+ RELDENS_ADMIN_ROUTE_PATH=/admin
9
+ RELDENS_ADMIN_SECRET=your-secret-key
10
+
11
+ RELDENS_DB_CLIENT=mysql
12
+ RELDENS_DB_HOST=localhost
13
+ RELDENS_DB_PORT=3306
14
+ RELDENS_DB_NAME=cms_db
15
+ RELDENS_DB_USER=username
16
+ RELDENS_DB_PASSWORD=password
17
+ RELDENS_STORAGE_DRIVER=prisma
18
+
19
+ RELDENS_DEFAULT_DOMAIN=example.com
20
+ RELDENS_DOMAIN_MAPPING={"dev.example.com":"development"}
21
+ RELDENS_SITE_KEY_MAPPING={"example.com":"main"}
22
+ ```
23
+
24
+ ## Template Reloading Configuration
25
+
26
+ Configure template reloading for development environments:
27
+
28
+ ```javascript
29
+ const cms = new Manager({
30
+ // Development: reload templates on every request when changes detected
31
+ reloadTime: -1,
32
+
33
+ // Production: disable template reloading (default)
34
+ reloadTime: 0,
35
+
36
+ // Interval-based: reload every 5 seconds when changes detected
37
+ reloadTime: 5000
38
+ });
39
+ ```
40
+
41
+ **Template Reloading Options:**
42
+
43
+ - `reloadTime: 0` (default) - Template reloading disabled. Templates load once at startup.
44
+ - `reloadTime: -1` - Reload templates on every request when file changes are detected. Best for active development.
45
+ - `reloadTime: > 0` - Check for template changes at specified interval (milliseconds) and reload when needed. Good for development with lower overhead.
46
+
47
+ **How it works:**
48
+
49
+ - Tracks file modification times for admin and frontend templates
50
+ - Only reloads templates that have actually changed
51
+ - Automatically updates admin contents and frontend template cache
52
+ - Works with both admin panel templates and frontend templates/partials
53
+ - Zero performance impact when disabled (`reloadTime: 0`)
54
+
55
+ ## Custom Entity Configuration
56
+
57
+ ```javascript
58
+ const entityConfig = {
59
+ articles: {
60
+ listProperties: ['title', 'status', 'created_at'],
61
+ showProperties: ['title', 'content', 'author', 'status'],
62
+ editProperties: ['title', 'content', 'author_id', 'status'],
63
+ filterProperties: ['status', 'author_id'],
64
+ titleProperty: 'title',
65
+ parentItemLabel: 'Content',
66
+ properties: {
67
+ title: { type: 'string', isRequired: true },
68
+ content: { type: 'text' },
69
+ author_id: { type: 'reference', reference: 'users' },
70
+ featured_image: {
71
+ type: 'string',
72
+ isUpload: true,
73
+ allowedTypes: 'image',
74
+ bucket: 'uploads'
75
+ }
76
+ }
77
+ }
78
+ };
79
+
80
+ const cms = new Manager({
81
+ entitiesConfig: entityConfig
82
+ });
83
+ ```
84
+
85
+ ## Manager Configuration Options
86
+
87
+ ```javascript
88
+ const cms = new Manager({
89
+ projectRoot: process.cwd(),
90
+
91
+ // Entity Access Control
92
+ entityAccess: {
93
+ cmsPages: { public: true, operations: ['read'] },
94
+ articles: { public: true, operations: ['read'] },
95
+ users: { public: false }
96
+ },
97
+
98
+ // Authentication
99
+ authenticationMethod: 'db-users',
100
+ adminRoleId: 99,
101
+ authenticationCallback: async (email, password, roleId) => {
102
+ return await yourAuthService.validate(email, password, roleId);
103
+ },
104
+
105
+ // Performance
106
+ cache: true,
107
+ reloadTime: 0,
108
+
109
+ // Multi-Domain
110
+ defaultDomain: 'example.com',
111
+ domainMapping: {'dev.example.com': 'development'},
112
+ siteKeyMapping: {'example.com': 'main'},
113
+
114
+ // Custom Entities
115
+ entitiesConfig: entityConfig,
116
+ entitiesTranslations: {},
117
+ adminTranslations: {},
118
+
119
+ // Optional Custom Services
120
+ app: customExpressApp,
121
+ appServer: customAppServer,
122
+ dataServer: customDataServer,
123
+ adminManager: customAdmin,
124
+ frontend: customFrontend
125
+ });
126
+ ```
@@ -0,0 +1,32 @@
1
+ # Database Schema
2
+
3
+ ## Core Tables
4
+
5
+ - `routes` - URL routing and SEO metadata
6
+ - `cms_pages` - Page content with layout assignments
7
+ - `cms_blocks` - Reusable content blocks
8
+ - `entities_access` - Entity access control rules
9
+ - `entities_meta` - Generic metadata storage
10
+ - `cms_pages_meta` - Page-specific metadata
11
+
12
+ ## Forms Tables
13
+
14
+ - `cms_forms` - Form configurations with JSON schema
15
+ - `cms_forms_submitted` - Form submissions with JSON data
16
+
17
+ ## User Management Tables (Optional)
18
+
19
+ - `users` - User authentication with encrypted passwords
20
+ - `roles` - Role definitions
21
+
22
+ ## Installation Options
23
+
24
+ The installer provides checkboxes for:
25
+
26
+ - CMS core tables
27
+ - User authentication system
28
+ - Default admin user
29
+ - Default homepage
30
+ - Default content blocks
31
+ - Entity access control rules
32
+ - Dynamic forms system
@@ -0,0 +1,193 @@
1
+ # Dynamic Forms System Guide
2
+
3
+ ## Basic Form Usage
4
+
5
+ Create forms in your templates using the `<cmsForm>` tag:
6
+
7
+ ```html
8
+ <cmsForm key="contactForm"/>
9
+ <cmsForm key="contactForm" fields="name,email,subject,message"/>
10
+ <cmsForm key="newsletterSignup"
11
+ fields="email,name"
12
+ submitButtonText="Subscribe Now"
13
+ cssClass="newsletter-form"
14
+ successRedirect="/thank-you"
15
+ errorRedirect="/contact-error"/>
16
+ ```
17
+
18
+ ## Form Configuration
19
+
20
+ Forms are configured in the `cms_forms` table via the admin panel.
21
+
22
+ ### Supported Field Types
23
+
24
+ - **text** - Basic text input with maxLength, pattern validation
25
+ - **email** - Email input with built-in email validation
26
+ - **number** - Numeric input with min/max validation
27
+ - **textarea** - Multi-line text with maxLength
28
+ - **select** - Dropdown with options array
29
+ - **password** - Password input (masked)
30
+ - **tel** - Phone number input
31
+ - **url** - URL input with validation
32
+ - **date** - Date picker input
33
+
34
+ ### Field Schema Properties
35
+
36
+ ```json
37
+ {
38
+ "name": "fieldName",
39
+ "type": "text",
40
+ "label": "Field Label",
41
+ "required": true,
42
+ "placeholder": "Enter text...",
43
+ "helpText": "Additional help",
44
+ "maxLength": 100,
45
+ "minLength": 3,
46
+ "pattern": "^[A-Za-z]+$",
47
+ "min": 0,
48
+ "max": 100,
49
+ "step": 1,
50
+ "defaultValue": "default",
51
+ "options": [
52
+ {"value": "val1", "label": "Option 1"},
53
+ {"value": "val2", "label": "Option 2"}
54
+ ]
55
+ }
56
+ ```
57
+
58
+ ## Security Features
59
+
60
+ ### Honeypot Protection
61
+
62
+ Automatic bot detection using invisible fields.
63
+
64
+ ### Server-Side Validation
65
+
66
+ - SchemaValidator integration
67
+ - Required field validation
68
+ - Type validation
69
+ - Length limits
70
+ - Custom validation
71
+
72
+ ### Data Sanitization
73
+
74
+ - XSS protection
75
+ - Input normalization
76
+ - Length truncation
77
+
78
+ ### Rate Limiting
79
+
80
+ Uses AppServerFactory integration from server-utils.
81
+
82
+ ## Template Customization
83
+
84
+ Forms use a domain-aware template fallback system:
85
+
86
+ ```
87
+ templates/
88
+ ├── domains/
89
+ │ └── example.com/
90
+ │ └── cms_forms/
91
+ │ ├── form.html
92
+ │ ├── field_text.html
93
+ │ └── field_email.html
94
+ └── cms_forms/
95
+ ├── form.html
96
+ ├── field_text.html
97
+ ├── field_email.html
98
+ ├── field_textarea.html
99
+ ├── field_select.html
100
+ └── field_number.html
101
+ ```
102
+
103
+ ## Event System Integration
104
+
105
+ ### Available Form Events
106
+
107
+ - `reldens.formsTransformer.beforeRender` - Before form rendering
108
+ - `reldens.formsTransformer.afterRender` - After form rendering
109
+ - `reldens.dynamicForm.beforeValidation` - Before form validation
110
+ - `reldens.dynamicForm.afterValidation` - After form validation
111
+ - `reldens.dynamicForm.beforeSave` - Before saving to database
112
+ - `reldens.dynamicForm.afterSave` - After successful save
113
+ - `reldens.dynamicFormRenderer.beforeFieldsRender` - Before rendering fields
114
+ - `reldens.dynamicFormRenderer.afterFieldsRender` - After rendering fields
115
+ - `reldens.dynamicFormRequestHandler.beforeValidation` - Before request validation
116
+ - `reldens.dynamicFormRequestHandler.beforeSave` - Before save process
117
+ - `reldens.dynamicFormRequestHandler.afterSave` - After successful save
118
+
119
+ ### Example Event Usage
120
+
121
+ ```javascript
122
+ cms.events.on('reldens.formsTransformer.beforeRender', (eventData) => {
123
+ eventData.formAttributes.cssClass += ' custom-form';
124
+ });
125
+
126
+ cms.events.on('reldens.dynamicForm.afterSave', (eventData) => {
127
+ console.log('Form saved:', eventData.result.id);
128
+ });
129
+ ```
130
+
131
+ ## Database Tables
132
+
133
+ ### cms_forms Table
134
+
135
+ ```sql
136
+ CREATE TABLE `cms_forms` (
137
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
138
+ `form_key` VARCHAR(255) NOT NULL UNIQUE,
139
+ `fields_schema` JSON NOT NULL,
140
+ `enabled` TINYINT UNSIGNED NOT NULL DEFAULT '0',
141
+ `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
142
+ `updated_at` TIMESTAMP NOT NULL DEFAULT (NOW()) ON UPDATE CURRENT_TIMESTAMP,
143
+ PRIMARY KEY (`id`)
144
+ );
145
+ ```
146
+
147
+ ### cms_forms_submitted Table
148
+
149
+ ```sql
150
+ CREATE TABLE `cms_forms_submitted` (
151
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
152
+ `form_id` INT UNSIGNED NOT NULL,
153
+ `submitted_values` JSON NOT NULL,
154
+ `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
155
+ PRIMARY KEY (`id`),
156
+ FOREIGN KEY (`form_id`) REFERENCES `cms_forms`(`id`)
157
+ );
158
+ ```
159
+
160
+ ## Form Processing Flow
161
+
162
+ 1. Template Processing - FormsTransformer finds cmsForm tags
163
+ 2. Form Loading - Loads form configuration from database
164
+ 3. Field Filtering - Applies field filter if specified
165
+ 4. Template Rendering - Renders form using domain-aware templates
166
+ 5. Form Submission - POST request to /dynamic-form endpoint
167
+ 6. Validation - Honeypot, required fields, and schema validation
168
+ 7. Data Processing - Input sanitization and normalization
169
+ 8. Database Storage - Save to cms_forms_submitted table
170
+ 9. Response - Redirect with success/error parameters
171
+
172
+ ## Advanced Usage
173
+
174
+ ### AJAX Form Submissions
175
+
176
+ ```javascript
177
+ const cms = new Manager({
178
+ enableJsonResponse: true
179
+ });
180
+ ```
181
+
182
+ ```javascript
183
+ document.querySelector('.dynamic-form').addEventListener('submit', async function(e) {
184
+ e.preventDefault();
185
+ let response = await fetch('/dynamic-form', {method: 'POST', body: new FormData(this)});
186
+ let result = await response.json();
187
+ if(result.success){
188
+ alert('Form submitted successfully!');
189
+ return;
190
+ }
191
+ alert('Error: '+result.error);
192
+ });
193
+ ```