slicejs-web-framework 4.0.2 → 4.1.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 (73) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +97 -97
  3. package/Slice/Components/Structural/ContextManager/ContextManager.js +422 -422
  4. package/Slice/Components/Structural/ContextManager/ContextManagerDebugger.js +470 -470
  5. package/Slice/Components/Structural/Controller/Controller.js +1406 -1406
  6. package/Slice/Components/Structural/Controller/allowedValuesValidation.js +52 -52
  7. package/Slice/Components/Structural/Debugger/Debugger.html +72 -72
  8. package/Slice/Components/Structural/Debugger/Debugger.js +1505 -1505
  9. package/Slice/Components/Structural/EventManager/EventManager.js +651 -651
  10. package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +985 -985
  11. package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -296
  12. package/Slice/Components/Structural/Logger/Log.js +10 -10
  13. package/Slice/Components/Structural/Logger/LogViewer/LogViewer.js +662 -662
  14. package/Slice/Components/Structural/Logger/Logger.js +225 -225
  15. package/Slice/Components/Structural/Router/Router.js +820 -810
  16. package/Slice/Components/Structural/Router/applyRouteMetadata.js +39 -0
  17. package/Slice/Components/Structural/StylesManager/StylesManager.js +82 -82
  18. package/Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +175 -175
  19. package/Slice/Slice.js +711 -710
  20. package/api/framework/devDepsOptimizer.js +335 -335
  21. package/api/framework/express.js +3 -3
  22. package/api/framework/precompressedStatic.js +102 -93
  23. package/api/framework/publicEnvResolver.js +123 -123
  24. package/api/framework/securityMiddleware.js +197 -197
  25. package/api/framework/seo.js +387 -0
  26. package/api/framework/server.js +777 -410
  27. package/api/index.js +14 -4
  28. package/package.json +6 -2
  29. package/sliceConfig.schema.json +122 -122
  30. package/src/App/index.html +69 -69
  31. package/src/App/index.js +20 -20
  32. package/src/App/style.css +11 -11
  33. package/src/Components/AppComponents/AboutSection/AboutSection.css +9 -9
  34. package/src/Components/AppComponents/AboutSection/AboutSection.html +8 -8
  35. package/src/Components/AppComponents/AboutSection/AboutSection.js +12 -12
  36. package/src/Components/AppComponents/AppShell/AppShell.css +10 -10
  37. package/src/Components/AppComponents/AppShell/AppShell.html +4 -4
  38. package/src/Components/AppComponents/AppShell/AppShell.js +36 -36
  39. package/src/Components/AppComponents/HomeSection/HomeSection.css +20 -20
  40. package/src/Components/AppComponents/HomeSection/HomeSection.html +10 -10
  41. package/src/Components/AppComponents/HomeSection/HomeSection.js +19 -19
  42. package/src/Components/components.js +8 -8
  43. package/src/public/Styles/sliceStyles.css +34 -34
  44. package/src/public/Themes/Dark.css +42 -42
  45. package/src/public/Themes/Light.css +31 -31
  46. package/src/public/Themes/Slice.css +47 -47
  47. package/src/public/manifest.json +15 -15
  48. package/src/public/robots.txt +4 -4
  49. package/src/public/sitemap.xml +8 -8
  50. package/src/routes.js +9 -9
  51. package/src/sliceConfig.json +72 -72
  52. package/types/index.d.ts +219 -219
  53. package/.opencode/opencode.json +0 -15
  54. package/Slice/tests/build-bundled-component-without-category.test.js +0 -103
  55. package/Slice/tests/build-js-only-visual-components.test.js +0 -144
  56. package/Slice/tests/build-singleton.test.js +0 -244
  57. package/Slice/tests/bundle-v2-runtime-contract.test.js +0 -747
  58. package/Slice/tests/context-patch-use.test.js +0 -95
  59. package/Slice/tests/destroy-cascade.test.js +0 -215
  60. package/Slice/tests/event-emitters.test.js +0 -79
  61. package/Slice/tests/event-registry.test.js +0 -141
  62. package/Slice/tests/fixtures/real-runtime-loader.mjs +0 -21
  63. package/Slice/tests/leak-orphans.test.js +0 -131
  64. package/Slice/tests/props-allowed-values-validation.test.js +0 -119
  65. package/Slice/tests/public-env-runtime-accessors.test.js +0 -44
  66. package/Slice/tests/public-env-typed-accessors.test.js +0 -66
  67. package/Slice/tests/router-loading-finally.test.js +0 -68
  68. package/api/tests/dev-deps-optimizer.test.js +0 -137
  69. package/api/tests/dev-server-external.test.js +0 -56
  70. package/api/tests/precompressed-static.test.js +0 -119
  71. package/api/tests/public-env-resolver.test.js +0 -193
  72. package/tests/router-build-failure.test.js +0 -125
  73. package/tests/router-emit-ordering.test.js +0 -63
