@reldens/cms 0.40.0 → 0.42.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/CLAUDE.md ADDED
@@ -0,0 +1,566 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Package Overview
6
+
7
+ **@reldens/cms** is a comprehensive Content Management System package for Reldens. It provides a complete web application framework with:
8
+ - Database-driven content management with entity access control
9
+ - Multi-domain support with domain-specific templates
10
+ - Powerful template engine with Mustache integration
11
+ - Dynamic forms system with validation and security
12
+ - Search functionality with customizable templates
13
+ - Admin panel with full CRUD operations
14
+ - Template reloading for development
15
+ - Caching system for performance
16
+ - Event-driven architecture for extensibility
17
+
18
+ ## Key Commands
19
+
20
+ ```bash
21
+ # Start CMS (runs installer if not installed)
22
+ npx reldens-cms
23
+
24
+ # Generate entities from database
25
+ npx reldens-cms-generate-entities
26
+
27
+ # Or via npm scripts
28
+ npm run generate-entities
29
+ ```
30
+
31
+ ## Architecture Overview
32
+
33
+ The CMS follows a modular architecture with specialized classes following SOLID principles:
34
+
35
+ ### Core Orchestrators
36
+
37
+ **lib/manager.js** - Main CMS orchestrator
38
+ - Initializes all services (data server, admin, frontend)
39
+ - Handles configuration and environment variables
40
+ - Manages multi-domain setup and security
41
+ - Coordinates service lifecycle
42
+
43
+ **lib/frontend.js** - Frontend orchestrator
44
+ - Coordinates all frontend operations
45
+ - Manages template engine, cache, and rendering
46
+ - Handles search and dynamic forms
47
+ - Routes requests to appropriate handlers
48
+
49
+ **lib/admin-manager.js** - Admin panel orchestrator
50
+ - Manages admin panel routes and authentication
51
+ - Handles entity CRUD operations
52
+ - Processes file uploads
53
+ - Builds admin UI from entity configurations
54
+
55
+ ### Installation & Setup
56
+
57
+ **lib/installer.js** - Installation orchestrator
58
+ - Web-based installer with subprocess management
59
+ - Dependency checking and installation
60
+ - Database schema creation
61
+ - Environment file generation
62
+ - Post-installation callbacks
63
+
64
+ **lib/mysql-installer.js** - Database-specific installation
65
+ - MySQL schema creation
66
+ - Schema migration support
67
+ - Database validation
68
+
69
+ **lib/prisma-subprocess-worker.js** - Subprocess worker
70
+ - Handles Prisma client generation
71
+ - Progress tracking for long operations
72
+
73
+ ### Frontend Architecture (lib/frontend/)
74
+
75
+ **template-resolver.js** - Template discovery
76
+ - Domain-aware template resolution
77
+ - Fallback system (domain → default → base)
78
+ - Layout and partial template lookup
79
+ - Path-to-template mapping
80
+
81
+ **template-cache.js** - Template caching
82
+ - Loads and caches partials
83
+ - Domain-specific template management
84
+ - Partial inheritance and overrides
85
+
86
+ **request-processor.js** - Request routing
87
+ - Route database lookup
88
+ - Domain extraction from requests
89
+ - Path normalization
90
+ - Cache key generation
91
+
92
+ **entity-access-manager.js** - Entity access control
93
+ - Loads entity access rules
94
+ - Public/private entity validation
95
+ - Entity lookup by path
96
+
97
+ **content-renderer.js** - Content generation
98
+ - Main content rendering logic
99
+ - Route-based content generation
100
+ - Template processing
101
+ - Meta field handling
102
+
103
+ **response-manager.js** - Response handling
104
+ - HTTP response management
105
+ - Cache integration
106
+ - Error handling (404, 500)
107
+
108
+ ### Template Engine (lib/template-engine.js & lib/template-engine/)
109
+
110
+ **template-engine.js** - Core template processor
111
+ - Orchestrates all template transformers
112
+ - System variables injection
113
+ - Event-driven rendering pipeline
114
+ - Mustache integration
115
+
116
+ **Template Transformers:**
117
+ - **entities-transformer.js** - Single entity rendering `<entity name="cmsBlocks" field="name" value="header"/>`
118
+ - **collections-transformer.js** - Collection loops with pagination
119
+ - **collections-single-transformer.js** - Single field collections
120
+ - **partials-transformer.js** - Partial template processing
121
+ - **forms-transformer.js** - Dynamic forms rendering `<cmsForm key="contact"/>`
122
+ - **url-transformer.js** - URL generation `[url(/path)]`
123
+ - **asset-transformer.js** - Asset URLs `[asset(/img/logo.png)]`
124
+ - **cdn-transformer.js** - CDN URL transformation
125
+ - **date-transformer.js** - Date formatting `[date(now, Y-m-d)]`
126
+ - **translate-transformer.js** - Internationalization `[translate(key)]`
127
+
128
+ **system-variables-provider.js** - System variables
129
+ - Current request context (host, path, protocol)
130
+ - Current route data
131
+ - Current domain information
132
+ - System information (environment, timestamp)
133
+
134
+ **translation-service.js** - Translation loading
135
+ - JSON translation file management
136
+ - Locale detection
137
+ - Fallback handling
138
+
139
+ ### Dynamic Forms System
140
+
141
+ **lib/dynamic-form.js** - Form validation and processing
142
+ - Schema-based validation
143
+ - Honeypot protection
144
+ - Rate limiting integration
145
+ - Data sanitization
146
+ - Database storage
147
+
148
+ **lib/dynamic-form-renderer.js** - Form template rendering
149
+ - Domain-aware form templates
150
+ - Field type templates
151
+ - Error display
152
+ - Form attribute handling
153
+
154
+ **lib/dynamic-form-request-handler.js** - Form request handling
155
+ - POST request processing
156
+ - Validation orchestration
157
+ - Success/error redirects
158
+ - JSON response support
159
+
160
+ ### Search System
161
+
162
+ **lib/search.js** - Search functionality
163
+ - Multi-entity search
164
+ - Custom search sets
165
+ - Query parameter parsing
166
+ - Pagination support
167
+
168
+ **lib/search-renderer.js** - Search result rendering
169
+ - Template-based result display
170
+ - Custom column classes
171
+ - Domain-aware templates
172
+
173
+ **lib/search-request-handler.js** - Search request handling
174
+ - Query processing
175
+ - Template data support
176
+ - Error handling
177
+
178
+ ### Cache System (lib/cache/)
179
+
180
+ **cache-manager.js** - Cache orchestrator
181
+ - Domain and path-based caching
182
+ - Cache invalidation
183
+ - Enable/disable functionality
184
+
185
+ **cache-routes-handler.js** - Cache admin routes
186
+ - Cache clearing endpoints
187
+ - Cache management UI integration
188
+
189
+ **add-cache-button-subscriber.js** - Cache UI integration
190
+ - Adds cache buttons to admin panel
191
+ - Event-driven cache controls
192
+
193
+ ### Admin System (lib/admin-manager/)
194
+
195
+ **router.js** - Admin routing
196
+ - Authentication middleware
197
+ - Session management
198
+ - CRUD route setup
199
+ - File upload handling
200
+
201
+ **router-contents.js** - Admin content generation
202
+ - List view generation
203
+ - Edit form generation
204
+ - Relation handling
205
+ - Save/delete processing
206
+
207
+ **contents-builder.js** - Admin UI builder
208
+ - Sidebar navigation
209
+ - Entity list/edit views
210
+ - Form field generation
211
+ - Branding and styling
212
+
213
+ **admin-filters-manager.js** - Entity filtering
214
+ - Filter UI generation
215
+ - Query building
216
+
217
+ **default-translations.js** - Admin translations
218
+ - Default English labels
219
+ - Extensible translation system
220
+
221
+ ### Utility Classes
222
+
223
+ **lib/entities-loader.js** - Entity loading from files
224
+ **lib/loaded-entities-processor.js** - Entity configuration processing
225
+ **lib/admin-entities-generator.js** - Admin entity configuration
226
+ **lib/admin-templates-loader.js** - Admin template loading
227
+ **lib/templates-to-path-mapper.js** - Template path mapping
228
+ **lib/templates-list.js** - Template file list
229
+ **lib/json-fields-parser.js** - JSON field parsing
230
+ **lib/pagination-handler.js** - Pagination logic
231
+ **lib/template-reloader.js** - Development template reloading
232
+ **lib/cms-pages-route-manager.js** - CMS page routing
233
+ **lib/admin-manager-validator.js** - Admin config validation
234
+ **lib/admin-dist-helper.js** - Admin asset distribution
235
+ **lib/mime-types.js** - File type definitions
236
+ **lib/allowed-extensions.js** - Upload extension whitelist
237
+
238
+ ## Database Schema
239
+
240
+ The CMS uses these core tables:
241
+
242
+ ### Content Tables
243
+ - **routes** - URL routing with SEO metadata (title, description, keywords)
244
+ - **cms_pages** - Page content with layout assignments
245
+ - **cms_blocks** - Reusable content blocks (by name identifier)
246
+ - **cms_forms** - Dynamic form configurations with JSON schema
247
+ - **cms_forms_submitted** - Form submission storage with JSON data
248
+
249
+ ### Access Control
250
+ - **entities_access** - Entity visibility and operation rules
251
+ - **entities_meta** - Generic metadata storage
252
+ - **cms_pages_meta** - Page-specific metadata
253
+
254
+ ### User Management (Optional)
255
+ - **users** - User authentication
256
+ - **roles** - Role definitions
257
+
258
+ ## Template System
259
+
260
+ ### Template Directory Structure
261
+ ```
262
+ templates/
263
+ ├── domains/ # Domain-specific templates
264
+ │ └── example.com/
265
+ │ ├── layouts/ # Domain layouts
266
+ │ ├── partials/ # Domain partials
267
+ │ ├── cms_forms/ # Domain form templates
268
+ │ └── page.html # Domain page wrapper
269
+ ├── layouts/ # Default layouts (body content only)
270
+ │ ├── default.html
271
+ │ └── full-width.html
272
+ ├── partials/ # Default partials
273
+ ├── cms_forms/ # Default form templates
274
+ │ ├── form.html
275
+ │ ├── field_text.html
276
+ │ └── field_email.html
277
+ ├── translations/ # i18n files
278
+ │ ├── en.json
279
+ │ └── es.json
280
+ ├── page.html # Base HTML wrapper
281
+ └── 404.html # Error page
282
+ ```
283
+
284
+ ### Template Resolution Order
285
+ 1. Domain-specific: `templates/domains/{domain}/template.html`
286
+ 2. Default: `templates/template.html`
287
+ 3. Base: Package default templates
288
+
289
+ ### Template Functions
290
+
291
+ **Entity Rendering:**
292
+ ```html
293
+ <entity name="cmsBlocks" field="name" value="header-main"/>
294
+ <entity name="articles" id="123"/>
295
+ ```
296
+
297
+ **Collection Loops:**
298
+ ```html
299
+ <collection name="articles" filters="{featured: true}" data="{limit: 5, sortBy: 'created_at', sortDirection: 'desc'}">
300
+ <div class="article">
301
+ <h3>{{row.title}}</h3>
302
+ <p>{{row.summary}}</p>
303
+ </div>
304
+ </collection>
305
+ ```
306
+
307
+ **Pagination:**
308
+ ```html
309
+ <collection name="articles" filters="{}" data="{limit: 10}" pagination="articles-list" container="pagedCollection" prevPages="2" nextPages="2">
310
+ <article>{{row.title}}</article>
311
+ </collection>
312
+ ```
313
+
314
+ **Dynamic Forms:**
315
+ ```html
316
+ <cmsForm key="contactForm" fields="name,email,message" submitButtonText="Send Message"/>
317
+ ```
318
+
319
+ **Partials (HTML-style):**
320
+ ```html
321
+ <partial name="hero"
322
+ title="Welcome"
323
+ subtitle="To our site"
324
+ imageUrl="/img/hero.jpg"/>
325
+ ```
326
+
327
+ **Partials (Mustache-style):**
328
+ ```html
329
+ {{>cardView -{row}-}}
330
+ {{>hero -{title: "Welcome", subtitle: "To our site"}-}}
331
+ ```
332
+
333
+ **System Variables:**
334
+ ```html
335
+ {{currentRequest.host}}
336
+ {{currentRequest.path}}
337
+ {{currentRoute.title}}
338
+ {{currentDomain.current}}
339
+ {{systemInfo.timestamp}}
340
+ {{currentEntity.title}} <!-- In child blocks -->
341
+ ```
342
+
343
+ **Template Functions:**
344
+ ```html
345
+ [url(/articles)] <!-- URL generation -->
346
+ [asset(/img/logo.png)] <!-- Asset URLs -->
347
+ [date(now, Y-m-d)] <!-- Date formatting -->
348
+ [translate(welcome.message)] <!-- i18n -->
349
+ [t(key, Default, {var: value})] <!-- i18n with interpolation -->
350
+ ```
351
+
352
+ ## Configuration
353
+
354
+ ### Environment Variables (.env)
355
+ ```bash
356
+ # Server
357
+ RELDENS_APP_HOST=http://localhost
358
+ RELDENS_APP_PORT=8080
359
+
360
+ # Admin
361
+ RELDENS_ADMIN_ROUTE_PATH=/admin
362
+ RELDENS_ADMIN_SECRET=your-secret-key
363
+
364
+ # Database
365
+ RELDENS_DB_CLIENT=mysql
366
+ RELDENS_DB_HOST=localhost
367
+ RELDENS_DB_PORT=3306
368
+ RELDENS_DB_NAME=cms_db
369
+ RELDENS_DB_USER=username
370
+ RELDENS_DB_PASSWORD=password
371
+ RELDENS_STORAGE_DRIVER=prisma
372
+
373
+ # Multi-domain
374
+ RELDENS_DEFAULT_DOMAIN=example.com
375
+ RELDENS_DOMAIN_MAPPING={"dev.example.com":"development"}
376
+ RELDENS_SITE_KEY_MAPPING={"example.com":"main"}
377
+ RELDENS_DOMAIN_PUBLIC_URL_MAPPING={"example.com":"https://cdn.example.com"}
378
+ RELDENS_DOMAIN_CDN_MAPPING={"example.com":"https://cdn.example.com"}
379
+ ```
380
+
381
+ ### Manager Configuration
382
+ ```javascript
383
+ const { Manager } = require('@reldens/cms');
384
+
385
+ const cms = new Manager({
386
+ projectRoot: process.cwd(),
387
+
388
+ // Entity access control
389
+ entityAccess: {
390
+ articles: { public: true, operations: ['read'] },
391
+ cmsPages: { public: true, operations: ['read'] },
392
+ users: { public: false }
393
+ },
394
+
395
+ // Authentication
396
+ authenticationMethod: 'db-users', // or 'custom'
397
+ authenticationCallback: async (email, password, roleId) => {
398
+ // Custom auth logic
399
+ },
400
+ adminRoleId: 99,
401
+
402
+ // Performance
403
+ cache: true,
404
+ reloadTime: -1, // Development: reload on every request
405
+ // reloadTime: 0, // Production: disable reloading
406
+
407
+ // Multi-domain
408
+ defaultDomain: 'example.com',
409
+ domainMapping: {'dev.example.com': 'development'},
410
+ siteKeyMapping: {'example.com': 'main'},
411
+
412
+ // Custom entities and translations
413
+ entitiesConfig: {},
414
+ entitiesTranslations: {},
415
+ adminTranslations: {}
416
+ });
417
+
418
+ await cms.start();
419
+ ```
420
+
421
+ ## Event System
422
+
423
+ The CMS provides extensive event hooks for customization:
424
+
425
+ ### Manager Events
426
+ - `reldens.cmsManagerInitializeServices` - Before service initialization
427
+ - `reldens.manager.initializeAdminManager` - Before admin initialization
428
+
429
+ ### Template Events
430
+ - `reldens.afterVariablesCreated` - Modify system variables
431
+ - `reldens.beforeContentProcess` - Before template processing
432
+ - `reldens.afterContentProcess` - After template processing
433
+
434
+ ### Form Events
435
+ - `reldens.formsTransformer.beforeRender` - Before form rendering
436
+ - `reldens.formsTransformer.afterRender` - After form rendering
437
+ - `reldens.dynamicForm.beforeValidation` - Before validation
438
+ - `reldens.dynamicForm.afterValidation` - After validation
439
+ - `reldens.dynamicForm.beforeSave` - Before saving
440
+ - `reldens.dynamicForm.afterSave` - After successful save
441
+ - `reldens.dynamicFormRequestHandler.beforeSave` - Before request save
442
+
443
+ ### Admin Events
444
+ - `reldens.setupAdminRouter` - Setup admin routes
445
+ - `reldens.setupAdminRoutes` - After route setup
446
+ - `reldens.setupAdminManagers` - After manager setup
447
+
448
+ ### Template Reloading Events
449
+ - `reldens.templateReloader.templatesChanged` - Templates changed
450
+
451
+ ## Development Workflow
452
+
453
+ ### Template Reloading
454
+ Set `reloadTime: -1` in Manager configuration for development:
455
+ - Admin templates reload automatically when files change
456
+ - Frontend templates reload on next page load
457
+ - No server restart needed
458
+ - Zero performance impact in production (`reloadTime: 0`)
459
+
460
+ ### Entity Generation
461
+ ```bash
462
+ # Generate entities from database schema
463
+ npx reldens-cms-generate-entities
464
+
465
+ # Or programmatically
466
+ await dataServer.generateEntities();
467
+ ```
468
+
469
+ ### Custom Entities
470
+ Define custom entity configurations in `entitiesConfig`:
471
+ ```javascript
472
+ {
473
+ articles: {
474
+ listProperties: ['title', 'status', 'created_at'],
475
+ showProperties: ['title', 'content', 'author'],
476
+ editProperties: ['title', 'content', 'author_id'],
477
+ filterProperties: ['status', 'author_id'],
478
+ titleProperty: 'title',
479
+ parentItemLabel: 'Content',
480
+ properties: {
481
+ title: { type: 'string', isRequired: true },
482
+ content: { type: 'text' },
483
+ author_id: { type: 'reference', reference: 'users' },
484
+ featured_image: {
485
+ type: 'string',
486
+ isUpload: true,
487
+ allowedTypes: 'image',
488
+ bucket: 'uploads'
489
+ }
490
+ }
491
+ }
492
+ }
493
+ ```
494
+
495
+ ## Security Features
496
+
497
+ - **Authentication** - Role-based admin access
498
+ - **CSRF Protection** - Via session tokens
499
+ - **File Upload Validation** - MIME type and extension checking
500
+ - **Entity Access Control** - Public/private entity rules
501
+ - **Honeypot Protection** - Bot detection in forms
502
+ - **Rate Limiting** - Via @reldens/server-utils
503
+ - **XSS Protection** - Input sanitization via @reldens/server-utils
504
+ - **SQL Injection Prevention** - Via Prisma ORM
505
+ - **Path Validation** - File path security
506
+ - **CSP Headers** - Content Security Policy via Helmet
507
+ - **HTTPS Support** - SSL/TLS configuration
508
+
509
+ ## Important Implementation Notes
510
+
511
+ 1. **Always use specialized tools over bash** for file operations (Read, Edit, Write)
512
+ 2. **Template resolution follows domain fallback** - check domain-specific templates first
513
+ 3. **Entity access is controlled** via `entities_access` table - respect public/private flags
514
+ 4. **Template functions are case-sensitive** - use exact syntax
515
+ 5. **Collection pagination uses URL parameters** - preserve query strings
516
+ 6. **Form schemas are JSON** - validate JSON structure
517
+ 7. **System variables are always available** - no need to pass them manually
518
+ 8. **Event hooks are async** - use await when emitting events
519
+ 9. **Template reloading is development-only** - disable in production
520
+ 10. **Multi-domain requires proper configuration** - set up domain mapping correctly
521
+
522
+ ## Common File Paths
523
+
524
+ - **Admin templates:** `admin/templates/`
525
+ - **Frontend templates:** `templates/`
526
+ - **Domain templates:** `templates/domains/{domain}/`
527
+ - **Entities:** `entities/` (generated)
528
+ - **Public assets:** `public/`
529
+ - **Environment:** `.env`
530
+ - **Install lock:** `install.lock`
531
+
532
+ ## Troubleshooting
533
+
534
+ ### Installation Issues
535
+ - Check database connection in `.env`
536
+ - Ensure Prisma schema is valid
537
+ - Verify Node.js version >= 20.0.0
538
+
539
+ ### Template Issues
540
+ - Check template resolution order
541
+ - Verify domain mapping configuration
542
+ - Enable template reloading for development
543
+
544
+ ### Form Issues
545
+ - Validate JSON schema syntax
546
+ - Check form key matches database
547
+ - Verify field names in schema
548
+
549
+ ### Entity Issues
550
+ - Regenerate entities after schema changes
551
+ - Check entity access configuration
552
+ - Verify relationship mappings
553
+
554
+ ## Dependencies
555
+
556
+ - **@reldens/storage** - Database abstraction layer
557
+ - **@reldens/server-utils** - Server utilities (AppServerFactory, FileHandler, Encryptor)
558
+ - **@reldens/utils** - Common utilities (EventsManager, Logger, SchemaValidator)
559
+ - **dotenv** - Environment variable management
560
+ - **mustache** - Template engine
561
+
562
+ ## Additional Resources
563
+
564
+ - Main README.md for user documentation
565
+ - Package.json for dependency versions
566
+ - License: MIT
@@ -25,7 +25,7 @@ class AddCacheButtonSubscriber
25
25
  setupEvents()
26
26
  {
27
27
  if(!this.cacheManager){
28
- Logger.error('Cache Manager not found on AddCacheButtonSubscriber.');
28
+ Logger.debug('Cache Manager not found on AddCacheButtonSubscriber.');
29
29
  return false;
30
30
  }
31
31
  if(!this.cacheManager.isEnabled()){
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@reldens/cms",
3
3
  "scope": "@reldens",
4
- "version": "0.40.0",
4
+ "version": "0.42.0",
5
5
  "description": "Reldens - CMS",
6
6
  "author": "Damian A. Pastorini",
7
7
  "license": "MIT",
@@ -33,9 +33,9 @@
33
33
  "url": "https://github.com/damian-pastorini/reldens-cms/issues"
34
34
  },
35
35
  "dependencies": {
36
- "@reldens/server-utils": "^0.39.0",
37
- "@reldens/storage": "^0.76.0",
38
- "@reldens/utils": "^0.53.0",
36
+ "@reldens/server-utils": "^0.40.0",
37
+ "@reldens/storage": "^0.77.0",
38
+ "@reldens/utils": "^0.54.0",
39
39
  "dotenv": "17.2.3",
40
40
  "mustache": "4.2.0"
41
41
  }