hightjs 0.1.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.
Files changed (131) hide show
  1. package/.idea/HightJS.iml +9 -0
  2. package/.idea/copilot.data.migration.agent.xml +6 -0
  3. package/.idea/copilot.data.migration.ask.xml +6 -0
  4. package/.idea/copilot.data.migration.ask2agent.xml +6 -0
  5. package/.idea/copilot.data.migration.edit.xml +6 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +13 -0
  7. package/.idea/libraries/test_package.xml +9 -0
  8. package/.idea/libraries/ts_commonjs_default_export.xml +9 -0
  9. package/.idea/misc.xml +7 -0
  10. package/.idea/modules.xml +8 -0
  11. package/.idea/vcs.xml +6 -0
  12. package/LICENSE +13 -0
  13. package/README.md +508 -0
  14. package/dist/adapters/express.d.ts +7 -0
  15. package/dist/adapters/express.js +63 -0
  16. package/dist/adapters/factory.d.ts +23 -0
  17. package/dist/adapters/factory.js +122 -0
  18. package/dist/adapters/fastify.d.ts +25 -0
  19. package/dist/adapters/fastify.js +61 -0
  20. package/dist/adapters/native.d.ts +8 -0
  21. package/dist/adapters/native.js +203 -0
  22. package/dist/adapters/starters/express.d.ts +0 -0
  23. package/dist/adapters/starters/express.js +1 -0
  24. package/dist/adapters/starters/factory.d.ts +0 -0
  25. package/dist/adapters/starters/factory.js +1 -0
  26. package/dist/adapters/starters/fastify.d.ts +0 -0
  27. package/dist/adapters/starters/fastify.js +1 -0
  28. package/dist/adapters/starters/index.d.ts +0 -0
  29. package/dist/adapters/starters/index.js +1 -0
  30. package/dist/adapters/starters/native.d.ts +0 -0
  31. package/dist/adapters/starters/native.js +1 -0
  32. package/dist/api/console.d.ts +92 -0
  33. package/dist/api/console.js +276 -0
  34. package/dist/api/http.d.ts +180 -0
  35. package/dist/api/http.js +467 -0
  36. package/dist/auth/client.d.ts +14 -0
  37. package/dist/auth/client.js +68 -0
  38. package/dist/auth/components.d.ts +29 -0
  39. package/dist/auth/components.js +84 -0
  40. package/dist/auth/core.d.ts +38 -0
  41. package/dist/auth/core.js +124 -0
  42. package/dist/auth/index.d.ts +7 -0
  43. package/dist/auth/index.js +27 -0
  44. package/dist/auth/jwt.d.ts +41 -0
  45. package/dist/auth/jwt.js +169 -0
  46. package/dist/auth/providers.d.ts +5 -0
  47. package/dist/auth/providers.js +14 -0
  48. package/dist/auth/react/index.d.ts +6 -0
  49. package/dist/auth/react/index.js +32 -0
  50. package/dist/auth/react.d.ts +22 -0
  51. package/dist/auth/react.js +175 -0
  52. package/dist/auth/routes.d.ts +16 -0
  53. package/dist/auth/routes.js +104 -0
  54. package/dist/auth/types.d.ts +62 -0
  55. package/dist/auth/types.js +2 -0
  56. package/dist/bin/hightjs.d.ts +2 -0
  57. package/dist/bin/hightjs.js +35 -0
  58. package/dist/builder.d.ts +32 -0
  59. package/dist/builder.js +341 -0
  60. package/dist/client/DefaultNotFound.d.ts +1 -0
  61. package/dist/client/DefaultNotFound.js +53 -0
  62. package/dist/client/ErrorBoundary.d.ts +16 -0
  63. package/dist/client/ErrorBoundary.js +181 -0
  64. package/dist/client/clientRouter.d.ts +58 -0
  65. package/dist/client/clientRouter.js +116 -0
  66. package/dist/client/entry.client.d.ts +1 -0
  67. package/dist/client/entry.client.js +271 -0
  68. package/dist/client/routerContext.d.ts +26 -0
  69. package/dist/client/routerContext.js +62 -0
  70. package/dist/client.d.ts +3 -0
  71. package/dist/client.js +8 -0
  72. package/dist/components/Link.d.ts +7 -0
  73. package/dist/components/Link.js +13 -0
  74. package/dist/eslint/index.d.ts +32 -0
  75. package/dist/eslint/index.js +15 -0
  76. package/dist/eslint/use-client-rule.d.ts +19 -0
  77. package/dist/eslint/use-client-rule.js +99 -0
  78. package/dist/eslintSetup.d.ts +0 -0
  79. package/dist/eslintSetup.js +1 -0
  80. package/dist/example/src/web/routes/index.d.ts +3 -0
  81. package/dist/example/src/web/routes/index.js +15 -0
  82. package/dist/helpers.d.ts +18 -0
  83. package/dist/helpers.js +318 -0
  84. package/dist/hotReload.d.ts +23 -0
  85. package/dist/hotReload.js +292 -0
  86. package/dist/index.d.ts +17 -0
  87. package/dist/index.js +480 -0
  88. package/dist/renderer.d.ts +14 -0
  89. package/dist/renderer.js +106 -0
  90. package/dist/router.d.ts +78 -0
  91. package/dist/router.js +359 -0
  92. package/dist/types/framework.d.ts +37 -0
  93. package/dist/types/framework.js +2 -0
  94. package/dist/types.d.ts +43 -0
  95. package/dist/types.js +2 -0
  96. package/dist/typescript/use-client-plugin.d.ts +5 -0
  97. package/dist/typescript/use-client-plugin.js +113 -0
  98. package/dist/validation.d.ts +0 -0
  99. package/dist/validation.js +1 -0
  100. package/package.json +72 -0
  101. package/src/adapters/express.ts +70 -0
  102. package/src/adapters/factory.ts +96 -0
  103. package/src/adapters/fastify.ts +88 -0
  104. package/src/adapters/native.ts +223 -0
  105. package/src/api/console.ts +285 -0
  106. package/src/api/http.ts +515 -0
  107. package/src/auth/client.ts +74 -0
  108. package/src/auth/components.tsx +109 -0
  109. package/src/auth/core.ts +143 -0
  110. package/src/auth/index.ts +9 -0
  111. package/src/auth/jwt.ts +194 -0
  112. package/src/auth/providers.ts +13 -0
  113. package/src/auth/react/index.ts +9 -0
  114. package/src/auth/react.tsx +209 -0
  115. package/src/auth/routes.ts +133 -0
  116. package/src/auth/types.ts +73 -0
  117. package/src/bin/hightjs.js +40 -0
  118. package/src/builder.js +362 -0
  119. package/src/client/DefaultNotFound.tsx +68 -0
  120. package/src/client/clientRouter.ts +137 -0
  121. package/src/client/entry.client.tsx +302 -0
  122. package/src/client.ts +8 -0
  123. package/src/components/Link.tsx +22 -0
  124. package/src/helpers.ts +316 -0
  125. package/src/hotReload.ts +289 -0
  126. package/src/index.ts +514 -0
  127. package/src/renderer.tsx +122 -0
  128. package/src/router.ts +400 -0
  129. package/src/types/framework.ts +42 -0
  130. package/src/types.ts +54 -0
  131. package/tsconfig.json +17 -0
