vatts 1.2.0-alpha.1 → 1.2.0-alpha.2

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 (46) hide show
  1. package/dist/adapters/express.js +5 -1
  2. package/dist/adapters/factory.js +58 -21
  3. package/dist/adapters/fastify.js +5 -1
  4. package/dist/adapters/native.js +5 -1
  5. package/dist/api/console.js +25 -17
  6. package/dist/api/framework.js +22 -15
  7. package/dist/api/http.js +7 -2
  8. package/dist/builder.js +19 -10
  9. package/dist/client/clientRouter.js +6 -2
  10. package/dist/client/rpc.js +7 -4
  11. package/dist/env/env.js +18 -11
  12. package/dist/global/global.d.ts +177 -122
  13. package/dist/helpers.js +108 -67
  14. package/dist/hotReload.d.ts +6 -0
  15. package/dist/hotReload.js +179 -31
  16. package/dist/index.js +159 -115
  17. package/dist/react/BuildingPage.d.ts +2 -1
  18. package/dist/react/BuildingPage.js +47 -4
  19. package/dist/react/DefaultNotFound.d.ts +2 -1
  20. package/dist/react/DefaultNotFound.js +92 -17
  21. package/dist/react/DevIndicator.js +66 -23
  22. package/dist/react/ErrorModal.js +91 -40
  23. package/dist/react/Link.d.ts +2 -2
  24. package/dist/react/Link.js +27 -5
  25. package/dist/react/client.js +16 -5
  26. package/dist/react/entry.client.js +70 -30
  27. package/dist/react/image/Image.js +8 -3
  28. package/dist/react/renderer-react.js +53 -25
  29. package/dist/renderer.d.ts +4 -0
  30. package/dist/renderer.js +13 -5
  31. package/dist/router.js +82 -63
  32. package/dist/rpc/annotations.js +7 -3
  33. package/dist/rpc/server.js +21 -15
  34. package/dist/rpc/types.js +4 -1
  35. package/dist/types/framework.js +2 -1
  36. package/dist/types.js +2 -1
  37. package/dist/vue/App.vue +34 -37
  38. package/dist/vue/BuildingPage.vue +118 -102
  39. package/dist/vue/ErrorModal.vue +19 -37
  40. package/dist/vue/Link.vue +8 -7
  41. package/dist/vue/client.js +16 -6
  42. package/dist/vue/entry.client.js +8 -3
  43. package/dist/vue/image/Image.vue +25 -19
  44. package/dist/vue/renderer.vue.js +80 -26
  45. package/package.json +25 -12
  46. package/dist/global/global.js +0 -17
package/dist/router.js CHANGED
@@ -1,3 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.clearAllRouteCache = clearAllRouteCache;
7
+ exports.clearFileCache = clearFileCache;
8
+ exports.loadLayout = loadLayout;
9
+ exports.getLayout = getLayout;
10
+ exports.loadPathRoutes = loadPathRoutes;
11
+ exports.loadRoutes = loadRoutes;
12
+ exports.findMatchingRoute = findMatchingRoute;
13
+ exports.loadBackendRoutes = loadBackendRoutes;
14
+ exports.findMatchingBackendRoute = findMatchingBackendRoute;
15
+ exports.loadNotFound = loadNotFound;
16
+ exports.getNotFound = getNotFound;
17
+ exports.processWebSocketRoutes = processWebSocketRoutes;
18
+ exports.findMatchingWebSocketRoute = findMatchingWebSocketRoute;
19
+ exports.setupWebSocketUpgrade = setupWebSocketUpgrade;
1
20
  /*
2
21
  * This file is part of the Vatts.js Project.
3
22
  * Copyright (c) 2026 itsmuzin
@@ -14,14 +33,14 @@
14
33
  * See the License for the specific language governing permissions and
15
34
  * limitations under the License.
16
35
  */