@@ -1,197 +1,197 @@
1
- // api/framework/securityMiddleware.js
2
- import path from 'path';
3
-
4
- /**
5
- * Middleware de seguridad para prevenir acceso directo malicioso
6
- * pero permitir que la aplicación cargue sus dependencias normalmente
7
- */
8
- export function securityMiddleware(options = {}) {
9
- const {
10
- allowedExtensions = [
11
- '.js', '.mjs', '.cjs',
12
- '.css',
13
- '.html', '.htm',
14
- '.json',
15
- '.svg', '.png', '.jpg', '.jpeg', '.gif', '.webp', '.avif', '.ico',
16
- '.woff', '.woff2', '.ttf', '.otf', '.eot',
17
- '.txt', '.xml', '.pdf',
18
- '.webm', '.mp4', '.mp3', '.wav', '.ogg',
19
- '.wasm'
20
- ],
21
- blockedPaths = [
22
- '/node_modules',
23
- '/package.json',
24
- '/package-lock.json',
25
- '/.env',
26
- '/.git'
27
- ],
28
- allowPublicAssets = true,
29
- publicPaths = ['/assets', '/public', '/images', '/styles']
30
- } = options;
31
-
32
- return (req, res, next) => {
33
- const requestPath = req.path;
34
-
35
- // 1. Bloquear acceso a rutas definitivamente sensibles (configuración, dependencias)
36
- const isBlockedPath = blockedPaths.some(blocked =>
37
- requestPath.startsWith(blocked) || requestPath.includes(blocked)
38
- );
39
-
40
- if (isBlockedPath) {
41
- console.warn(`🚫 Blocked access to sensitive path: ${requestPath}`);
42
- return res.status(403).json({
43
- error: 'Forbidden',
44
- message: 'Access to this resource is not allowed',
45
- path: requestPath
46
- });
47
- }
48
-
49
- // 2. Permitir acceso a assets públicos (servidos desde src/public/)
50
- if (allowPublicAssets) {
51
- const isPublicAsset = publicPaths.some(publicPath =>
52
- requestPath.startsWith(publicPath)
53
- );
54
-
55
- if (isPublicAsset) {
56
- return next();
57
- }
58
- }
59
-
60
- // 3. Validar extensiones de archivo
61
- const fileExtension = path.extname(requestPath).toLowerCase();
62
-
63
- if (fileExtension && !allowedExtensions.includes(fileExtension)) {
64
- console.warn(`🚫 Blocked file type: ${requestPath}`);
65
- return res.status(403).json({
66
- error: 'Forbidden',
67
- message: 'File type not allowed',
68
- extension: fileExtension
69
- });
70
- }
71
-
72
- // 4. Prevenir path traversal attacks
73
- const normalizedPath = path.normalize(requestPath);
74
- if (normalizedPath.includes('..') || normalizedPath.includes('~')) {
75
- console.warn(`🚫 Path traversal attempt: ${requestPath}`);
76
- return res.status(403).json({
77
- error: 'Forbidden',
78
- message: 'Invalid path',
79
- path: requestPath
80
- });
81
- }
82
-
83
- // Todo está bien, continuar
84
- next();
85
- };
86
- }
87
-
88
- /**
89
- * Middleware específico para proteger archivos del framework Slice.js
90
- * PERMITE acceso cuando viene desde la propia aplicación (Referer válido)
91
- * BLOQUEA acceso directo desde navegador o herramientas externas
92
- */
93
- export function sliceFrameworkProtection(options = {}) {
94
- const {
95
- port = 3000,
96
- strictMode = false,
97
- allowedDomains = [] // Dominios personalizados permitidos
98
- } = options;
99
-
100
- return (req, res, next) => {
101
- const requestPath = req.path;
102
-
103
- // Rutas del framework que requieren verificación
104
- const frameworkPaths = [
105
- '/Slice/Components/Structural'
106
- ];
107
-
108
- const isFrameworkFile = frameworkPaths.some(fwPath =>
109
- requestPath.startsWith(fwPath)
110
- );
111
-
112
- if (!isFrameworkFile) {
113
- return next();
114
- }
115
-
116
- // Verificar el origen de la petición
117
- const referer = req.get('Referer') || req.get('Referrer');
118
- const origin = req.get('Origin');
119
- const host = req.get('Host');
120
-
121
- // Construir lista de orígenes válidos dinámicamente
122
- const validOrigins = [
123
- `http://localhost:${port}`,
124
- `http://127.0.0.1:${port}`,
125
- `http://0.0.0.0:${port}`,
126
- `https://localhost:${port}`,
127
- ...allowedDomains // Dominios personalizados del usuario
128
- ];
129
-
130
- // Si hay un Host header, agregarlo automáticamente
131
- if (host) {
132
- validOrigins.push(`http://${host}`);
133
- validOrigins.push(`https://${host}`);
134
- }
135
-
136
- // Verificar si la petición viene de un origen válido
137
- const hasValidReferer = referer && validOrigins.some(valid => referer.startsWith(valid));
138
- const hasValidOrigin = origin && validOrigins.some(valid => origin === valid);
139
- const isSameHost = host && referer && referer.includes(host);
140
-
141
- // Permitir si viene desde la aplicación
142
- if (hasValidReferer || hasValidOrigin || isSameHost) {
143
- return next();
144
- }
145
-
146
- // En modo estricto, bloquear todo acceso sin referer válido
147
- if (strictMode) {
148
- console.warn(`🚫 Blocked direct framework file access: ${requestPath}`);
149
- return res.status(403).json({
150
- error: 'Framework Protection',
151
- message: 'Direct access to Slice.js framework files is blocked',
152
- tip: 'Framework files must be loaded through the application',
153
- path: requestPath
154
- });
155
- }
156
-
157
- // En modo normal (desarrollo), permitir pero advertir
158
- console.warn(`⚠️ Framework file accessed without valid referer: ${requestPath}`);
159
- next();
160
- };
161
- }
162
-
163
- /**
164
- * Middleware para logging de peticiones sospechosas
165
- */
166
- export function suspiciousRequestLogger() {
167
- const suspiciousPatterns = [
168
- /\.\.\//, // Path traversal
169
- /~/, // Home directory access
170
- /\.env/, // Environment files
171
- /\.git/, // Git files
172
- /package\.json/, // Package files
173
- /package-lock\.json/,
174
- /node_modules/, // Dependencies
175
- ];
176
-
177
- return (req, res, next) => {
178
- const requestPath = req.path;
179
-
180
- const isSuspicious = suspiciousPatterns.some(pattern =>
181
- pattern.test(requestPath)
182
- );
183
-
184
- if (isSuspicious) {
185
- const clientIp = req.ip || req.connection.remoteAddress;
186
- console.warn(`⚠️ Suspicious request: ${requestPath} from ${clientIp}`);
187
- }
188
-
189
- next();
190
- };
191
- }
192
-
193
- export default {
194
- securityMiddleware,
195
- sliceFrameworkProtection,
196
- suspiciousRequestLogger
197
- };
1
+ // api/framework/securityMiddleware.js
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Middleware de seguridad para prevenir acceso directo malicioso
6
+ * pero permitir que la aplicación cargue sus dependencias normalmente
7
+ */
8
+ export function securityMiddleware(options = {}) {
9
+ const {
10
+ allowedExtensions = [
11
+ '.js', '.mjs', '.cjs',
12
+ '.css',
13
+ '.html', '.htm',
14
+ '.json',
15
+ '.svg', '.png', '.jpg', '.jpeg', '.gif', '.webp', '.avif', '.ico',
16
+ '.woff', '.woff2', '.ttf', '.otf', '.eot',
17
+ '.txt', '.xml', '.pdf',
18
+ '.webm', '.mp4', '.mp3', '.wav', '.ogg',
19
+ '.wasm'
20
+ ],
21
+ blockedPaths = [
22
+ '/node_modules',
23
+ '/package.json',
24
+ '/package-lock.json',
25
+ '/.env',
26
+ '/.git'
27
+ ],
28
+ allowPublicAssets = true,
29
+ publicPaths = ['/assets', '/public', '/images', '/styles']
30
+ } = options;
31
+
32
+ return (req, res, next) => {
33
+ const requestPath = req.path;
34
+
35
+ // 1. Bloquear acceso a rutas definitivamente sensibles (configuración, dependencias)
36
+ const isBlockedPath = blockedPaths.some(blocked =>
37
+ requestPath.startsWith(blocked) || requestPath.includes(blocked)
38
+ );
39
+
40
+ if (isBlockedPath) {
41
+ console.warn(`🚫 Blocked access to sensitive path: ${requestPath}`);
42
+ return res.status(403).json({
43
+ error: 'Forbidden',
44
+ message: 'Access to this resource is not allowed',
45
+ path: requestPath
46
+ });
47
+ }
48
+
49
+ // 2. Permitir acceso a assets públicos (servidos desde src/public/)
50
+ if (allowPublicAssets) {
51
+ const isPublicAsset = publicPaths.some(publicPath =>
52
+ requestPath.startsWith(publicPath)
53
+ );
54
+
55
+ if (isPublicAsset) {
56
+ return next();
57
+ }
58
+ }
59
+
60
+ // 3. Validar extensiones de archivo
61
+ const fileExtension = path.extname(requestPath).toLowerCase();
62
+
63
+ if (fileExtension && !allowedExtensions.includes(fileExtension)) {
64
+ console.warn(`🚫 Blocked file type: ${requestPath}`);
65
+ return res.status(403).json({
66
+ error: 'Forbidden',
67
+ message: 'File type not allowed',
68
+ extension: fileExtension
69
+ });
70
+ }
71
+
72
+ // 4. Prevenir path traversal attacks
73
+ const normalizedPath = path.normalize(requestPath);
74
+ if (normalizedPath.includes('..') || normalizedPath.includes('~')) {
75
+ console.warn(`🚫 Path traversal attempt: ${requestPath}`);
76
+ return res.status(403).json({
77
+ error: 'Forbidden',
78
+ message: 'Invalid path',
79
+ path: requestPath
80
+ });
81
+ }
82
+
83
+ // Todo está bien, continuar
84
+ next();
85
+ };
86
+ }
87
+
88
+ /**
89
+ * Middleware específico para proteger archivos del framework Slice.js
90
+ * PERMITE acceso cuando viene desde la propia aplicación (Referer válido)
91
+ * BLOQUEA acceso directo desde navegador o herramientas externas
92
+ */
93
+ export function sliceFrameworkProtection(options = {}) {
94
+ const {
95
+ port = 3000,
96
+ strictMode = false,
97
+ allowedDomains = [] // Dominios personalizados permitidos
98
+ } = options;
99
+
100
+ return (req, res, next) => {
101
+ const requestPath = req.path;
102
+
103
+ // Rutas del framework que requieren verificación
104
+ const frameworkPaths = [
105
+ '/Slice/Components/Structural'
106
+ ];
107
+
108
+ const isFrameworkFile = frameworkPaths.some(fwPath =>
109
+ requestPath.startsWith(fwPath)
110
+ );
111
+
112
+ if (!isFrameworkFile) {
113
+ return next();
114
+ }
115
+
116
+ // Verificar el origen de la petición
117
+ const referer = req.get('Referer') || req.get('Referrer');
118
+ const origin = req.get('Origin');
119
+ const host = req.get('Host');
120
+
121
+ // Construir lista de orígenes válidos dinámicamente
122
+ const validOrigins = [
123
+ `http://localhost:${port}`,
124
+ `http://127.0.0.1:${port}`,
125
+ `http://0.0.0.0:${port}`,
126
+ `https://localhost:${port}`,
127
+ ...allowedDomains // Dominios personalizados del usuario
128
+ ];
129
+
130
+ // Si hay un Host header, agregarlo automáticamente
131
+ if (host) {
132
+ validOrigins.push(`http://${host}`);
133
+ validOrigins.push(`https://${host}`);
134
+ }
135
+
136
+ // Verificar si la petición viene de un origen válido
137
+ const hasValidReferer = referer && validOrigins.some(valid => referer.startsWith(valid));
138
+ const hasValidOrigin = origin && validOrigins.some(valid => origin === valid);
139
+ const isSameHost = host && referer && referer.includes(host);
140
+
141
+ // Permitir si viene desde la aplicación
142
+ if (hasValidReferer || hasValidOrigin || isSameHost) {
143
+ return next();
144
+ }
145
+
146
+ // En modo estricto, bloquear todo acceso sin referer válido
147
+ if (strictMode) {
148
+ console.warn(`🚫 Blocked direct framework file access: ${requestPath}`);
149
+ return res.status(403).json({
150
+ error: 'Framework Protection',
151
+ message: 'Direct access to Slice.js framework files is blocked',
152
+ tip: 'Framework files must be loaded through the application',
153
+ path: requestPath
154
+ });
155
+ }
156
+
157
+ // En modo normal (desarrollo), permitir pero advertir
158
+ console.warn(`⚠️ Framework file accessed without valid referer: ${requestPath}`);
159
+ next();
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Middleware para logging de peticiones sospechosas
165
+ */
166
+ export function suspiciousRequestLogger() {
167
+ const suspiciousPatterns = [
168
+ /\.\.\//, // Path traversal
169
+ /~/, // Home directory access
170
+ /\.env/, // Environment files
171
+ /\.git/, // Git files
172
+ /package\.json/, // Package files
173
+ /package-lock\.json/,
174
+ /node_modules/, // Dependencies
175
+ ];
176
+
177
+ return (req, res, next) => {
178
+ const requestPath = req.path;
179
+
180
+ const isSuspicious = suspiciousPatterns.some(pattern =>
181
+ pattern.test(requestPath)
182
+ );
183
+
184
+ if (isSuspicious) {
185
+ const clientIp = req.ip || req.connection.remoteAddress;
186
+ console.warn(`⚠️ Suspicious request: ${requestPath} from ${clientIp}`);
187
+ }
188
+
189
+ next();
190
+ };
191
+ }
192
+
193
+ export default {
194
+ securityMiddleware,
195
+ sliceFrameworkProtection,
196
+ suspiciousRequestLogger
197
+ };