hightjs 0.4.0 → 0.5.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 (125) hide show
  1. package/README.md +48 -116
  2. package/dist/bin/hightjs.js +51 -23
  3. package/dist/builder.js +139 -4
  4. package/dist/client/DefaultNotFound.d.ts +1 -1
  5. package/dist/client/DefaultNotFound.js +72 -46
  6. package/dist/client/client.d.ts +3 -0
  7. package/dist/{client.js → client/client.js} +4 -4
  8. package/dist/client/entry.client.js +39 -29
  9. package/dist/global/global.d.ts +117 -0
  10. package/dist/{auth/types.js → global/global.js} +0 -1
  11. package/dist/helpers.js +80 -2
  12. package/dist/hotReload.js +2 -2
  13. package/dist/index.js +16 -16
  14. package/dist/loaders.d.ts +1 -0
  15. package/dist/loaders.js +46 -0
  16. package/dist/renderer.js +158 -4
  17. package/dist/types.d.ts +44 -0
  18. package/package.json +36 -31
  19. package/.idea/HightJS.iml +0 -9
  20. package/.idea/copilot.data.migration.agent.xml +0 -6
  21. package/.idea/copilot.data.migration.ask.xml +0 -6
  22. package/.idea/copilot.data.migration.ask2agent.xml +0 -6
  23. package/.idea/copilot.data.migration.edit.xml +0 -6
  24. package/.idea/copilotDiffState.xml +0 -67
  25. package/.idea/inspectionProfiles/Project_Default.xml +0 -13
  26. package/.idea/libraries/test_package.xml +0 -9
  27. package/.idea/libraries/ts_commonjs_default_export.xml +0 -9
  28. package/.idea/misc.xml +0 -7
  29. package/.idea/modules.xml +0 -8
  30. package/.idea/vcs.xml +0 -6
  31. package/dist/auth/client.d.ts +0 -24
  32. package/dist/auth/client.js +0 -146
  33. package/dist/auth/components.d.ts +0 -29
  34. package/dist/auth/components.js +0 -100
  35. package/dist/auth/core.d.ts +0 -55
  36. package/dist/auth/core.js +0 -189
  37. package/dist/auth/index.d.ts +0 -7
  38. package/dist/auth/index.js +0 -45
  39. package/dist/auth/jwt.d.ts +0 -41
  40. package/dist/auth/jwt.js +0 -185
  41. package/dist/auth/providers/credentials.d.ts +0 -60
  42. package/dist/auth/providers/credentials.js +0 -97
  43. package/dist/auth/providers/discord.d.ts +0 -63
  44. package/dist/auth/providers/discord.js +0 -190
  45. package/dist/auth/providers/google.d.ts +0 -63
  46. package/dist/auth/providers/google.js +0 -186
  47. package/dist/auth/providers/index.d.ts +0 -2
  48. package/dist/auth/providers/index.js +0 -35
  49. package/dist/auth/providers.d.ts +0 -3
  50. package/dist/auth/providers.js +0 -26
  51. package/dist/auth/react/index.d.ts +0 -6
  52. package/dist/auth/react/index.js +0 -48
  53. package/dist/auth/react.d.ts +0 -22
  54. package/dist/auth/react.js +0 -199
  55. package/dist/auth/routes.d.ts +0 -16
  56. package/dist/auth/routes.js +0 -152
  57. package/dist/auth/types.d.ts +0 -76
  58. package/dist/client.d.ts +0 -3
  59. package/docs/README.md +0 -58
  60. package/docs/arquivos-especiais.md +0 -10
  61. package/docs/autenticacao.md +0 -212
  62. package/docs/checklist.md +0 -9
  63. package/docs/cli.md +0 -72
  64. package/docs/config.md +0 -216
  65. package/docs/estrutura.md +0 -20
  66. package/docs/faq.md +0 -10
  67. package/docs/hot-reload.md +0 -5
  68. package/docs/integracoes.md +0 -240
  69. package/docs/middlewares.md +0 -73
  70. package/docs/rotas-backend.md +0 -45
  71. package/docs/rotas-frontend.md +0 -66
  72. package/docs/seguranca.md +0 -8
  73. package/docs/websocket.md +0 -45
  74. package/example/certs/cert.pem +0 -20
  75. package/example/certs/key.pem +0 -27
  76. package/example/hightjs.config.ts +0 -87
  77. package/example/package-lock.json +0 -1174
  78. package/example/package.json +0 -26
  79. package/example/postcss.config.js +0 -8
  80. package/example/src/backend/auth.ts +0 -42
  81. package/example/src/backend/routes/auth.ts +0 -3
  82. package/example/src/backend/routes/version.ts +0 -13
  83. package/example/src/web/components/Home.tsx +0 -140
  84. package/example/src/web/components/LoginPage.tsx +0 -149
  85. package/example/src/web/globals.css +0 -5
  86. package/example/src/web/layout.tsx +0 -100
  87. package/example/src/web/routes/index.tsx +0 -13
  88. package/example/src/web/routes/login.tsx +0 -30
  89. package/example/tailwind.config.js +0 -12
  90. package/example/tsconfig.json +0 -15
  91. package/src/adapters/express.ts +0 -87
  92. package/src/adapters/factory.ts +0 -112
  93. package/src/adapters/fastify.ts +0 -104
  94. package/src/adapters/native.ts +0 -234
  95. package/src/api/console.ts +0 -305
  96. package/src/api/http.ts +0 -535
  97. package/src/auth/client.ts +0 -171
  98. package/src/auth/components.tsx +0 -125
  99. package/src/auth/core.ts +0 -215
  100. package/src/auth/index.ts +0 -25
  101. package/src/auth/jwt.ts +0 -210
  102. package/src/auth/providers/credentials.ts +0 -139
  103. package/src/auth/providers/discord.ts +0 -239
  104. package/src/auth/providers/google.ts +0 -234
  105. package/src/auth/providers/index.ts +0 -20
  106. package/src/auth/providers.ts +0 -20
  107. package/src/auth/react/index.ts +0 -25
  108. package/src/auth/react.tsx +0 -234
  109. package/src/auth/routes.ts +0 -183
  110. package/src/auth/types.ts +0 -108
  111. package/src/bin/hightjs.js +0 -222
  112. package/src/builder.js +0 -472
  113. package/src/client/DefaultNotFound.tsx +0 -84
  114. package/src/client/clientRouter.ts +0 -153
  115. package/src/client/entry.client.tsx +0 -511
  116. package/src/client.ts +0 -24
  117. package/src/components/Link.tsx +0 -38
  118. package/src/helpers.ts +0 -542
  119. package/src/hotReload.ts +0 -569
  120. package/src/index.ts +0 -555
  121. package/src/renderer.tsx +0 -263
  122. package/src/router.ts +0 -730
  123. package/src/types/framework.ts +0 -58
  124. package/src/types.ts +0 -207
  125. package/tsconfig.json +0 -17
