slicejs-web-framework 3.4.4 → 3.5.1
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/Slice/Components/Structural/Controller/Controller.js +135 -0
- package/Slice/Components/Structural/EventManager/EventManager.js +289 -4
- package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +368 -30
- package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -0
- package/Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +56 -0
- package/Slice/Slice.js +14 -1
- package/Slice/tests/event-emitters.test.js +79 -0
- package/Slice/tests/event-registry.test.js +141 -0
- package/Slice/tests/leak-orphans.test.js +131 -0
- package/api/{middleware → framework}/securityMiddleware.js +18 -74
- package/api/framework/server.js +333 -0
- package/api/index.js +5 -279
- package/api/tests/public-env-resolver.test.js +1 -1
- package/package.json +4 -2
- package/sliceConfig.schema.json +10 -1
- package/src/App/index.html +31 -1
- package/src/manifest.json +15 -0
- package/src/robots.txt +4 -0
- package/src/sitemap.xml +8 -0
- package/src/sliceConfig.json +5 -1
- package/types/index.d.ts +12 -0
- package/slicejs-cli/.github/workflows/ci.yml +0 -43
- package/slicejs-cli/LICENSE +0 -21
- package/slicejs-cli/assets/Slice.js-logo.png +0 -0
- package/slicejs-cli/client.js +0 -740
- package/slicejs-cli/commands/Print.js +0 -164
- package/slicejs-cli/commands/Validations.js +0 -92
- package/slicejs-cli/commands/build/build.js +0 -40
- package/slicejs-cli/commands/buildProduction/buildProduction.js +0 -577
- package/slicejs-cli/commands/bundle/bundle.js +0 -236
- package/slicejs-cli/commands/createComponent/VisualComponentTemplate.js +0 -55
- package/slicejs-cli/commands/createComponent/createComponent.js +0 -128
- package/slicejs-cli/commands/deleteComponent/deleteComponent.js +0 -81
- package/slicejs-cli/commands/doctor/doctor.js +0 -516
- package/slicejs-cli/commands/getComponent/getComponent.js +0 -695
- package/slicejs-cli/commands/init/init.js +0 -473
- package/slicejs-cli/commands/listComponents/listComponents.js +0 -172
- package/slicejs-cli/commands/startServer/startServer.js +0 -240
- package/slicejs-cli/commands/startServer/watchServer.js +0 -66
- package/slicejs-cli/commands/types/types.js +0 -583
- package/slicejs-cli/commands/utils/LocalCliDelegation.js +0 -53
- package/slicejs-cli/commands/utils/PackageManager.js +0 -148
- package/slicejs-cli/commands/utils/PathHelper.js +0 -75
- package/slicejs-cli/commands/utils/VersionChecker.js +0 -169
- package/slicejs-cli/commands/utils/bundling/BundleGenerator.js +0 -2525
- package/slicejs-cli/commands/utils/bundling/DependencyAnalyzer.js +0 -933
- package/slicejs-cli/commands/utils/loadConfig.js +0 -31
- package/slicejs-cli/commands/utils/sliceScripts.js +0 -48
- package/slicejs-cli/commands/utils/updateManager.js +0 -471
- package/slicejs-cli/package.json +0 -71
- package/slicejs-cli/playwright.config.js +0 -51
- package/slicejs-cli/pnpm-lock.yaml +0 -1629
- package/slicejs-cli/tests/build-command-integration.test.js +0 -87
- package/slicejs-cli/tests/build-mangling-e2e.test.js +0 -290
- package/slicejs-cli/tests/build-production-e2e.test.js +0 -140
- package/slicejs-cli/tests/builder-edge-cases.test.js +0 -322
- package/slicejs-cli/tests/bundle-generate-e2e.test.js +0 -115
- package/slicejs-cli/tests/bundle-generator.test.js +0 -691
- package/slicejs-cli/tests/bundle-v2-register-output.test.js +0 -470
- package/slicejs-cli/tests/bundling-dependency-edges.test.js +0 -127
- package/slicejs-cli/tests/bundling-imports-unit.test.js +0 -267
- package/slicejs-cli/tests/client-launcher-contract.test.js +0 -211
- package/slicejs-cli/tests/commands-component-crud.test.js +0 -128
- package/slicejs-cli/tests/commands-doctor.test.js +0 -152
- package/slicejs-cli/tests/commands-version-checker.test.js +0 -37
- package/slicejs-cli/tests/component-registry-parse.test.js +0 -34
- package/slicejs-cli/tests/dependency-analyzer.test.js +0 -24
- package/slicejs-cli/tests/e2e/bundles.spec.js +0 -91
- package/slicejs-cli/tests/e2e/dependency-scenarios.spec.js +0 -56
- package/slicejs-cli/tests/e2e/fixtures/components/Service/FetchManager/FetchManager.js +0 -136
- package/slicejs-cli/tests/e2e/fixtures/components/Service/IndexedDbManager/IndexedDbManager.js +0 -149
- package/slicejs-cli/tests/e2e/fixtures/components/Service/LocalStorageManager/LocalStorageManager.js +0 -45
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.css +0 -106
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.html +0 -5
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.js +0 -158
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Link/Link.js +0 -33
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.css +0 -56
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.html +0 -83
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.js +0 -164
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/MultiRoute/MultiRoute.js +0 -167
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.css +0 -116
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.html +0 -44
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.js +0 -180
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/NotFound/NotFound.js +0 -20
- package/slicejs-cli/tests/e2e/fixtures/components/Visual/Route/Route.js +0 -181
- package/slicejs-cli/tests/e2e/fixtures/components/registry.json +0 -12
- package/slicejs-cli/tests/e2e/fixtures/vendor-components.mjs +0 -65
- package/slicejs-cli/tests/e2e/navigation.spec.js +0 -44
- package/slicejs-cli/tests/e2e/render.spec.js +0 -34
- package/slicejs-cli/tests/e2e/serve.mjs +0 -264
- package/slicejs-cli/tests/e2e/shared-deps.spec.js +0 -61
- package/slicejs-cli/tests/e2e/unminified.spec.js +0 -33
- package/slicejs-cli/tests/e2e-serve.test.js +0 -148
- package/slicejs-cli/tests/fixtures/components.js +0 -8
- package/slicejs-cli/tests/fixtures/sliceConfig.json +0 -74
- package/slicejs-cli/tests/getcomponent.test.js +0 -435
- package/slicejs-cli/tests/helpers/setup.js +0 -102
- package/slicejs-cli/tests/init-command-contract.test.js +0 -101
- package/slicejs-cli/tests/init-e2e.test.js +0 -82
- package/slicejs-cli/tests/init-project-isolation.test.js +0 -98
- package/slicejs-cli/tests/local-cli-delegation.test.js +0 -81
- package/slicejs-cli/tests/package-manager.test.js +0 -127
- package/slicejs-cli/tests/path-helper.test.js +0 -206
- package/slicejs-cli/tests/perf-budget.test.js +0 -84
- package/slicejs-cli/tests/postinstall-command.test.js +0 -103
- package/slicejs-cli/tests/property-mangling-regression.test.js +0 -182
- package/slicejs-cli/tests/types-breakage.test.js +0 -491
- package/slicejs-cli/tests/types-generator-errors.test.js +0 -361
- package/slicejs-cli/tests/types-generator.test.js +0 -348
- /package/api/{utils → framework}/publicEnvResolver.js +0 -0
package/api/index.js
CHANGED
|
@@ -1,281 +1,7 @@
|
|
|
1
|
-
// api/index.js -
|
|
2
|
-
import
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import fs from 'fs';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import { dirname } from 'path';
|
|
7
|
-
import {
|
|
8
|
-
securityMiddleware,
|
|
9
|
-
sliceFrameworkProtection,
|
|
10
|
-
suspiciousRequestLogger
|
|
11
|
-
} from './middleware/securityMiddleware.js';
|
|
12
|
-
import { createPublicEnvProvider } from './utils/publicEnvResolver.js';
|
|
1
|
+
// api/index.js - Punto de entrada del servidor
|
|
2
|
+
import { createSliceServer } from 'slicejs-web-framework/api/framework/server.js';
|
|
13
3
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
import sliceConfig from '../src/sliceConfig.json' with { type: 'json' };
|
|
4
|
+
const server = createSliceServer();
|
|
5
|
+
server.start();
|
|
17
6
|
|
|
18
|
-
|
|
19
|
-
const app = express();
|
|
20
|
-
|
|
21
|
-
// Parsear argumentos de línea de comandos
|
|
22
|
-
const args = process.argv.slice(2);
|
|
23
|
-
|
|
24
|
-
const runMode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
|
|
25
|
-
const folderDeployed = runMode === 'production' ? 'dist' : 'src';
|
|
26
|
-
const publicEnvProvider = createPublicEnvProvider({
|
|
27
|
-
mode: runMode,
|
|
28
|
-
envFilePath: path.join(__dirname, '..', '.env')
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// Obtener puerto desde process.env.PORT con fallback a sliceConfig.json
|
|
32
|
-
const PORT = process.env.PORT || sliceConfig.server?.port || 3001;
|
|
33
|
-
|
|
34
|
-
// ==============================================
|
|
35
|
-
// MIDDLEWARES DE SEGURIDAD (APLICAR PRIMERO)
|
|
36
|
-
// ==============================================
|
|
37
|
-
|
|
38
|
-
// 1. Logger de peticiones sospechosas (solo observación, no bloquea)
|
|
39
|
-
app.use(suspiciousRequestLogger());
|
|
40
|
-
|
|
41
|
-
// 2. Protección del framework - TOTALMENTE AUTOMÁTICA
|
|
42
|
-
// Detecta automáticamente el dominio desde los headers
|
|
43
|
-
// Funciona en localhost, IP, y cualquier dominio
|
|
44
|
-
app.use(sliceFrameworkProtection());
|
|
45
|
-
|
|
46
|
-
// 3. Middleware de seguridad general
|
|
47
|
-
app.use(securityMiddleware({
|
|
48
|
-
allowedExtensions: [
|
|
49
|
-
'.js', '.css', '.html', '.json',
|
|
50
|
-
'.svg', '.png', '.jpg', '.jpeg', '.gif',
|
|
51
|
-
'.woff', '.woff2', '.ttf', '.ico'
|
|
52
|
-
],
|
|
53
|
-
blockedPaths: [
|
|
54
|
-
'/node_modules',
|
|
55
|
-
'/package.json',
|
|
56
|
-
'/package-lock.json',
|
|
57
|
-
'/.env',
|
|
58
|
-
'/.git',
|
|
59
|
-
'/api/middleware'
|
|
60
|
-
],
|
|
61
|
-
allowPublicAssets: true
|
|
62
|
-
}));
|
|
63
|
-
|
|
64
|
-
// ==============================================
|
|
65
|
-
// MIDDLEWARES DE APLICACIÓN
|
|
66
|
-
// ==============================================
|
|
67
|
-
|
|
68
|
-
// Middleware global para archivos JavaScript con MIME types correctos
|
|
69
|
-
app.use((req, res, next) => {
|
|
70
|
-
if (req.path.endsWith('.js')) {
|
|
71
|
-
// Forzar headers correctos para TODOS los archivos .js
|
|
72
|
-
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
|
73
|
-
}
|
|
74
|
-
next();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
// Middleware para parsear JSON y formularios
|
|
78
|
-
app.use(express.json());
|
|
79
|
-
app.use(express.urlencoded({ extended: true }));
|
|
80
|
-
|
|
81
|
-
// Configurar headers de CORS
|
|
82
|
-
app.use((req, res, next) => {
|
|
83
|
-
res.header('Access-Control-Allow-Origin', '*');
|
|
84
|
-
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
85
|
-
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
|
86
|
-
|
|
87
|
-
if (req.method === 'OPTIONS') {
|
|
88
|
-
res.sendStatus(200);
|
|
89
|
-
} else {
|
|
90
|
-
next();
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// ==============================================
|
|
95
|
-
// RUNTIME MODE ENDPOINT
|
|
96
|
-
// ==============================================
|
|
97
|
-
|
|
98
|
-
app.get('/slice-env.json', (req, res) => {
|
|
99
|
-
const payload = publicEnvProvider.getPayload();
|
|
100
|
-
res.setHeader('Cache-Control', 'no-store');
|
|
101
|
-
res.setHeader('Pragma', 'no-cache');
|
|
102
|
-
res.setHeader('Expires', '0');
|
|
103
|
-
res.json(payload);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// ==============================================
|
|
107
|
-
// ARCHIVOS ESTÁTICOS (DESPUÉS DE SEGURIDAD)
|
|
108
|
-
// ==============================================
|
|
109
|
-
|
|
110
|
-
if (runMode === 'production') {
|
|
111
|
-
app.get('/Slice/Slice.js', (req, res) => {
|
|
112
|
-
const slicePath = path.join(__dirname, '..', 'node_modules', 'slicejs-web-framework', 'Slice', 'Slice.js');
|
|
113
|
-
try {
|
|
114
|
-
if (fs.existsSync(slicePath)) {
|
|
115
|
-
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
|
116
|
-
return res.send(fs.readFileSync(slicePath, 'utf8'));
|
|
117
|
-
}
|
|
118
|
-
} catch (error) {
|
|
119
|
-
console.error(`Error reading Slice.js:`, error);
|
|
120
|
-
return res.status(500).send('Error loading framework');
|
|
121
|
-
}
|
|
122
|
-
return res.status(404).send('Slice.js not found');
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
app.use('/Slice', (req, res) => res.status(404).send('Not found'));
|
|
126
|
-
app.use('/Components', (req, res) => res.status(404).send('Not found'));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Middleware personalizado para archivos de bundles con MIME types correctos
|
|
130
|
-
// ⚠️ DEBE IR ANTES del middleware general para tener prioridad
|
|
131
|
-
app.use('/bundles/', (req, res, next) => {
|
|
132
|
-
// Solo procesar archivos .js
|
|
133
|
-
if (req.path.endsWith('.js')) {
|
|
134
|
-
const filePath = path.join(__dirname, `../${folderDeployed}`, 'bundles', req.path);
|
|
135
|
-
console.log(`📂 Processing bundle: ${req.path} -> ${filePath}`);
|
|
136
|
-
|
|
137
|
-
// Verificar que el archivo existe
|
|
138
|
-
if (fs.existsSync(filePath)) {
|
|
139
|
-
try {
|
|
140
|
-
// Leer y servir el archivo con headers correctos
|
|
141
|
-
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
142
|
-
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
|
143
|
-
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); // No cachear para permitir actualizaciones en tiempo real
|
|
144
|
-
res.setHeader('Pragma', 'no-cache');
|
|
145
|
-
res.setHeader('Expires', '0');
|
|
146
|
-
console.log(`✅ Serving bundle: ${req.path} (${fileContent.length} bytes, ${Buffer.byteLength(fileContent, 'utf8')} bytes UTF-8)`);
|
|
147
|
-
return res.send(fileContent);
|
|
148
|
-
} catch (error) {
|
|
149
|
-
console.error(`Error reading bundle file:`, error);
|
|
150
|
-
return res.status(500).send('Error reading bundle file');
|
|
151
|
-
}
|
|
152
|
-
} else {
|
|
153
|
-
console.log(`❌ Bundle file not found: ${filePath}`);
|
|
154
|
-
return res.status(404).send('Bundle file not found');
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Para archivos no .js, continuar con el middleware estático normal
|
|
159
|
-
next();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Servir otros archivos de bundles (JSON, CSS, etc.) con el middleware estático normal
|
|
163
|
-
app.use('/bundles/', express.static(path.join(__dirname, `../${folderDeployed}`, 'bundles')));
|
|
164
|
-
console.log(`📦 Serving bundles from /${folderDeployed}/bundles`);
|
|
165
|
-
|
|
166
|
-
// Servir framework Slice.js (solo development)
|
|
167
|
-
if (runMode === 'development') {
|
|
168
|
-
app.use('/Slice/', express.static(path.join(__dirname, '..', 'node_modules', 'slicejs-web-framework', 'Slice')));
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Servir archivos estáticos del proyecto con allowlist
|
|
172
|
-
const publicFolders = Array.isArray(sliceConfig.publicFolders) ? sliceConfig.publicFolders : [];
|
|
173
|
-
const normalizedPublicFolders = publicFolders
|
|
174
|
-
.filter((entry) => typeof entry === 'string')
|
|
175
|
-
.map((entry) => entry.trim())
|
|
176
|
-
.filter((entry) => entry.length > 0)
|
|
177
|
-
.map((entry) => (entry.startsWith('/') ? entry : `/${entry}`));
|
|
178
|
-
|
|
179
|
-
if (runMode === 'development') {
|
|
180
|
-
app.use(express.static(path.join(__dirname, `../${folderDeployed}`)));
|
|
181
|
-
} else {
|
|
182
|
-
app.use('/App', express.static(path.join(__dirname, `../${folderDeployed}`, 'App')));
|
|
183
|
-
const serveStaticFile = (req, res, filePath, contentType, fileName) => {
|
|
184
|
-
try {
|
|
185
|
-
if (fs.existsSync(filePath)) {
|
|
186
|
-
res.setHeader('Content-Type', contentType);
|
|
187
|
-
return res.send(fs.readFileSync(filePath, 'utf8'));
|
|
188
|
-
}
|
|
189
|
-
} catch (error) {
|
|
190
|
-
console.error(`Error reading ${fileName}:`, error);
|
|
191
|
-
return res.status(500).send(`Error reading ${fileName}`);
|
|
192
|
-
}
|
|
193
|
-
return res.status(404).send(`${fileName} not found`);
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
app.get('/manifest.json', (req, res) => {
|
|
197
|
-
const manifestPath = path.join(__dirname, `../${folderDeployed}`, 'manifest.json');
|
|
198
|
-
serveStaticFile(req, res, manifestPath, 'application/json; charset=utf-8', 'manifest.json');
|
|
199
|
-
});
|
|
200
|
-
app.get('/service-worker.js', (req, res) => {
|
|
201
|
-
const workerPath = path.join(__dirname, `../${folderDeployed}`, 'service-worker.js');
|
|
202
|
-
serveStaticFile(req, res, workerPath, 'application/javascript; charset=utf-8', 'service-worker.js');
|
|
203
|
-
});
|
|
204
|
-
app.get('/routes.js', (req, res) => {
|
|
205
|
-
const routesPath = path.join(__dirname, `../${folderDeployed}`, 'routes.js');
|
|
206
|
-
serveStaticFile(req, res, routesPath, 'application/javascript; charset=utf-8', 'routes.js');
|
|
207
|
-
});
|
|
208
|
-
app.get('/sliceConfig.json', (req, res) => {
|
|
209
|
-
const configPath = path.join(__dirname, `../${folderDeployed}`, 'sliceConfig.json');
|
|
210
|
-
serveStaticFile(req, res, configPath, 'application/json; charset=utf-8', 'sliceConfig.json');
|
|
211
|
-
});
|
|
212
|
-
for (const folder of normalizedPublicFolders) {
|
|
213
|
-
app.use(folder, express.static(path.join(__dirname, `../${folderDeployed}`, folder)));
|
|
214
|
-
}
|
|
215
|
-
app.use('/bundles/', express.static(path.join(__dirname, `../${folderDeployed}`, 'bundles')));
|
|
216
|
-
app.use('/dist/', express.static(path.join(__dirname, '..', 'dist')));
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// ==============================================
|
|
220
|
-
// RUTAS DE API
|
|
221
|
-
// ==============================================
|
|
222
|
-
|
|
223
|
-
// Ruta de ejemplo para API
|
|
224
|
-
app.get('/api/status', (req, res) => {
|
|
225
|
-
res.json({
|
|
226
|
-
status: 'ok',
|
|
227
|
-
mode: runMode,
|
|
228
|
-
folder: folderDeployed,
|
|
229
|
-
timestamp: new Date().toISOString(),
|
|
230
|
-
framework: 'Slice.js',
|
|
231
|
-
version: '2.0.0',
|
|
232
|
-
security: {
|
|
233
|
-
enabled: true,
|
|
234
|
-
mode: 'automatic',
|
|
235
|
-
description: 'Zero-config security - works with any domain'
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
// ==============================================
|
|
242
|
-
// SPA FALLBACK
|
|
243
|
-
// ==============================================
|
|
244
|
-
|
|
245
|
-
// SPA fallback - servir index.html para rutas no encontradas
|
|
246
|
-
app.get('*', (req, res) => {
|
|
247
|
-
const indexPath = path.join(__dirname, `../${folderDeployed}`, "App", 'index.html');
|
|
248
|
-
res.sendFile(indexPath, (err) => {
|
|
249
|
-
if (err) {
|
|
250
|
-
console.error(`[SPA Fallback] Error sending ${indexPath}:`, err);
|
|
251
|
-
res.status(500).send(`<h1>500 - Internal Server Error</h1><p>Could not serve application file</p>`);
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
// ==============================================
|
|
257
|
-
// INICIO DEL SERVIDOR
|
|
258
|
-
// ==============================================
|
|
259
|
-
|
|
260
|
-
function startServer() {
|
|
261
|
-
server = app.listen(PORT, () => {
|
|
262
|
-
console.log(`🔒 Security middleware: active (zero-config, automatic)`);
|
|
263
|
-
console.log(`🚀 Slice.js server running on port ${PORT}`);
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Manejar cierre del proceso
|
|
268
|
-
process.on('SIGINT', () => {
|
|
269
|
-
console.log('\n🛑 Slice server stopped');
|
|
270
|
-
process.exit(0);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
process.on('SIGTERM', () => {
|
|
274
|
-
console.log('\n🛑 Server terminated');
|
|
275
|
-
process.exit(0);
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
// Iniciar servidor
|
|
279
|
-
startServer();
|
|
280
|
-
|
|
281
|
-
export default app;
|
|
7
|
+
export default server.app;
|
|
@@ -4,7 +4,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
6
6
|
|
|
7
|
-
const resolverModulePath = new URL('../
|
|
7
|
+
const resolverModulePath = new URL('../framework/publicEnvResolver.js', import.meta.url);
|
|
8
8
|
|
|
9
9
|
async function withTempEnvFile(contents, callback) {
|
|
10
10
|
const dir = await mkdtemp(path.join(tmpdir(), 'slice-public-env-'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slicejs-web-framework",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20"
|
|
@@ -25,10 +25,12 @@
|
|
|
25
25
|
"type": "module",
|
|
26
26
|
"exports": {
|
|
27
27
|
".": "./Slice/Slice.js",
|
|
28
|
-
"./api/framework/express.js": "./api/framework/express.js"
|
|
28
|
+
"./api/framework/express.js": "./api/framework/express.js",
|
|
29
|
+
"./api/framework/server.js": "./api/framework/server.js"
|
|
29
30
|
},
|
|
30
31
|
"types": "./types/index.d.ts",
|
|
31
32
|
"dependencies": {
|
|
33
|
+
"compression": "^1.8.1",
|
|
32
34
|
"express": "^4.19.2"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
package/sliceConfig.schema.json
CHANGED
|
@@ -10,7 +10,16 @@
|
|
|
10
10
|
"additionalProperties": true,
|
|
11
11
|
"properties": {
|
|
12
12
|
"enabled": { "type": "boolean" },
|
|
13
|
-
"click": { "type": "string", "enum": ["right", "left"] }
|
|
13
|
+
"click": { "type": "string", "enum": ["right", "left"] },
|
|
14
|
+
"leakInspector": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"additionalProperties": true,
|
|
17
|
+
"description": "Dev-only memory-leak panel. Disabled in production regardless of this flag.",
|
|
18
|
+
"properties": {
|
|
19
|
+
"enabled": { "type": "boolean" },
|
|
20
|
+
"shortcut": { "type": "string" }
|
|
21
|
+
}
|
|
22
|
+
}
|
|
14
23
|
}
|
|
15
24
|
},
|
|
16
25
|
"stylesManager": {
|
package/src/App/index.html
CHANGED
|
@@ -3,9 +3,39 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Slice
|
|
6
|
+
<title>Slice.js Web Framework</title>
|
|
7
|
+
<meta name="description" content="Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time. No build step required." />
|
|
8
|
+
<meta name="robots" content="index, follow" />
|
|
9
|
+
<meta name="author" content="vkneider.dev" />
|
|
10
|
+
<link rel="canonical" href="https://slicejs.com" />
|
|
7
11
|
<link rel="icon" type="image/x-icon" href="/images/favicon.ico" />
|
|
12
|
+
<link rel="manifest" href="/manifest.json" />
|
|
13
|
+
<meta name="theme-color" content="#F8F4FF" />
|
|
14
|
+
<meta name="color-scheme" content="light dark" />
|
|
15
|
+
<meta property="og:type" content="website" />
|
|
16
|
+
<meta property="og:title" content="Slice.js Web Framework" />
|
|
17
|
+
<meta property="og:description" content="Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time. No build step required." />
|
|
18
|
+
<meta property="og:url" content="https://slicejs.com" />
|
|
19
|
+
<meta property="og:image" content="https://slicejs.com/images/og-image.png" />
|
|
20
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
21
|
+
<meta name="twitter:title" content="Slice.js Web Framework" />
|
|
22
|
+
<meta name="twitter:description" content="Slice.js — a lightweight web framework built on native Web Components." />
|
|
23
|
+
<meta name="twitter:image" content="https://slicejs.com/images/og-image.png" />
|
|
8
24
|
<link rel="stylesheet" type="text/css" href="/App/style.css" />
|
|
25
|
+
<script type="application/ld+json">
|
|
26
|
+
{
|
|
27
|
+
"@context": "https://schema.org",
|
|
28
|
+
"@type": "WebSite",
|
|
29
|
+
"name": "Slice.js Web Framework",
|
|
30
|
+
"url": "https://slicejs.com",
|
|
31
|
+
"description": "Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time.",
|
|
32
|
+
"author": {
|
|
33
|
+
"@type": "Organization",
|
|
34
|
+
"name": "VKneider",
|
|
35
|
+
"url": "https://github.com/VKneider"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
9
39
|
</head>
|
|
10
40
|
|
|
11
41
|
<body>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Slice.js Web Framework",
|
|
3
|
+
"short_name": "Slice.js",
|
|
4
|
+
"start_url": "/",
|
|
5
|
+
"display": "standalone",
|
|
6
|
+
"background_color": "#F8F4FF",
|
|
7
|
+
"theme_color": "#F8F4FF",
|
|
8
|
+
"icons": [
|
|
9
|
+
{
|
|
10
|
+
"src": "/images/favicon.ico",
|
|
11
|
+
"sizes": "192x192 512x512",
|
|
12
|
+
"type": "image/x-icon"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
package/src/robots.txt
ADDED
package/src/sitemap.xml
ADDED
package/src/sliceConfig.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -44,6 +44,10 @@ export interface SliceControllerApi {
|
|
|
44
44
|
destroyComponent(components: HTMLElement | string | Array<HTMLElement | string>): number;
|
|
45
45
|
destroyByContainer(container: HTMLElement): number;
|
|
46
46
|
destroyByPattern(pattern: string | RegExp): number;
|
|
47
|
+
findOrphans(): Array<{ sliceId: string; name: string; reason: string; retainPath: string[] }>;
|
|
48
|
+
registerLeakExclusion(predicate: (component: HTMLElement) => boolean): void;
|
|
49
|
+
sampleComponentGrowth(): void;
|
|
50
|
+
isGrowthMonotonic(): boolean;
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
export interface SliceStylesManagerApi {
|
|
@@ -88,6 +92,13 @@ export interface SliceEventManagerApi {
|
|
|
88
92
|
unsubscribe(eventName: string, subscriptionId: string): boolean;
|
|
89
93
|
emit(eventName: string, ...data: unknown[]): void;
|
|
90
94
|
bind(component: HTMLElement): SliceEventBindingApi | null;
|
|
95
|
+
register(namespace: string, catalog: Record<string, { description?: string; payload?: unknown }>): SliceEventManagerApi;
|
|
96
|
+
register(catalog: Record<string, { description?: string; payload?: unknown }>): SliceEventManagerApi;
|
|
97
|
+
loadGraph(graph: { events: Record<string, unknown>; dynamic?: unknown }): SliceEventManagerApi;
|
|
98
|
+
staticEmittersOf(eventName: string): Array<{ file: string; line: number; component: string | null }>;
|
|
99
|
+
staticListenersOf(eventName: string): Array<{ file: string; line: number; component: string | null }>;
|
|
100
|
+
isDeclared(eventName: string): boolean;
|
|
101
|
+
namespaceOf(eventName: string): string | null;
|
|
91
102
|
cleanupComponent(sliceId: string): number;
|
|
92
103
|
hasSubscribers(eventName: string): boolean;
|
|
93
104
|
subscriberCount(eventName: string): number;
|
|
@@ -178,6 +189,7 @@ export interface SliceApi {
|
|
|
178
189
|
debugger?: SliceDebuggerApi;
|
|
179
190
|
eventsDebugger?: SlicePanelDebuggerApi;
|
|
180
191
|
contextDebugger?: SlicePanelDebuggerApi;
|
|
192
|
+
leakInspector?: SlicePanelDebuggerApi;
|
|
181
193
|
loading?: SliceLoadingApi;
|
|
182
194
|
paths: SlicePaths;
|
|
183
195
|
_mode: SliceMode;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [master, main]
|
|
6
|
-
pull_request:
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
test:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
timeout-minutes: 20
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v4
|
|
14
|
-
|
|
15
|
-
- uses: pnpm/action-setup@v4
|
|
16
|
-
with:
|
|
17
|
-
version: 11
|
|
18
|
-
|
|
19
|
-
- uses: actions/setup-node@v4
|
|
20
|
-
with:
|
|
21
|
-
node-version: 22
|
|
22
|
-
cache: pnpm
|
|
23
|
-
|
|
24
|
-
- name: Install dependencies
|
|
25
|
-
run: pnpm install --frozen-lockfile
|
|
26
|
-
|
|
27
|
-
- name: Install Playwright browser
|
|
28
|
-
run: pnpm exec playwright install --with-deps chromium
|
|
29
|
-
|
|
30
|
-
# Serialized to avoid resource contention between the build-heavy
|
|
31
|
-
# integration tests under parallel runners.
|
|
32
|
-
- name: Unit & integration tests
|
|
33
|
-
run: node --test --test-concurrency=1
|
|
34
|
-
|
|
35
|
-
- name: Browser E2E tests
|
|
36
|
-
run: pnpm exec playwright test
|
|
37
|
-
|
|
38
|
-
- uses: actions/upload-artifact@v4
|
|
39
|
-
if: ${{ !cancelled() }}
|
|
40
|
-
with:
|
|
41
|
-
name: playwright-report
|
|
42
|
-
path: playwright-report/
|
|
43
|
-
retention-days: 7
|
package/slicejs-cli/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Victor Jose Kneider Alnahi and Julio Antonio Graterol Bracho
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
Binary file
|