@@ -0,0 +1,23 @@
1
+ import { FrameworkAdapter } from '../types/framework';
2
+ /**
3
+ * Factory para criar o adapter correto baseado no framework detectado
4
+ */
5
+ export declare class FrameworkAdapterFactory {
6
+ private static adapter;
7
+ /**
8
+ * Detecta automaticamente o framework baseado na requisição/resposta
9
+ */
10
+ static detectFramework(req: any, res: any): FrameworkAdapter;
11
+ /**
12
+ * Força o uso de um framework específico
13
+ */
14
+ static setFramework(framework: 'express' | 'fastify' | 'native'): void;
15
+ /**
16
+ * Reset do adapter (útil para testes)
17
+ */
18
+ static reset(): void;
19
+ /**
20
+ * Retorna o adapter atual (se já foi detectado)
21
+ */
22
+ static getCurrentAdapter(): FrameworkAdapter | null;
23
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FrameworkAdapterFactory = void 0;
37
+ const express_1 = require("./express");
38
+ const fastify_1 = require("./fastify");
39
+ const native_1 = require("./native");
40
+ const console_1 = __importStar(require("../api/console"));
41
+ /**
42
+ * Factory para criar o adapter correto baseado no framework detectado
43
+ */
44
+ class FrameworkAdapterFactory {
45
+ /**
46
+ * Detecta automaticamente o framework baseado na requisição/resposta
47
+ */
48
+ static detectFramework(req, res) {
49
+ // Se já detectamos antes, retorna o mesmo adapter
50
+ if (this.adapter) {
51
+ return this.adapter;
52
+ }
53
+ const msg = console_1.default.dynamicLine(` ${console_1.Colors.FgYellow}● ${console_1.Colors.Reset}Detectando framework web...`);
54
+ // Detecta Express
55
+ if (req.app && req.route && res.locals !== undefined) {
56
+ msg.end(` ${console_1.Colors.FgGreen}● ${console_1.Colors.Reset}Framework detectado: Express`);
57
+ this.adapter = new express_1.ExpressAdapter();
58
+ return this.adapter;
59
+ }
60
+ // Detecta Fastify
61
+ if (req.server && req.routerPath !== undefined && res.request) {
62
+ msg.end(` ${console_1.Colors.FgGreen}● ${console_1.Colors.Reset}Framework detectado: Fastify`);
63
+ this.adapter = new fastify_1.FastifyAdapter();
64
+ return this.adapter;
65
+ }
66
+ // Detecta HTTP nativo do Node.js
67
+ if (req.method !== undefined && req.url !== undefined && req.headers !== undefined &&
68
+ res.statusCode !== undefined && res.setHeader !== undefined && res.end !== undefined) {
69
+ msg.end(` ${console_1.Colors.FgGreen}● ${console_1.Colors.Reset}Framework detectado: HightJS Native (HTTP)`);
70
+ this.adapter = new native_1.NativeAdapter();
71
+ return this.adapter;
72
+ }
73
+ // Fallback mais específico para Express
74
+ if (res.status && res.send && res.json && res.cookie) {
75
+ msg.end(` ${console_1.Colors.FgGreen}● ${console_1.Colors.Reset}Framework detectado: Express (fallback)`);
76
+ this.adapter = new express_1.ExpressAdapter();
77
+ return this.adapter;
78
+ }
79
+ // Fallback mais específico para Fastify
80
+ if (res.code && res.send && res.type && res.setCookie) {
81
+ msg.end(` ${console_1.Colors.FgGreen}● ${console_1.Colors.Reset}Framework detectado: Fastify (fallback)`);
82
+ this.adapter = new fastify_1.FastifyAdapter();
83
+ return this.adapter;
84
+ }
85
+ // Default para HightJS Native se não conseguir detectar
86
+ msg.end(` ${console_1.Colors.FgYellow}● ${console_1.Colors.Reset}Não foi possível detectar o framework. Usando HightJS Native como padrão.`);
87
+ this.adapter = new native_1.NativeAdapter();
88
+ return this.adapter;
89
+ }
90
+ /**
91
+ * Força o uso de um framework específico
92
+ */
93
+ static setFramework(framework) {
94
+ switch (framework) {
95
+ case 'express':
96
+ this.adapter = new express_1.ExpressAdapter();
97
+ break;
98
+ case 'fastify':
99
+ this.adapter = new fastify_1.FastifyAdapter();
100
+ break;
101
+ case 'native':
102
+ this.adapter = new native_1.NativeAdapter();
103
+ break;
104
+ default:
105
+ throw new Error(`Framework não suportado: ${framework}`);
106
+ }
107
+ }
108
+ /**
109
+ * Reset do adapter (útil para testes)
110
+ */
111
+ static reset() {
112
+ this.adapter = null;
113
+ }
114
+ /**
115
+ * Retorna o adapter atual (se já foi detectado)
116
+ */
117
+ static getCurrentAdapter() {
118
+ return this.adapter;
119
+ }
120
+ }
121
+ exports.FrameworkAdapterFactory = FrameworkAdapterFactory;
122
+ FrameworkAdapterFactory.adapter = null;
@@ -0,0 +1,25 @@
1
+ interface FastifyRequest {
2
+ method: string;
3
+ url: string;
4
+ headers: Record<string, string | string[]>;
5
+ body?: any;
6
+ query?: Record<string, any>;
7
+ params?: Record<string, string>;
8
+ cookies?: Record<string, string>;
9
+ }
10
+ interface FastifyReply {
11
+ status(code: number): FastifyReply;
12
+ header(name: string, value: string): FastifyReply;
13
+ setCookie(name: string, value: string, options?: any): FastifyReply;
14
+ clearCookie(name: string, options?: any): FastifyReply;
15
+ type(contentType: string): FastifyReply;
16
+ send(data: any): void;
17
+ redirect(url: string): void;
18
+ }
19
+ import { GenericRequest, GenericResponse, FrameworkAdapter } from '../types/framework';
20
+ export declare class FastifyAdapter implements FrameworkAdapter {
21
+ type: "fastify";
22
+ parseRequest(req: FastifyRequest): GenericRequest;
23
+ createResponse(reply: FastifyReply): GenericResponse;
24
+ }
25
+ export {};
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FastifyAdapter = void 0;
4
+ class FastifyAdapter {
5
+ constructor() {
6
+ this.type = 'fastify';
7
+ }
8
+ parseRequest(req) {
9
+ return {
10
+ method: req.method,
11
+ url: req.url,
12
+ headers: req.headers,
13
+ body: req.body,
14
+ query: req.query,
15
+ params: req.params,
16
+ cookies: req.cookies || {},
17
+ raw: req
18
+ };
19
+ }
20
+ createResponse(reply) {
21
+ return new FastifyResponseWrapper(reply);
22
+ }
23
+ }
24
+ exports.FastifyAdapter = FastifyAdapter;
25
+ class FastifyResponseWrapper {
26
+ constructor(reply) {
27
+ this.reply = reply;
28
+ }
29
+ get raw() {
30
+ return this.reply;
31
+ }
32
+ status(code) {
33
+ this.reply.status(code);
34
+ return this;
35
+ }
36
+ header(name, value) {
37
+ this.reply.header(name, value);
38
+ return this;
39
+ }
40
+ cookie(name, value, options) {
41
+ this.reply.setCookie(name, value, options);
42
+ return this;
43
+ }
44
+ clearCookie(name, options) {
45
+ this.reply.clearCookie(name, options);
46
+ return this;
47
+ }
48
+ json(data) {
49
+ this.reply.send(data);
50
+ }
51
+ text(data) {
52
+ this.reply.type('text/plain; charset=utf-8');
53
+ this.reply.send(data);
54
+ }
55
+ send(data) {
56
+ this.reply.send(data);
57
+ }
58
+ redirect(url) {
59
+ this.reply.redirect(url);
60
+ }
61
+ }
@@ -0,0 +1,8 @@
1
+ import type { IncomingMessage, ServerResponse } from 'http';
2
+ import { GenericRequest, GenericResponse, FrameworkAdapter } from '../types/framework';
3
+ export declare class NativeAdapter implements FrameworkAdapter {
4
+ type: "native";
5
+ parseRequest(req: IncomingMessage): GenericRequest;
6
+ createResponse(res: ServerResponse): GenericResponse;
7
+ private parseCookies;
8
+ }
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NativeAdapter = void 0;
4
+ const url_1 = require("url");
5
+ // --- Funções Auxiliares de Segurança ---
6
+ /**
7
+ * Remove caracteres de quebra de linha (\r, \n) de uma string para prevenir
8
+ * ataques de HTTP Header Injection (CRLF Injection).
9
+ * @param value O valor a ser sanitizado.
10
+ * @returns A string sanitizada.
11
+ */
12
+ function sanitizeHeaderValue(value) {
13
+ return String(value).replace(/[\r\n]/g, '');
14
+ }
15
+ /**
16
+ * Valida se o nome de um cookie contém apenas caracteres permitidos pela RFC 6265.
17
+ * Isso previne a criação de cookies com nomes inválidos ou maliciosos.
18
+ * @param name O nome do cookie a ser validado.
19
+ * @returns `true` se o nome for válido, `false` caso contrário.
20
+ */
21
+ function isValidCookieName(name) {
22
+ // A RFC 6265 define 'token' como 1 ou mais caracteres que não são controle nem separadores.
23
+ // Separadores: ( ) < > @ , ; : \ " / [ ] ? = { }
24
+ const validCookieNameRegex = /^[a-zA-Z0-9!#$%&'*+-.^_`|~]+$/;
25
+ return validCookieNameRegex.test(name);
26
+ }
27
+ class NativeAdapter {
28
+ constructor() {
29
+ this.type = 'native';
30
+ }
31
+ parseRequest(req) {
32
+ const url = (0, url_1.parse)(req.url || '', true);
33
+ return {
34
+ method: req.method || 'GET',
35
+ url: req.url || '/',
36
+ headers: req.headers,
37
+ // Adicionado fallback para null para maior segurança caso o body parser não tenha rodado.
38
+ body: req.body ?? null,
39
+ // Tipo mais específico para a query.
40
+ query: url.query,
41
+ params: {}, // Será preenchido pelo roteador
42
+ cookies: this.parseCookies(req.headers.cookie || ''),
43
+ raw: req
44
+ };
45
+ }
46
+ createResponse(res) {
47
+ return new NativeResponseWrapper(res);
48
+ }
49
+ parseCookies(cookieHeader) {
50
+ const cookies = {};
51
+ if (!cookieHeader)
52
+ return cookies;
53
+ cookieHeader.split(';').forEach(cookie => {
54
+ const [name, ...rest] = cookie.trim().split('=');
55
+ if (name && rest.length > 0) {
56
+ try {
57
+ // Tenta decodificar o valor do cookie.
58
+ cookies[name] = decodeURIComponent(rest.join('='));
59
+ }
60
+ catch (e) {
61
+ // Prevenção de crash: Ignora cookies com valores malformados (e.g., URI inválida).
62
+ console.error(`Aviso: Cookie malformado com nome "${name}" foi ignorado.`);
63
+ }
64
+ }
65
+ });
66
+ return cookies;
67
+ }
68
+ }
69
+ exports.NativeAdapter = NativeAdapter;
70
+ class NativeResponseWrapper {
71
+ constructor(res) {
72
+ this.res = res;
73
+ this.statusCode = 200;
74
+ this.headers = {};
75
+ this.cookiesToSet = []; // Array para lidar corretamente com múltiplos cookies.
76
+ this.finished = false;
77
+ }
78
+ get raw() {
79
+ return this.res;
80
+ }
81
+ status(code) {
82
+ this.statusCode = code;
83
+ return this;
84
+ }
85
+ header(name, value) {
86
+ // Medida de segurança CRÍTICA: Previne HTTP Header Injection (CRLF Injection).
87
+ // Sanitiza tanto o nome quanto o valor do header para remover quebras de linha.
88
+ const sanitizedName = sanitizeHeaderValue(name);
89
+ const sanitizedValue = sanitizeHeaderValue(value);
90
+ if (name !== sanitizedName || String(value) !== sanitizedValue) {
91
+ console.warn(`Aviso: Tentativa potencial de HTTP Header Injection foi detectada e sanitizada. Header original: "${name}"`);
92
+ }
93
+ // Evita setar o header 'Set-Cookie' diretamente para não conflitar com o método cookie().
94
+ if (sanitizedName.toLowerCase() === 'set-cookie') {
95
+ console.warn(`Aviso: Use o método .cookie() para definir cookies, não o .header().`);
96
+ return this;
97
+ }
98
+ this.headers[sanitizedName] = sanitizedValue;
99
+ return this;
100
+ }
101
+ cookie(name, value, options) {
102
+ // Medida de segurança: Valida o nome do cookie.
103
+ if (!isValidCookieName(name)) {
104
+ console.error(`Erro: Nome de cookie inválido "${name}". O cookie não será definido.`);
105
+ return this;
106
+ }
107
+ let cookieString = `${name}=${encodeURIComponent(value)}`;
108
+ if (options) {
109
+ // Sanitiza as opções que são strings para prevenir Header Injection.
110
+ if (options.domain)
111
+ cookieString += `; Domain=${sanitizeHeaderValue(options.domain)}`;
112
+ if (options.path)
113
+ cookieString += `; Path=${sanitizeHeaderValue(options.path)}`;
114
+ if (options.expires)
115
+ cookieString += `; Expires=${options.expires.toUTCString()}`;
116
+ if (options.maxAge)
117
+ cookieString += `; Max-Age=${options.maxAge}`;
118
+ if (options.httpOnly)
119
+ cookieString += '; HttpOnly';
120
+ if (options.secure)
121
+ cookieString += '; Secure';
122
+ if (options.sameSite) {
123
+ const sameSiteValue = typeof options.sameSite === 'boolean' ? 'Strict' : options.sameSite;
124
+ cookieString += `; SameSite=${sanitizeHeaderValue(sameSiteValue)}`;
125
+ }
126
+ }
127
+ this.cookiesToSet.push(cookieString);
128
+ return this;
129
+ }
130
+ clearCookie(name, options) {
131
+ const clearOptions = { ...options, expires: new Date(0), maxAge: 0 };
132
+ return this.cookie(name, '', clearOptions);
133
+ }
134
+ writeHeaders() {
135
+ if (this.finished)
136
+ return;
137
+ this.res.statusCode = this.statusCode;
138
+ Object.entries(this.headers).forEach(([name, value]) => {
139
+ this.res.setHeader(name, value);
140
+ });
141
+ // CORREÇÃO: Envia múltiplos cookies corretamente como headers 'Set-Cookie' separados.
142
+ // O método antigo de juntar com vírgula estava incorreto.
143
+ if (this.cookiesToSet.length > 0) {
144
+ this.res.setHeader('Set-Cookie', this.cookiesToSet);
145
+ }
146
+ }
147
+ json(data) {
148
+ if (this.finished)
149
+ return;
150
+ this.header('Content-Type', 'application/json; charset=utf-8');
151
+ this.writeHeaders();
152
+ const jsonString = JSON.stringify(data);
153
+ this.res.end(jsonString);
154
+ this.finished = true;
155
+ }
156
+ text(data) {
157
+ if (this.finished)
158
+ return;
159
+ this.header('Content-Type', 'text/plain; charset=utf-8');
160
+ this.writeHeaders();
161
+ this.res.end(data);
162
+ this.finished = true;
163
+ }
164
+ send(data) {
165
+ if (this.finished)
166
+ return;
167
+ const existingContentType = this.headers['Content-Type'];
168
+ if (typeof data === 'string') {
169
+ if (!existingContentType) {
170
+ this.header('Content-Type', 'text/plain; charset=utf-8');
171
+ }
172
+ this.writeHeaders();
173
+ this.res.end(data);
174
+ }
175
+ else if (Buffer.isBuffer(data)) {
176
+ this.writeHeaders();
177
+ this.res.end(data);
178
+ }
179
+ else if (data !== null && typeof data === 'object') {
180
+ this.json(data); // Reutiliza o método json para consistência
181
+ return; // O método json já finaliza a resposta
182
+ }
183
+ else {
184
+ if (!existingContentType) {
185
+ this.header('Content-Type', 'text/plain; charset=utf-8');
186
+ }
187
+ this.writeHeaders();
188
+ this.res.end(String(data));
189
+ }
190
+ this.finished = true;
191
+ }
192
+ redirect(url) {
193
+ if (this.finished)
194
+ return;
195
+ this.status(302);
196
+ // A sanitização no método .header() previne que um URL manipulado
197
+ // cause um ataque de Open Redirect via Header Injection.
198
+ this.header('Location', url);
199
+ this.writeHeaders();
200
+ this.res.end();
201
+ this.finished = true;
202
+ }
203
+ }
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,92 @@
1
+ import { Options as BoxenOptions } from 'boxen';
2
+ /**
3
+ * Um "handle" para uma linha dinâmica. As instâncias desta classe
4
+ * são retornadas por `Console.dynamicLine()` e usadas para controlar
5
+ * o conteúdo da linha.
6
+ */
7
+ export declare class DynamicLine {
8
+ private readonly _id;
9
+ constructor(initialContent: string);
10
+ /**
11
+ * Atualiza o conteúdo da linha no console.
12
+ * @param newContent O novo texto a ser exibido.
13
+ */
14
+ update(newContent: string): void;
15
+ /**
16
+ * Finaliza a linha, opcionalmente com um texto final, e a torna estática.
17
+ * @param finalContent O texto final a ser exibido.
18
+ */
19
+ end(finalContent: string): void;
20
+ }
21
+ export declare enum Colors {
22
+ Reset = "\u001B[0m",
23
+ Bright = "\u001B[1m",
24
+ Dim = "\u001B[2m",
25
+ Underscore = "\u001B[4m",
26
+ Blink = "\u001B[5m",
27
+ Reverse = "\u001B[7m",
28
+ Hidden = "\u001B[8m",
29
+ FgBlack = "\u001B[30m",
30
+ FgRed = "\u001B[31m",
31
+ FgGreen = "\u001B[32m",
32
+ FgYellow = "\u001B[33m",
33
+ FgBlue = "\u001B[34m",
34
+ FgMagenta = "\u001B[35m",
35
+ FgCyan = "\u001B[36m",
36
+ FgWhite = "\u001B[37m",
37
+ BgBlack = "\u001B[40m",
38
+ BgRed = "\u001B[41m",
39
+ BgGreen = "\u001B[42m",
40
+ BgYellow = "\u001B[43m",
41
+ BgBlue = "\u001B[44m",
42
+ BgMagenta = "\u001B[45m",
43
+ BgCyan = "\u001B[46m",
44
+ BgWhite = "\u001B[47m"
45
+ }
46
+ export declare enum Levels {
47
+ ERROR = "ERROR",
48
+ WARN = "WARN",
49
+ INFO = "INFO",
50
+ DEBUG = "DEBUG",
51
+ SUCCESS = "SUCCESS"
52
+ }
53
+ export default class Console {
54
+ private static activeLines;
55
+ private static lastRenderedLines;
56
+ /**
57
+ * Limpa todas as linhas dinâmicas da tela e as redesenha com o conteúdo atualizado.
58
+ * Observação: usamos lastRenderedLines para saber quantas linhas mover
59
+ * o cursor para cima (isso evita mover para cima demais quando uma nova
60
+ * linha foi registrada).
61
+ */
62
+ private static redrawDynamicLines;
63
+ /**
64
+ * Envolve a escrita de texto estático (logs normais) para não interferir
65
+ * com as linhas dinâmicas.
66
+ */
67
+ private static writeStatic;
68
+ private static registerDynamicLine;
69
+ private static updateDynamicLine;
70
+ private static endDynamicLine;
71
+ static error(...args: any[]): void;
72
+ static warn(...args: any[]): void;
73
+ static info(...args: any[]): void;
74
+ static success(...args: any[]): void;
75
+ static debug(...args: any[]): void;
76
+ static logCustomLevel(levelName: string, without?: boolean, ...args: any[]): void;
77
+ static logWithout(level: Levels, ...args: any[]): void;
78
+ static log(level: Levels, ...args: any[]): void;
79
+ static ask(question: string, defaultValue?: string): Promise<string>;
80
+ static confirm(message: string, defaultYes?: boolean): Promise<boolean>;
81
+ static table(data: Record<string, any> | Array<{
82
+ Field: string;
83
+ Value: any;
84
+ }>): void;
85
+ static box(content: string, options?: BoxenOptions): void;
86
+ /**
87
+ * Cria e retorna um controlador para uma linha dinâmica no console.
88
+ * @param initialContent O conteúdo inicial a ser exibido.
89
+ * @returns Uma instância de DynamicLine para controlar a linha.
90
+ */
91
+ static dynamicLine(initialContent: string): DynamicLine;
92
+ }