package/src/helpers.ts DELETED
@@ -1,542 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /*
4
- * This file is part of the HightJS Project.
5
- * Copyright (c) 2025 itsmuzin
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License");
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- */
19
-
20
- // Imports Nativos do Node.js (movidos para o topo)
21
- import http, {IncomingMessage, Server, ServerResponse} from 'http';
22
- import os from 'os';
23
- import {URLSearchParams} from 'url'; // API moderna, substitui 'querystring'
24
- import path from 'path';
25
- // Helpers para integração com diferentes frameworks
26
- import hweb, {FrameworkAdapterFactory} from './index'; // Importando o tipo
27
- import type {HightJSOptions, HightConfig, HightConfigFunction} from './types';
28
- import Console, {Colors} from "./api/console";
29
- import https, { Server as HttpsServer } from 'https'; // <-- ADICIONAR
30
- import fs from 'fs'; // <-- ADICIONAR
31
- // --- Tipagem ---
32
-
33
- /**
34
- * Interface para a instância principal do hweb, inferida pelo uso.
35
- */
36
- interface HWebApp {
37
- prepare: () => Promise<void>;
38
- // O handler pode ter assinaturas diferentes dependendo do framework
39
- getRequestHandler: () => (req: any, res: any, next?: any) => Promise<void> | void;
40
- setupWebSocket: (server: Server | any) => void; // Aceita http.Server ou app (Express/Fastify)
41
- executeInstrumentation: () => void;
42
- }
43
-
44
- /**
45
- * Estende a request nativa do Node para incluir o body parseado.
46
- */
47
- interface HWebIncomingMessage extends IncomingMessage {
48
- body?: object | string | null;
49
- }
50
-
51
- // --- Helpers ---
52
-
53
- /**
54
- * Encontra o IP externo local (rede)
55
- */
56
- function getLocalExternalIp(): string {
57
- const interfaces = os.networkInterfaces();
58
- for (const name of Object.keys(interfaces)) {
59
- const ifaceList = interfaces[name];
60
- if (ifaceList) {
61
- for (const iface of ifaceList) {
62
- if (iface.family === 'IPv4' && !iface.internal) {
63
- return iface.address;
64
- }
65
- }
66
- }
67
- }
68
- return 'localhost'; // Fallback
69
- }
70
-
71
- const sendBox = (options: HightJSOptions) => {
72
- const isDev = options.dev ? "Running in development mode" : null;
73
-
74
- // 1. Verifica se o SSL está ativado (baseado na mesma lógica do initNativeServer)
75
- const isSSL = options.ssl && options.ssl.key && options.ssl.cert;
76
- const protocol = isSSL ? 'https' : 'http';
77
- const localIp = getLocalExternalIp(); // Assume que getLocalExternalIp() existe
78
-
79
- // 2. Monta as mensagens com o protocolo correto
80
- const messages = [
81
- ` ${Colors.FgGray}┃${Colors.Reset} Local: ${Colors.FgGreen}${protocol}://localhost:${options.port}${Colors.Reset}`,
82
- ];
83
-
84
- // Só adiciona a rede se o IP local for encontrado
85
- if (localIp) {
86
- messages.push(` ${Colors.FgGray}┃${Colors.Reset} Network: ${Colors.FgGreen}${protocol}://${localIp}:${options.port}${Colors.Reset}`);
87
- }
88
-
89
- if (isDev) {
90
- messages.push(` ${Colors.FgGray}┃${Colors.Reset} ${isDev}`);
91
- }
92
-
93
- // Adiciona aviso de redirecionamento se estiver em modo SSL
94
- if (isSSL && options.ssl?.redirectPort) {
95
- messages.push(` ${Colors.FgGray}┃${Colors.Reset} HTTP (port ${options.ssl?.redirectPort}) is redirecting to HTTPS.`);
96
- }
97
-
98
- Console.box(messages.join("\n"), { title: "Access on:" });
99
- }
100
-
101
- /**
102
- * Carrega o arquivo de configuração hightjs.config.ts ou hightjs.config.js do projeto
103
- * @param projectDir Diretório raiz do projeto
104
- * @param phase Fase de execução ('development' ou 'production')
105
- * @returns Configuração mesclada com os valores padrão
106
- */
107
- async function loadHightConfig(projectDir: string, phase: string): Promise<HightConfig> {
108
- const defaultConfig: HightConfig = {
109
- maxHeadersCount: 100,
110
- headersTimeout: 60000,
111
- requestTimeout: 30000,
112
- serverTimeout: 35000,
113
- individualRequestTimeout: 30000,
114
- maxUrlLength: 2048,
115
- accessLogging: true,
116
- };
117
-
118
- try {
119
- // Tenta primeiro .ts, depois .js
120
- const possiblePaths = [
121
- path.join(projectDir, 'hightjs.config.ts'),
122
- path.join(projectDir, 'hightjs.config.js'),
123
- ];
124
-
125
- let configPath: string | null = null;
126
- for (const p of possiblePaths) {
127
- if (fs.existsSync(p)) {
128
- configPath = p;
129
- break;
130
- }
131
- }
132
-
133
- if (!configPath) {
134
- return defaultConfig;
135
- }
136
-
137
- // Remove do cache para permitir hot reload da configuração em dev
138
- delete require.cache[require.resolve(configPath)];
139
-
140
- const configModule = require(configPath);
141
- const configExport = configModule.default || configModule;
142
-
143
- let userConfig: HightConfig;
144
-
145
- if (typeof configExport === 'function') {
146
- // Suporta tanto função síncrona quanto assíncrona
147
- userConfig = await Promise.resolve(
148
- (configExport as HightConfigFunction)(phase, { defaultConfig })
149
- );
150
- } else {
151
- userConfig = configExport;
152
- }
153
-
154
- // Mescla a configuração do usuário com a padrão
155
- const mergedConfig = { ...defaultConfig, ...userConfig };
156
-
157
- const configFileName = path.basename(configPath);
158
- Console.info(`${Colors.FgCyan}[Config]${Colors.Reset} Loaded ${configFileName}`);
159
-
160
- return mergedConfig;
161
- } catch (error) {
162
- if (error instanceof Error) {
163
- Console.warn(`${Colors.FgYellow}[Config]${Colors.Reset} Error loading hightjs.config: ${error.message}`);
164
- Console.warn(`${Colors.FgYellow}[Config]${Colors.Reset} Using default configuration`);
165
- }
166
- return defaultConfig;
167
- }
168
- }
169
-
170
- /**
171
- * Middleware para parsing do body com proteções de segurança (versão melhorada).
172
- * Rejeita a promise em caso de erro de parsing ou estouro de limite.
173
- */
174
- const parseBody = (req: IncomingMessage): Promise<object | string | null> => {
175
- // Constantes para limites de segurança
176
- const MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB limite total
177
- const MAX_JSON_SIZE = 1 * 1024 * 1024; // 1MB limite para JSON
178
- const BODY_TIMEOUT = 30000; // 30 segundos
179
-
180
- return new Promise((resolve, reject) => {
181
- if (req.method === 'GET' || req.method === 'HEAD') {
182
- resolve(null);
183
- return;
184
- }
185
-
186
- let body = '';
187
- let totalSize = 0;
188
-
189
- // Timeout para requisições lentas
190
- const timeout = setTimeout(() => {
191
- req.destroy();
192
- reject(new Error('Request body timeout'));
193
- }, BODY_TIMEOUT);
194
-
195
- req.on('data', (chunk: Buffer) => {
196
- totalSize += chunk.length;
197
-
198
- // Proteção contra DoS (Payload Too Large)
199
- if (totalSize > MAX_BODY_SIZE) {
200
- clearTimeout(timeout);
201
- req.destroy();
202
- reject(new Error('Request body too large'));
203
- return;
204
- }
205
- body += chunk.toString();
206
- });
207
-
208
- req.on('end', () => {
209
- clearTimeout(timeout);
210
-
211
- if (!body) {
212
- resolve(null);
213
- return;
214
- }
215
-
216
- try {
217
- const contentType = req.headers['content-type'] || '';
218
-
219
- if (contentType.includes('application/json')) {
220
- if (body.length > MAX_JSON_SIZE) {
221
- reject(new Error('JSON body too large'));
222
- return;
223
- }
224
- // Rejeita promise se o JSON for inválido
225
- try {
226
- resolve(JSON.parse(body));
227
- } catch (e) {
228
- reject(new Error('Invalid JSON body'));
229
- }
230
- } else if (contentType.includes('application/x-www-form-urlencoded')) {
231
- // Usa API moderna URLSearchParams (segura contra prototype pollution)
232
- resolve(Object.fromEntries(new URLSearchParams(body)));
233
- } else {
234
- resolve(body); // Fallback para texto plano
235
- }
236
- } catch (error) {
237
- // Pega qualquer outro erro síncrono
238
- reject(error);
239
- }
240
- });
241
-
242
- req.on('error', (error: Error) => {
243
- clearTimeout(timeout);
244
- reject(error);
245
- });
246
- });
247
- };
248
-
249
- /**
250
- * Inicializa servidor nativo do HightJS usando HTTP ou HTTPS
251
- */
252
- async function initNativeServer(hwebApp: HWebApp, options: HightJSOptions, port: number, hostname: string) {
253
- const time = Date.now();
254
-
255
- await hwebApp.prepare();
256
-
257
- // Carrega a configuração do arquivo hightjs.config.js
258
- const projectDir = options.dir || process.cwd();
259
- const phase = options.dev ? 'development' : 'production';
260
- const hightConfig = await loadHightConfig(projectDir, phase);
261
-
262
- const handler = hwebApp.getRequestHandler();
263
- const msg = Console.dynamicLine(` ${Colors.BgYellow} ready ${Colors.Reset} ${Colors.Bright}Starting HightJS on port ${options.port}${Colors.Reset}`);
264
-
265
- // --- LÓGICA DO LISTENER (REUTILIZÁVEL) ---
266
- // Extraímos a lógica principal para uma variável
267
- // para que possa ser usada tanto pelo servidor HTTP quanto HTTPS.
268
- const requestListener = async (req: HWebIncomingMessage, res: ServerResponse) => {
269
- const requestStartTime = Date.now();
270
- const method = req.method || 'GET';
271
- const url = req.url || '/';
272
-
273
- // Configurações de segurança básicas
274
- res.setHeader('X-Content-Type-Options', 'nosniff');
275
- res.setHeader('X-Frame-Options', 'DENY');
276
- res.setHeader('X-XSS-Protection', '1; mode=block');
277
- res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
278
-
279
- // IMPORTANTE: Adiciona HSTS (Strict-Transport-Security) se estiver em modo SSL
280
- // Isso força o navegador a usar HTTPS no futuro.
281
- if (options.ssl) {
282
- res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
283
- }
284
-
285
- // Timeout por requisição (usa configuração personalizada)
286
- req.setTimeout(hightConfig.individualRequestTimeout || 30000, () => {
287
- res.statusCode = 408; // Request Timeout
288
- res.end('Request timeout');
289
-
290
- // Log de timeout
291
- if (hightConfig.accessLogging) {
292
- const duration = Date.now() - requestStartTime;
293
- Console.info(`${Colors.FgYellow}${method}${Colors.Reset} ${url} ${Colors.FgRed}408${Colors.Reset} ${Colors.FgGray}${duration}ms${Colors.Reset}`);
294
- }
295
- });
296
-
297
- // Intercepta o método end() para logar quando a resposta for enviada
298
- const originalEnd = res.end.bind(res);
299
- let hasEnded = false;
300
-
301
- res.end = function(this: ServerResponse, ...args: any[]): any {
302
- if (!hasEnded && hightConfig.accessLogging) {
303
- hasEnded = true;
304
- const duration = Date.now() - requestStartTime;
305
- const statusCode = res.statusCode || 200;
306
-
307
- // Define cor baseada no status code
308
- let statusColor = Colors.FgGreen; // 2xx
309
- if (statusCode >= 500) statusColor = Colors.FgRed; // 5xx
310
- else if (statusCode >= 400) statusColor = Colors.FgYellow; // 4xx
311
- else if (statusCode >= 300) statusColor = Colors.FgCyan; // 3xx
312
-
313
- // Formata o método com cor
314
- let methodColor = Colors.BgCyan;
315
- if (method === 'POST') methodColor = Colors.BgGreen;
316
- else if (method === 'PUT') methodColor = Colors.BgYellow;
317
- else if (method === 'DELETE') methodColor = Colors.BgRed;
318
- else if (method === 'PATCH') methodColor = Colors.BgMagenta;
319
- Console.logCustomLevel(method, true, methodColor, `${url} ${statusColor}${statusCode}${Colors.Reset} ${Colors.FgGray}${duration}ms${Colors.Reset}`);
320
- }
321
- // @ts-ignore
322
- return originalEnd.apply(this, args);
323
- } as any;
324
-
325
- try {
326
- // Validação básica de URL (usa configuração personalizada)
327
- const maxUrlLength = hightConfig.maxUrlLength || 2048;
328
- if (url.length > maxUrlLength) {
329
- res.statusCode = 414; // URI Too Long
330
- res.end('URL too long');
331
- return;
332
- }
333
-
334
- // Parse do body com proteções
335
- req.body = await parseBody(req); // Assumindo que parseBody existe
336
-
337
- // Adiciona host se não existir (necessário para `new URL`)
338
- req.headers.host = req.headers.host || `localhost:${port}`;
339
-
340
- // Chama o handler do HightJS
341
- await handler(req, res);
342
-
343
- } catch (error) {
344
- // Log do erro no servidor
345
- if (error instanceof Error) {
346
- Console.error(`Native server error: ${error.message}`);
347
- } else {
348
- Console.error('Unknown native server error:', error);
349
- }
350
-
351
- // Tratamento de erro (idêntico ao seu original)
352
- if (!res.headersSent) {
353
- res.setHeader('Content-Type', 'text/plain');
354
- if (error instanceof Error) {
355
- if (error.message.includes('too large')) {
356
- res.statusCode = 413; // Payload Too Large
357
- res.end('Request too large');
358
- } else if (error.message.includes('timeout')) {
359
- res.statusCode = 408; // Request Timeout
360
- res.end('Request timeout');
361
- } else if (error.message.includes('Invalid JSON')) {
362
- res.statusCode = 400; // Bad Request
363
- res.end('Invalid JSON body');
364
- } else {
365
- res.statusCode = 500;
366
- res.end('Internal server error');
367
- }
368
- } else {
369
- res.statusCode = 500;
370
- res.end('Internal server error');
371
- }
372
- }
373
- }
374
- };
375
- // --- FIM DO LISTENER ---
376
-
377
- let server: Server | HttpsServer; // O tipo do servidor pode variar
378
- const isSSL = options.ssl && options.ssl.key && options.ssl.cert;
379
-
380
- if (isSSL && options.ssl) {
381
-
382
- const sslOptions = {
383
- key: fs.readFileSync(options.ssl.key),
384
- cert: fs.readFileSync(options.ssl.cert),
385
- ca: options.ssl.ca ? fs.readFileSync(options.ssl.ca) : undefined
386
- };
387
-
388
- // 1. Cria o servidor HTTPS principal
389
- server = https.createServer(sslOptions, requestListener as any); // (any para contornar HWebIncomingMessage)
390
-
391
- // 2. Cria o servidor de REDIRECIONAMENTO (HTTP -> HTTPS)
392
- const httpRedirectPort = options.ssl.redirectPort;
393
- http.createServer((req, res) => {
394
- const host = req.headers['host'] || hostname;
395
- // Remove a porta do host (ex: meusite.com:80)
396
- const hostWithoutPort = host.split(':')[0];
397
-
398
- // Monta a URL de redirecionamento
399
- let redirectUrl = `https://${hostWithoutPort}`;
400
- // Adiciona a porta HTTPS apenas se não for a padrão (443)
401
- if (port !== 443) {
402
- redirectUrl += `:${port}`;
403
- }
404
- redirectUrl += req.url || '/';
405
-
406
- res.writeHead(301, { 'Location': redirectUrl });
407
- res.end();
408
- }).listen(httpRedirectPort, hostname, () => {});
409
-
410
- } else {
411
- // --- MODO HTTP (Original) ---
412
- // Cria o servidor HTTP nativo
413
- server = http.createServer(requestListener as any); // (any para contornar HWebIncomingMessage)
414
- }
415
-
416
- // Configurações de segurança do servidor (usa configuração personalizada)
417
- server.setTimeout(hightConfig.serverTimeout || 35000); // Timeout geral do servidor
418
- server.maxHeadersCount = hightConfig.maxHeadersCount || 100; // Limita número de headers
419
- server.headersTimeout = hightConfig.headersTimeout || 60000; // Timeout para headers
420
- server.requestTimeout = hightConfig.requestTimeout || 30000; // Timeout para requisições
421
-
422
- server.listen(port, hostname, () => {
423
- sendBox({ ...options, port });
424
- msg.end(` ${Colors.BgGreen} ready ${Colors.Reset} ${Colors.Bright}Ready on port ${Colors.BgGreen} ${options.port} ${Colors.Reset}${Colors.Bright} in ${Date.now() - time}ms${Colors.Reset}\n`);
425
- });
426
-
427
- // Configura WebSocket para hot reload (Comum a ambos)
428
- hwebApp.setupWebSocket(server);
429
- hwebApp.executeInstrumentation();
430
- return server;
431
- }
432
-
433
- // --- Função Principal ---
434
-
435
- export function app(options: HightJSOptions = {}) {
436
- const framework = options.framework || 'native';
437
- FrameworkAdapterFactory.setFramework(framework)
438
-
439
- // Tipando a app principal do hweb
440
- const hwebApp: HWebApp = hweb(options);
441
-
442
- return {
443
- ...hwebApp,
444
-
445
- /**
446
- * Integra com uma aplicação de qualquer framework (Express, Fastify, etc)
447
- * O 'serverApp: any' é mantido para flexibilidade, já que pode ser de tipos diferentes.
448
- */
449
- integrate: async (serverApp: any) => {
450
- await hwebApp.prepare();
451
- const handler = hwebApp.getRequestHandler();
452
-
453
- // O framework é setado nas opções do hweb, que deve
454
- // retornar o handler correto em getRequestHandler()
455
- // A lógica de integração original parece correta.
456
-
457
- if (framework === 'express') {
458
- const express = require('express');
459
- try {
460
- const cookieParser = require('cookie-parser');
461
- serverApp.use(cookieParser());
462
- } catch (e) {
463
- Console.error("Could not find cookie-parser");
464
- }
465
- serverApp.use(express.json());
466
- serverApp.use(express.urlencoded({ extended: true }));
467
- serverApp.use(handler);
468
- hwebApp.setupWebSocket(serverApp);
469
-
470
- } else if (framework === 'fastify') {
471
- try {
472
- await serverApp.register(require('@fastify/cookie'));
473
- } catch (e) {
474
- Console.error("Could not find @fastify/cookie");
475
- }
476
- try {
477
- await serverApp.register(require('@fastify/formbody'));
478
- } catch (e) {
479
- Console.error("Could not find @fastify/formbody");
480
- }
481
- await serverApp.register(async (fastify: any) => {
482
- fastify.all('*', handler);
483
- });
484
- hwebApp.setupWebSocket(serverApp);
485
-
486
- } else {
487
- // Generic integration (assume Express-like)
488
- serverApp.use(handler);
489
- hwebApp.setupWebSocket(serverApp);
490
- }
491
-
492
- hwebApp.executeInstrumentation();
493
- return serverApp;
494
- },
495
-
496
- /**
497
- * Inicia um servidor HightJS fechado (o usuário não tem acesso ao framework)
498
- */
499
- init: async () => {
500
- const currentVersion = require('../package.json').version;
501
-
502
- async function verifyVersion(): Promise<string> {
503
- // node fetch
504
- try {
505
- const response = await fetch('https://registry.npmjs.org/hightjs/latest');
506
- const data = await response.json();
507
- return data.version;
508
- } catch (error) {
509
- Console.error('Could not check for the latest HightJS version:', error);
510
- return currentVersion; // Retorna a versão atual em caso de erro
511
- }
512
- }
513
- const latestVersion = await verifyVersion();
514
- const isUpToDate = latestVersion === currentVersion;
515
- let message;
516
- if (!isUpToDate) {
517
- message = `${Colors.FgGreen} A new version is available (v${latestVersion})${Colors.FgMagenta}`
518
- } else {
519
- message = `${Colors.FgGreen} You are on the latest version${Colors.FgMagenta}`
520
- }
521
- console.log(`${Colors.FgMagenta}
522
- __ ___ ${Colors.FgGreen} __ ${Colors.FgMagenta}
523
- |__| | / _\` |__| | ${Colors.FgGreen} | /__\` ${Colors.FgMagenta} ${Colors.FgMagenta}HightJS ${Colors.FgGray}(v${require('../package.json').version}) - itsmuzin${Colors.FgMagenta}
524
- | | | \\__> | | | ${Colors.FgGreen}\\__/ .__/ ${message}
525
- ${Colors.Reset}`);
526
-
527
- const actualPort = options.port || 3000;
528
- const actualHostname = options.hostname || "0.0.0.0";
529
-
530
- if (framework !== 'native') {
531
- Console.warn(`The "${framework}" framework was selected, but the init() method only works with the "native" framework. Starting native server...`);
532
- }
533
-
534
-
535
-
536
- return await initNativeServer(hwebApp, options, actualPort, actualHostname);
537
- }
538
- }
539
- }
540
-
541
- // Exporta a função 'app' como nomeada e também como padrão
542
- export default app;