17
- import fs from 'fs';
18
- import path from 'path';
19
- import { WebSocketServer as WSServer, WebSocket } from 'ws';
20
- import { URL } from 'url';
21
- import Console from "./api/console";
22
- import { FrameworkAdapterFactory } from "./adapters/factory";
23
- import { VattsRequest } from "./api/http";
24
- import { config } from "./helpers";
36
+ const fs_1 = __importDefault(require("fs"));
37
+ const path_1 = __importDefault(require("path"));
38
+ const ws_1 = require("ws");
39
+ const url_1 = require("url");
40
+ const console_1 = __importDefault(require("./api/console"));
41
+ const factory_1 = require("./adapters/factory");
42
+ const http_1 = require("./api/http");
43
+ const helpers_1 = require("./helpers");
25
44
  // --- Estado Global ---
26
45
  let allRoutes = [];
27
46
  let allBackendRoutes = [];
@@ -62,12 +81,12 @@ function safeClearCache(filePath) {
62
81
  // Ignora erro se arquivo não for resolvível
63
82
  }
64
83
  }
65
- export function clearAllRouteCache() {
84
+ function clearAllRouteCache() {
66
85
  loadedFiles.forEach(file => safeClearCache(file));
67
86
  loadedFiles.clear();
68
87
  }
69
- export function clearFileCache(changedFilePath) {
70
- const absolutePath = path.resolve(changedFilePath);
88
+ function clearFileCache(changedFilePath) {
89
+ const absolutePath = path_1.default.resolve(changedFilePath);
71
90
  // Só tenta limpar se realmente já foi carregado (evita I/O desnecessário)
72
91
  if (loadedFiles.has(absolutePath)) {
73
92
  safeClearCache(absolutePath);
@@ -107,19 +126,19 @@ function requireWithoutStyles(modulePath) {
107
126
  }
108
127
  }
109
128
  // --- Carregamento de Layout (Otimizado - Sem I/O de Disco) ---
110
- export function loadLayout(webDir) {
129
+ function loadLayout(webDir) {
111
130
  const extensions = ['layout.tsx', 'layout.jsx', 'layout.vue'];
112
131
  let layoutFile = null;
113
132
  for (const ext of extensions) {
114
- const fullPath = path.join(webDir, ext);
115
- if (fs.existsSync(fullPath)) {
133
+ const fullPath = path_1.default.join(webDir, ext);
134
+ if (fs_1.default.existsSync(fullPath)) {
116
135
  layoutFile = fullPath;
117
136
  break;
118
137
  }
119
138
  }
120
139
  if (layoutFile) {
121
- const absolutePath = path.resolve(layoutFile);
122
- const componentPath = path.relative(process.cwd(), layoutFile).replace(/\\/g, '/');
140
+ const absolutePath = path_1.default.resolve(layoutFile);
141
+ const componentPath = path_1.default.relative(process.cwd(), layoutFile).replace(/\\/g, '/');
123
142
  try {
124
143
  // Se já carregamos antes, limpa o cache para garantir reload
125
144
  if (loadedFiles.has(absolutePath)) {
@@ -135,7 +154,7 @@ export function loadLayout(webDir) {
135
154
  return layoutComponent;
136
155
  }
137
156
  catch (error) {
138
- Console.error(`Error loading layout ${layoutFile}:`, error);
157
+ console_1.default.error(`Error loading layout ${layoutFile}:`, error);
139
158
  layoutComponent = { componentPath };
140
159
  return layoutComponent;
141
160
  }
@@ -143,12 +162,12 @@ export function loadLayout(webDir) {
143
162
  layoutComponent = null;
144
163
  return null;
145
164
  }
146
- export function getLayout() { return layoutComponent; }
165
+ function getLayout() { return layoutComponent; }
147
166
  // --- Carregamento de Rotas Frontend ---
148
167
  // Helper para converter o caminho do arquivo no padrão de URL (Next.js style)
149
168
  function convertPathToRoutePattern(absolutePath, routesDir) {
150
169
  // 1. Pega o caminho relativo e normaliza as barras
151
- let relPath = path.relative(routesDir, absolutePath).replace(/\\/g, '/');
170
+ let relPath = path_1.default.relative(routesDir, absolutePath).replace(/\\/g, '/');
152
171
  // 2. Remove o nome do arquivo (page.tsx, page.ts, page.jsx, page.js ou page.vue) do final
153
172
  relPath = relPath.replace(/\/?page\.(?:tsx|ts|jsx|js|vue)$/, '');
154
173
  // 3. Remove os "Route Groups" do Next.js, ex: (auth)/login vira /login
@@ -159,21 +178,21 @@ function convertPathToRoutePattern(absolutePath, routesDir) {
159
178
  // 5. Garante que comece com "/"
160
179
  return '/' + relPath;
161
180
  }
162
- export function loadPathRoutes(routesDir) {
163
- if (!fs.existsSync(routesDir)) {
181
+ function loadPathRoutes(routesDir) {
182
+ if (!fs_1.default.existsSync(routesDir)) {
164
183
  allRoutes = [];
165
184
  return [];
166
185
  }
167
186
  const loaded = [];
168
187
  const cwdPath = process.cwd();
169
188
  const scanAndLoad = (dir) => {
170
- const entries = fs.readdirSync(dir, { withFileTypes: true });
189
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
171
190
  for (const entry of entries) {
172
191
  const name = entry.name;
173
192
  // Ignora arquivos/pastas ocultas, de sistema ou de componentes (ex: _components)
174
193
  if (name.startsWith('.') || name.startsWith('_'))
175
194
  continue;
176
- const fullPath = path.join(dir, name);
195
+ const fullPath = path_1.default.join(dir, name);
177
196
  if (entry.isDirectory()) {
178
197
  if (name === 'backend' || name === 'api')
179
198
  continue;
@@ -182,7 +201,7 @@ export function loadPathRoutes(routesDir) {
182
201
  else if (entry.isFile() && (name === 'page.tsx' || name === 'page.ts' || name === 'page.jsx' || name === 'page.js' || name === 'page.vue')) {
183
202
  // SÓ carrega se for um arquivo "page"
184
203
  try {
185
- const absolutePath = path.resolve(fullPath);
204
+ const absolutePath = path_1.default.resolve(fullPath);
186
205
  // OTIMIZAÇÃO: Limpa cache apenas se já existia
187
206
  if (loadedFiles.has(absolutePath)) {
188
207
  safeClearCache(absolutePath);
@@ -192,7 +211,7 @@ export function loadPathRoutes(routesDir) {
192
211
  // O "default" agora é o Componente React/Vue em si
193
212
  const PageComponent = routeModule.default;
194
213
  if (PageComponent) {
195
- const componentPath = path.relative(cwdPath, fullPath).replace(/\\/g, '/');
214
+ const componentPath = path_1.default.relative(cwdPath, fullPath).replace(/\\/g, '/');
196
215
  // Gera o pattern baseado na pasta (ex: /blog/[id])
197
216
  const pattern = convertPathToRoutePattern(absolutePath, routesDir);
198
217
  // Monta o config dinamicamente
@@ -213,7 +232,7 @@ export function loadPathRoutes(routesDir) {
213
232
  }
214
233
  }
215
234
  catch (error) {
216
- Console.error(`Error loading page ${fullPath}:`, error);
235
+ console_1.default.error(`Error loading page ${fullPath}:`, error);
217
236
  }
218
237
  }
219
238
  }
@@ -232,11 +251,11 @@ export function loadPathRoutes(routesDir) {
232
251
  allRoutes = loaded;
233
252
  return allRoutes.map(r => ({ ...r.config, componentPath: r.componentPath }));
234
253
  }
235
- export function loadRoutes(routesDir) {
236
- if (config?.pathRouter == true) {
237
- return loadPathRoutes(path.join(routesDir, "../"));
254
+ function loadRoutes(routesDir) {
255
+ if (helpers_1.config?.pathRouter == true) {
256
+ return loadPathRoutes(path_1.default.join(routesDir, "../"));
238
257
  }
239
- if (!fs.existsSync(routesDir)) {
258
+ if (!fs_1.default.existsSync(routesDir)) {
240
259
  allRoutes = [];
241
260
  return [];
242
261
  }
@@ -244,13 +263,13 @@ export function loadRoutes(routesDir) {
244
263
  const cwdPath = process.cwd();
245
264
  // Função recursiva otimizada
246
265
  const scanAndLoad = (dir) => {
247
- const entries = fs.readdirSync(dir, { withFileTypes: true });
266
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
248
267
  for (const entry of entries) {
249
268
  const name = entry.name;
250
269
  // Skip arquivos ocultos ou de sistema para acelerar scan
251
270
  if (name.startsWith('.') || name.startsWith('_'))
252
271
  continue;
253
- const fullPath = path.join(dir, name);
272
+ const fullPath = path_1.default.join(dir, name);
254
273
  if (entry.isDirectory()) {
255
274
  if (name === 'backend')
256
275
  continue;
@@ -258,7 +277,7 @@ export function loadRoutes(routesDir) {
258
277
  }
259
278
  else if (entry.isFile() && (name.endsWith('.tsx') || name.endsWith('.ts') || name.endsWith(".jsx") || name.endsWith(".js") || name.endsWith(".vue"))) {
260
279
  try {
261
- const absolutePath = path.resolve(fullPath);
280
+ const absolutePath = path_1.default.resolve(fullPath);
262
281
  // OTIMIZAÇÃO CRÍTICA: Só limpa cache se o arquivo já foi carregado antes.
263
282
  // Isso evita chamadas caras de require.resolve() na inicialização do servidor.
264
283
  if (loadedFiles.has(absolutePath)) {
@@ -275,7 +294,7 @@ export function loadRoutes(routesDir) {
275
294
  };
276
295
  }
277
296
  if (defaultConfig?.pattern && defaultConfig?.component) {
278
- const componentPath = path.relative(cwdPath, fullPath).replace(/\\/g, '/');
297
+ const componentPath = path_1.default.relative(cwdPath, fullPath).replace(/\\/g, '/');
279
298
  // OTIMIZAÇÃO: Pré-compila a regex aqui
280
299
  const regex = compileRoutePatternWithGroups(defaultConfig.pattern);
281
300
  loaded.push({
@@ -288,7 +307,7 @@ export function loadRoutes(routesDir) {
288
307
  }
289
308
  }
290
309
  catch (error) {
291
- Console.error(`Error loading route ${fullPath}:`, error);
310
+ console_1.default.error(`Error loading route ${fullPath}:`, error);
292
311
  }
293
312
  }
294
313
  }
@@ -298,7 +317,7 @@ export function loadRoutes(routesDir) {
298
317
  allRoutes = loaded;
299
318
  return allRoutes.map(r => ({ ...r.config, componentPath: r.componentPath }));
300
319
  }
301
- export function findMatchingRoute(pathname) {
320
+ function findMatchingRoute(pathname) {
302
321
  // OTIMIZAÇÃO: Loop usando regex pré-compilada. Muito mais rápido.
303
322
  for (const route of allRoutes) {
304
323
  const match = pathname.match(route.regex);
@@ -320,10 +339,10 @@ function getMiddlewaresForDir(dir) {
320
339
  const files = ['middleware.ts', 'middleware.js'];
321
340
  let middlewares = [];
322
341
  for (const file of files) {
323
- const fullPath = path.join(dir, file);
324
- if (fs.existsSync(fullPath)) {
342
+ const fullPath = path_1.default.join(dir, file);
343
+ if (fs_1.default.existsSync(fullPath)) {
325
344
  try {
326
- const absolutePath = path.resolve(fullPath);
345
+ const absolutePath = path_1.default.resolve(fullPath);
327
346
  if (loadedFiles.has(absolutePath)) {
328
347
  safeClearCache(absolutePath);
329
348
  }
@@ -345,29 +364,29 @@ function getMiddlewaresForDir(dir) {
345
364
  break;
346
365
  }
347
366
  catch (e) {
348
- Console.error(`Error loading middleware ${fullPath}`, e);
367
+ console_1.default.error(`Error loading middleware ${fullPath}`, e);
349
368
  }
350
369
  }
351
370
  }
352
371
  middlewareCache.set(dir, middlewares);
353
372
  return middlewares;
354
373
  }
355
- export function loadBackendRoutes(backendRoutesDir) {
356
- if (!fs.existsSync(backendRoutesDir)) {
374
+ function loadBackendRoutes(backendRoutesDir) {
375
+ if (!fs_1.default.existsSync(backendRoutesDir)) {
357
376
  allBackendRoutes = [];
358
377
  return;
359
378
  }
360
379
  middlewareCache.clear(); // Limpa cache de middleware ao recarregar rotas
361
380
  const loaded = [];
362
381
  const scanAndLoadAPI = (dir) => {
363
- const entries = fs.readdirSync(dir, { withFileTypes: true });
382
+ const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
364
383
  // Primeiro carrega middleware deste diretório para cachear
365
384
  getMiddlewaresForDir(dir);
366
385
  for (const entry of entries) {
367
386
  const name = entry.name;
368
387
  if (name.startsWith('.') || name.startsWith('_'))
369
388
  continue;
370
- const fullPath = path.join(dir, name);
389
+ const fullPath = path_1.default.join(dir, name);
371
390
  if (entry.isDirectory()) {
372
391
  scanAndLoadAPI(fullPath);
373
392
  }
@@ -375,7 +394,7 @@ export function loadBackendRoutes(backendRoutesDir) {
375
394
  if (name.startsWith('middleware'))
376
395
  continue;
377
396
  try {
378
- const absolutePath = path.resolve(fullPath);
397
+ const absolutePath = path_1.default.resolve(fullPath);
379
398
  if (loadedFiles.has(absolutePath)) {
380
399
  safeClearCache(absolutePath);
381
400
  }
@@ -399,7 +418,7 @@ export function loadBackendRoutes(backendRoutesDir) {
399
418
  }
400
419
  }
401
420
  catch (e) {
402
- Console.error(`Error loading API route ${fullPath}`, e);
421
+ console_1.default.error(`Error loading API route ${fullPath}`, e);
403
422
  }
404
423
  }
405
424
  }
@@ -409,7 +428,7 @@ export function loadBackendRoutes(backendRoutesDir) {
409
428
  // Processa WebSockets após carregar rotas HTTP
410
429
  processWebSocketRoutes();
411
430
  }
412
- export function findMatchingBackendRoute(pathname, method) {
431
+ function findMatchingBackendRoute(pathname, method) {
413
432
  const methodUpper = method.toUpperCase();
414
433
  for (const route of allBackendRoutes) {
415
434
  // @ts-ignore
@@ -426,13 +445,13 @@ export function findMatchingBackendRoute(pathname, method) {
426
445
  return null;
427
446
  }
428
447
  // --- 404 Not Found ---
429
- export function loadNotFound(webDir) {
448
+ function loadNotFound(webDir) {
430
449
  const files = ['notFound.tsx', 'notFound.jsx', 'notFound.vue'];
431
450
  for (const file of files) {
432
- const fullPath = path.join(webDir, file);
433
- if (fs.existsSync(fullPath)) {
434
- const absolutePath = path.resolve(fullPath);
435
- const componentPath = path.relative(process.cwd(), fullPath).replace(/\\/g, '/');
451
+ const fullPath = path_1.default.join(webDir, file);
452
+ if (fs_1.default.existsSync(fullPath)) {
453
+ const absolutePath = path_1.default.resolve(fullPath);
454
+ const componentPath = path_1.default.relative(process.cwd(), fullPath).replace(/\\/g, '/');
436
455
  if (loadedFiles.has(absolutePath)) {
437
456
  safeClearCache(absolutePath);
438
457
  }
@@ -446,9 +465,9 @@ export function loadNotFound(webDir) {
446
465
  notFoundComponent = null;
447
466
  return null;
448
467
  }
449
- export function getNotFound() { return notFoundComponent; }
468
+ function getNotFound() { return notFoundComponent; }
450
469
  // --- WebSocket (Mantendo lógica, otimizando lookup) ---
451
- export function processWebSocketRoutes() {
470
+ function processWebSocketRoutes() {
452
471
  allWebSocketRoutes = allBackendRoutes
453
472
  .filter(r => r.config.WS)
454
473
  .map(r => ({
@@ -458,7 +477,7 @@ export function processWebSocketRoutes() {
458
477
  middleware: r.config.middleware
459
478
  }));
460
479
  }
461
- export function findMatchingWebSocketRoute(pathname) {
480
+ function findMatchingWebSocketRoute(pathname) {
462
481
  for (const wsRoute of allWebSocketRoutes) {
463
482
  const match = pathname.match(wsRoute.regex);
464
483
  if (match) {
@@ -477,7 +496,7 @@ export function findMatchingWebSocketRoute(pathname) {
477
496
  function handleWebSocketConnection(ws, req, hwebReq) {
478
497
  if (!req.url)
479
498
  return;
480
- const url = new URL(req.url, `http://${req.headers.host}`);
499
+ const url = new url_1.URL(req.url, `http://${req.headers.host}`);
481
500
  const match = findMatchingWebSocketRoute(url.pathname);
482
501
  if (!match) {
483
502
  ws.close(1000, 'Route not found');
@@ -491,7 +510,7 @@ function handleWebSocketConnection(ws, req, hwebReq) {
491
510
  params: match.params,
492
511
  query: Object.fromEntries(url.searchParams.entries()),
493
512
  send: (data) => {
494
- if (ws.readyState === WebSocket.OPEN) {
513
+ if (ws.readyState === ws_1.WebSocket.OPEN) {
495
514
  ws.send(typeof data === 'string' ? data : JSON.stringify(data));
496
515
  }
497
516
  },
@@ -500,7 +519,7 @@ function handleWebSocketConnection(ws, req, hwebReq) {
500
519
  const msg = typeof data === 'string' ? data : JSON.stringify(data);
501
520
  const excludeSet = new Set(exclude || []);
502
521
  for (const conn of wsConnections) {
503
- if (conn.readyState === WebSocket.OPEN && !excludeSet.has(conn)) {
522
+ if (conn.readyState === ws_1.WebSocket.OPEN && !excludeSet.has(conn)) {
504
523
  conn.send(msg);
505
524
  }
506
525
  }
@@ -514,16 +533,16 @@ function handleWebSocketConnection(ws, req, hwebReq) {
514
533
  ws.close(1011, 'Internal server error');
515
534
  }
516
535
  }
517
- export function setupWebSocketUpgrade(server, hotReloadManager) {
536
+ function setupWebSocketUpgrade(server, hotReloadManager) {
518
537
  if (server.listeners('upgrade').length > 0)
519
538
  return;
520
539
  server.on('upgrade', (request, socket, head) => {
521
- const adapter = FrameworkAdapterFactory.getCurrentAdapter();
540
+ const adapter = factory_1.FrameworkAdapterFactory.getCurrentAdapter();
522
541
  if (!adapter) {
523
542
  socket.destroy();
524
543
  return;
525
544
  }
526
- const { pathname } = new URL(request.url, `http://${request.headers.host}`);
545
+ const { pathname } = new url_1.URL(request.url, `http://${request.headers.host}`);
527
546
  // Prioridade 1: Hot Reload
528
547
  if (pathname === '/hweb-hotreload/') {
529
548
  if (hotReloadManager)
@@ -535,12 +554,12 @@ export function setupWebSocketUpgrade(server, hotReloadManager) {
535
554
  // Prioridade 2: Rotas App
536
555
  const match = findMatchingWebSocketRoute(pathname);
537
556
  if (match) {
538
- const wss = new WSServer({ noServer: true, perMessageDeflate: false, maxPayload: 1024 * 1024 });
557
+ const wss = new ws_1.WebSocketServer({ noServer: true, perMessageDeflate: false, maxPayload: 1024 * 1024 });
539
558
  wss.handleUpgrade(request, socket, head, (ws) => {
540
559
  wsConnections.add(ws);
541
560
  ws.on('close', () => wsConnections.delete(ws));
542
561
  ws.on('error', () => wsConnections.delete(ws));
543
- const hwebReq = new VattsRequest(adapter.parseRequest(request));
562
+ const hwebReq = new http_1.VattsRequest(adapter.parseRequest(request));
544
563
  handleWebSocketConnection(ws, request, hwebReq);
545
564
  });
546
565
  return;
@@ -1,15 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RPC_EXPOSED_KEY = void 0;
4
+ exports.default = Expose;
1
5
  /**
2
6
  * Símbolo único para marcar funções expostas.
3
7
  * Usamos Symbol para garantir que não possa ser falsificado via JSON no payload.
4
8
  */
5
- export const RPC_EXPOSED_KEY = Symbol('__rpc_exposed__');
6
- export default function Expose(...input) {
9
+ exports.RPC_EXPOSED_KEY = Symbol('__rpc_exposed__');
10
+ function Expose(...input) {
7
11
  const fns = Array.isArray(input[0]) ? input[0] : input;
8
12
  for (const fn of fns) {
9
13
  if (typeof fn !== 'function') {
10
14
  throw new TypeError('Expose aceita apenas funções');
11
15
  }
12
- fn[RPC_EXPOSED_KEY] = true;
16
+ fn[exports.RPC_EXPOSED_KEY] = true;
13
17
  }
14
18
  // Retorno:
15
19
  // - se veio uma função → retorna ela
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  * This file is part of the Vatts.js Project.
3
4
  * Copyright (c) 2026 itsmuzin
@@ -14,11 +15,16 @@
14
15
  * See the License for the specific language governing permissions and
15
16
  * limitations under the License.
16
17
  */
17
- import fs from 'fs';
18
- import path from 'path';
19
- import { VattsRequest } from '../api/http';
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.executeRpc = executeRpc;
23
+ const fs_1 = __importDefault(require("fs"));
24
+ const path_1 = __importDefault(require("path"));
25
+ const http_1 = require("../api/http");
20
26
  // Importamos a chave para verificar a anotação de segurança
21
- import { RPC_EXPOSED_KEY } from './annotations';
27
+ const annotations_1 = require("./annotations");
22
28
  const DEFAULT_ALLOWED_SERVER_DIRS = ['src/backend'];
23
29
  function normalizeToPosix(p) {
24
30
  return p.replace(/\\/g, '/');
@@ -45,19 +51,19 @@ function validatePayload(payload) {
45
51
  function tryResolveWithinAllowedDirs(projectDir, allowedDirs, requestedFile) {
46
52
  const req = requestedFile.replace(/\\/g, '/').replace(/^\.(?:\/|\\)/, '');
47
53
  for (const d of allowedDirs) {
48
- const baseAbs = path.resolve(projectDir, d);
54
+ const baseAbs = path_1.default.resolve(projectDir, d);
49
55
  // Interpret client path as relative to src/web (where it's typically authored)
50
- const fromWebAbs = path.resolve(projectDir, 'src/web', req);
56
+ const fromWebAbs = path_1.default.resolve(projectDir, 'src/web', req);
51
57
  // Map: <project>/src/backend/* (coming from ../../backend/* from web code)
52
- const mappedFromWebAbs = fromWebAbs.replace(path.resolve(projectDir, 'backend') + path.sep, path.resolve(projectDir, 'src', 'backend') + path.sep);
58
+ const mappedFromWebAbs = fromWebAbs.replace(path_1.default.resolve(projectDir, 'backend') + path_1.default.sep, path_1.default.resolve(projectDir, 'src', 'backend') + path_1.default.sep);
53
59
  // Also accept callers passing a backend-relative path like "./auth" or "auth"
54
- const fromBackendAbs = path.resolve(baseAbs, req);
60
+ const fromBackendAbs = path_1.default.resolve(baseAbs, req);
55
61
  const candidateAbsList = [mappedFromWebAbs, fromBackendAbs];
56
62
  for (const candidateAbs of candidateAbsList) {
57
- const baseWithSep = baseAbs.endsWith(path.sep) ? baseAbs : baseAbs + path.sep;
63
+ const baseWithSep = baseAbs.endsWith(path_1.default.sep) ? baseAbs : baseAbs + path_1.default.sep;
58
64
  if (!candidateAbs.startsWith(baseWithSep) && candidateAbs !== baseAbs)
59
65
  continue;
60
- if (!fs.existsSync(baseAbs))
66
+ if (!fs_1.default.existsSync(baseAbs))
61
67
  continue;
62
68
  return candidateAbs;
63
69
  }
@@ -97,9 +103,9 @@ function buildRpcRequestFromPayload(payload) {
97
103
  cookies: payload.request?.cookies || toCookies(cookieHeader),
98
104
  raw: null
99
105
  };
100
- return new VattsRequest(req);
106
+ return new http_1.VattsRequest(req);
101
107
  }
102
- export async function executeRpc(ctx, payload) {
108
+ async function executeRpc(ctx, payload) {
103
109
  try {
104
110
  if (!validatePayload(payload)) {
105
111
  return { success: false, error: 'Invalid RPC payload' };
@@ -113,7 +119,7 @@ export async function executeRpc(ctx, payload) {
113
119
  if (!absFile) {
114
120
  return { success: false, error: 'File not allowed for RPC' };
115
121
  }
116
- if (!absFile.startsWith(path.resolve(ctx.projectDir) + path.sep)) {
122
+ if (!absFile.startsWith(path_1.default.resolve(ctx.projectDir) + path_1.default.sep)) {
117
123
  return { success: false, error: 'Invalid file path' };
118
124
  }
119
125
  // Ensure fresh code in dev
@@ -153,7 +159,7 @@ export async function executeRpc(ctx, payload) {
153
159
  }
154
160
  // --- SECURITY CHECK (Expose Annotation or Allowlist) ---
155
161
  // 1. Verifica se a função possui o Symbol definido em annotations.ts (Via wrapper Expose())
156
- const isAnnotated = fnValue[RPC_EXPOSED_KEY];
162
+ const isAnnotated = fnValue[annotations_1.RPC_EXPOSED_KEY];
157
163
  // 2. Verifica se o módulo exporta uma lista explícita chamada 'exposed' ou 'rpcMethods'
158
164
  // Isso permite o uso de "export function" sem wrapper, listando os nomes no final do arquivo.
159
165
  const allowList = mod.exposed || mod.rpcMethods;
@@ -165,7 +171,7 @@ export async function executeRpc(ctx, payload) {
165
171
  };
166
172
  }
167
173
  // ------------------------------------------
168
- const rpcRequest = ctx.request ? new VattsRequest(ctx.request) : buildRpcRequestFromPayload(payload);
174
+ const rpcRequest = ctx.request ? new http_1.VattsRequest(ctx.request) : buildRpcRequestFromPayload(payload);
169
175
  // If the function declares a first parameter, we assume it's the injected request.
170
176
  // Otherwise, call it only with payload args.
171
177
  // it might be 0, so we treat length>=1 as "expects req".
package/dist/rpc/types.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  * This file is part of the Vatts.js Project.
3
4
  * Copyright (c) 2026 itsmuzin
@@ -14,4 +15,6 @@
14
15
  * See the License for the specific language governing permissions and
15
16
  * limitations under the License.
16
17
  */
17
- export const RPC_ENDPOINT = '/api/rpc';
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.RPC_ENDPOINT = void 0;
20
+ exports.RPC_ENDPOINT = '/api/rpc';
@@ -1 +1,2 @@
1
- export {};
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/types.js CHANGED
@@ -1 +1,2 @@
1
- export {};
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });