@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,223 @@
1
+ # Advanced Installation Guide
2
+
3
+ ## Subprocess Installation Handling
4
+
5
+ The installer supports complex operations through subprocess management:
6
+
7
+ ```javascript
8
+ const { Installer } = require('@reldens/cms');
9
+
10
+ const installer = new Installer({
11
+ projectRoot: process.cwd(),
12
+ subprocessMaxAttempts: 1800,
13
+ postInstallCallback: async (props) => {
14
+ console.log('Entities loaded:', Object.keys(props.loadedEntities.rawRegisteredEntities));
15
+ return true;
16
+ }
17
+ });
18
+ ```
19
+
20
+ **The installer automatically handles:**
21
+
22
+ - Package dependency checking and installation
23
+ - Database schema creation via subprocess
24
+ - Prisma client generation with progress tracking
25
+ - Entity generation with validation
26
+ - Environment file creation
27
+ - Directory structure setup
28
+
29
+ ## Enhanced Manager Initialization
30
+
31
+ The Manager class provides comprehensive service initialization:
32
+
33
+ ```javascript
34
+ const cms = new Manager({
35
+ app: customExpressApp,
36
+ appServer: customAppServer,
37
+ dataServer: customDataServer,
38
+ adminManager: customAdmin,
39
+ frontend: customFrontend,
40
+ adminRoleId: 99,
41
+ authenticationMethod: 'db-users',
42
+ authenticationCallback: async (email, password, roleId) => {
43
+ return await yourAuthService.validate(email, password, roleId);
44
+ },
45
+ cache: true,
46
+ reloadTime: -1,
47
+ defaultDomain: 'example.com',
48
+ domainMapping: {'dev.example.com': 'development'},
49
+ siteKeyMapping: {'example.com': 'main'}
50
+ });
51
+ ```
52
+
53
+ **Manager automatically:**
54
+
55
+ - Validates all provided instances
56
+ - Initializes missing services
57
+ - Sets up entity access control
58
+ - Generates admin entities
59
+ - Configures template reloading
60
+
61
+ ## Development Mode Detection
62
+
63
+ The CMS automatically detects development environments based on domain patterns.
64
+
65
+ **Default Development Patterns:**
66
+
67
+ ```javascript
68
+ const patterns = [
69
+ 'localhost',
70
+ '127.0.0.1',
71
+ '.local',
72
+ '.test',
73
+ '.dev',
74
+ '.acc',
75
+ '.staging',
76
+ 'local.',
77
+ 'test.',
78
+ 'dev.',
79
+ 'acc.',
80
+ 'staging.'
81
+ ];
82
+ ```
83
+
84
+ **Override Development Patterns:**
85
+
86
+ ```javascript
87
+ const cms = new Manager({
88
+ developmentPatterns: [
89
+ 'localhost',
90
+ '127.0.0.1',
91
+ '.local'
92
+ ],
93
+ domainMapping: {
94
+ 'www.example.com': 'example.com',
95
+ 'new.example.com': 'example.com'
96
+ }
97
+ });
98
+ ```
99
+
100
+ **Important Notes:**
101
+
102
+ - Domain patterns only match at the start or end of domains, not arbitrary positions
103
+ - Override `developmentPatterns` in production to prevent staging/acc domains from enabling development mode
104
+
105
+ ## Security Configuration
106
+
107
+ ### External Domains for CSP
108
+
109
+ Configure external domains for CSP directives (kebab-case or camelCase):
110
+
111
+ ```javascript
112
+ const cms = new Manager({
113
+ appServerConfig: {
114
+ developmentExternalDomains: {
115
+ 'scriptSrc': ['https://cdn.example.com'],
116
+ 'script-src': ['https://analytics.example.com'],
117
+ 'styleSrc': ['https://fonts.googleapis.com'],
118
+ 'font-src': ['https://fonts.gstatic.com']
119
+ }
120
+ }
121
+ });
122
+ ```
123
+
124
+ **The system automatically:**
125
+
126
+ - Converts kebab-case keys to camelCase
127
+ - Adds domains to both the base directive and the -elem variant
128
+
129
+ ### CSP Directive Merging vs Override
130
+
131
+ **Default (merge with base directives):**
132
+
133
+ ```javascript
134
+ const cms = new Manager({
135
+ appServerConfig: {
136
+ helmetConfig: {
137
+ contentSecurityPolicy: {
138
+ directives: {
139
+ scriptSrc: ['https://cdn.example.com']
140
+ }
141
+ }
142
+ }
143
+ }
144
+ });
145
+ ```
146
+
147
+ **Default Base Directives:**
148
+
149
+ ```javascript
150
+ {
151
+ defaultSrc: ["'self'"],
152
+ scriptSrc: ["'self'"],
153
+ scriptSrcElem: ["'self'"],
154
+ styleSrc: ["'self'", "'unsafe-inline'"],
155
+ styleSrcElem: ["'self'", "'unsafe-inline'"],
156
+ imgSrc: ["'self'", "data:", "https:"],
157
+ fontSrc: ["'self'"],
158
+ connectSrc: ["'self'"],
159
+ frameAncestors: ["'none'"],
160
+ baseUri: ["'self'"],
161
+ formAction: ["'self'"]
162
+ }
163
+ ```
164
+
165
+ **Complete Replacement:**
166
+
167
+ ```javascript
168
+ const cms = new Manager({
169
+ appServerConfig: {
170
+ helmetConfig: {
171
+ contentSecurityPolicy: {
172
+ overrideDirectives: true,
173
+ directives: {
174
+ defaultSrc: ["'self'"],
175
+ scriptSrc: ["'self'", "https://trusted-cdn.com"],
176
+ styleSrc: ["'self'", "'unsafe-inline'"],
177
+ imgSrc: ["'self'", "data:", "https:"],
178
+ fontSrc: ["'self'"],
179
+ connectSrc: ["'self'"],
180
+ frameAncestors: ["'none'"],
181
+ baseUri: ["'self'"],
182
+ formAction: ["'self'"]
183
+ }
184
+ }
185
+ }
186
+ }
187
+ });
188
+ ```
189
+
190
+ ### Additional Helmet Security Headers
191
+
192
+ ```javascript
193
+ const cms = new Manager({
194
+ appServerConfig: {
195
+ helmetConfig: {
196
+ hsts: {
197
+ maxAge: 31536000,
198
+ includeSubDomains: true,
199
+ preload: true
200
+ },
201
+ crossOriginOpenerPolicy: {
202
+ policy: "same-origin"
203
+ },
204
+ crossOriginResourcePolicy: {
205
+ policy: "same-origin"
206
+ },
207
+ crossOriginEmbedderPolicy: {
208
+ policy: "require-corp"
209
+ }
210
+ }
211
+ }
212
+ });
213
+ ```
214
+
215
+ **Note:** In development mode, CSP and HSTS are automatically disabled. Security headers are only enforced in production.
216
+
217
+ **Trusted Types:** To enable Trusted Types for enhanced XSS protection:
218
+
219
+ ```javascript
220
+ requireTrustedTypesFor: ["'script'"]
221
+ ```
222
+
223
+ However, this requires updating all JavaScript code to use the Trusted Types API.
@@ -0,0 +1,178 @@
1
+ # Multi-Domain and Internationalization Guide
2
+
3
+ ## Internationalization
4
+
5
+ ### Translation Files
6
+
7
+ Create translation files in the `translations` directory:
8
+
9
+ **translations/en.json:**
10
+
11
+ ```json
12
+ {
13
+ "navigation": {
14
+ "home": "Home",
15
+ "about": "About Us",
16
+ "contact": "Contact"
17
+ },
18
+ "messages": {
19
+ "welcome": "Welcome to our site!",
20
+ "greeting": "Hello {name}!"
21
+ }
22
+ }
23
+ ```
24
+
25
+ **translations/es.json:**
26
+
27
+ ```json
28
+ {
29
+ "navigation": {
30
+ "home": "Inicio",
31
+ "about": "Acerca de",
32
+ "contact": "Contacto"
33
+ },
34
+ "messages": {
35
+ "welcome": "¡Bienvenido a nuestro sitio!",
36
+ "greeting": "¡Hola {name}!"
37
+ }
38
+ }
39
+ ```
40
+
41
+ ### Using Translations in Templates
42
+
43
+ ```html
44
+ [translate(navigation.home)]
45
+ [t(navigation.home, Home)]
46
+ [t(messages.greeting, Hello!, {name: John})]
47
+ ```
48
+
49
+ Locale detection from request headers or ?locale=es parameter.
50
+
51
+ ## Multi-Domain Setup
52
+
53
+ ### Directory Structure
54
+
55
+ ```
56
+ templates/
57
+ ├── layouts/
58
+ │ ├── default.html
59
+ │ ├── full-width.html
60
+ │ └── minimal.html
61
+ ├── domains/
62
+ │ ├── example.com/
63
+ │ │ ├── layouts/
64
+ │ │ ├── partials/
65
+ │ │ │ ├── header.html
66
+ │ │ │ └── footer.html
67
+ │ │ ├── cms_forms/
68
+ │ │ │ ├── form.html
69
+ │ │ │ └── field_text.html
70
+ │ │ ├── page.html
71
+ │ │ └── index.html
72
+ │ └── dev.example.com/
73
+ │ └── page.html
74
+ ├── partials/
75
+ │ ├── header.html (default)
76
+ │ └── footer.html (default)
77
+ ├── cms_forms/
78
+ │ ├── form.html
79
+ │ ├── field_text.html
80
+ │ └── field_email.html
81
+ ├── translations/
82
+ │ ├── en.json
83
+ │ ├── es.json
84
+ │ └── fr.json
85
+ ├── page.html (base HTML wrapper)
86
+ └── 404.html
87
+ ```
88
+
89
+ ### Template Resolution Order
90
+
91
+ 1. Domain-specific: `templates/domains/{domain}/template.html`
92
+ 2. Default: `templates/template.html`
93
+ 3. Base: Package default templates
94
+
95
+ ### Configuration
96
+
97
+ ```javascript
98
+ const cms = new Manager({
99
+ defaultDomain: 'example.com',
100
+ domainMapping: {'dev.example.com': 'development'},
101
+ siteKeyMapping: {'example.com': 'main'}
102
+ });
103
+ ```
104
+
105
+ ## Layout System
106
+
107
+ The CMS uses a two-tier layout system:
108
+
109
+ **page.html - Full HTML wrapper:**
110
+
111
+ ```html
112
+ <!DOCTYPE html>
113
+ <html lang="{{locale}}">
114
+ <head>
115
+ <title>{{title}}</title>
116
+ <meta name="description" content="{{description}}"/>
117
+ <link href="[url(/css/styles.css)]" rel="stylesheet"/>
118
+ </head>
119
+ <body class="{{siteHandle}}">
120
+ {{&content}}
121
+ <script src="[url(/js/scripts.js)]"></script>
122
+ </body>
123
+ </html>
124
+ ```
125
+
126
+ **layouts/default.html - Body content only:**
127
+
128
+ ```html
129
+ <entity name="cmsBlocks" field="name" value="header-main"/>
130
+
131
+ <main id="main" class="main-container">
132
+ <div class="container">
133
+ <div class="row">
134
+ <div class="col-md-3">
135
+ <entity name="cmsBlocks" field="name" value="sidebar-left"/>
136
+ </div>
137
+ <div class="col-md-9">
138
+ {{&content}}
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </main>
143
+
144
+ <entity name="cmsBlocks" field="name" value="footer-main"/>
145
+ ```
146
+
147
+ **Available Layouts:**
148
+
149
+ Pages can use different layouts by setting the `layout` field in `cms_pages`:
150
+
151
+ - `default` - Header, sidebar, main content, footer
152
+ - `full-width` - Full width without sidebars
153
+ - `minimal` - Basic layout with minimal styling
154
+
155
+ ## Content Blocks
156
+
157
+ Create reusable content blocks in the `cms_blocks` table via admin panel:
158
+
159
+ ```sql
160
+ INSERT INTO cms_blocks (name, title, content) VALUES
161
+ ('contact-info', 'Contact Information', '<p>Email: info@example.com</p>'),
162
+ ('article-sidebar', 'Article Categories',
163
+ '<div class="categories"><h3>Categories</h3><ul><li><a href="[url(/articles/technology)]">Technology</a></li></ul></div>');
164
+ ```
165
+
166
+ ## Entity Access Control
167
+
168
+ Control which entities are publicly accessible:
169
+
170
+ ```javascript
171
+ const cms = new Manager({
172
+ entityAccess: {
173
+ articles: { public: true, operations: ['read'] },
174
+ cmsPages: { public: true, operations: ['read'] },
175
+ users: { public: false }
176
+ }
177
+ });
178
+ ```