hightjs 0.2.43 → 0.2.46
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/README.md +22 -562
- package/dist/bin/hightjs.js +393 -0
- package/dist/index.js +2 -0
- package/dist/renderer.js +2 -1
- package/dist/router.js +0 -1
- package/docs/README.md +59 -0
- package/docs/adapters.md +7 -0
- package/docs/arquivos-especiais.md +10 -0
- package/docs/autenticacao.md +212 -0
- package/docs/checklist.md +9 -0
- package/docs/cli.md +21 -0
- package/docs/estrutura.md +20 -0
- package/docs/faq.md +10 -0
- package/docs/hot-reload.md +5 -0
- package/docs/middlewares.md +73 -0
- package/docs/rotas-backend.md +45 -0
- package/docs/rotas-frontend.md +66 -0
- package/docs/seguranca.md +8 -0
- package/docs/websocket.md +45 -0
- package/package.json +1 -1
- package/src/bin/hightjs.js +475 -0
- package/src/index.ts +2 -0
- package/src/renderer.tsx +2 -1
- package/src/router.ts +0 -1
- package/dist/adapters/starters/express.d.ts +0 -0
- package/dist/adapters/starters/express.js +0 -1
- package/dist/adapters/starters/factory.d.ts +0 -0
- package/dist/adapters/starters/factory.js +0 -1
- package/dist/adapters/starters/fastify.d.ts +0 -0
- package/dist/adapters/starters/fastify.js +0 -1
- package/dist/adapters/starters/index.d.ts +0 -0
- package/dist/adapters/starters/index.js +0 -1
- package/dist/adapters/starters/native.d.ts +0 -0
- package/dist/adapters/starters/native.js +0 -1
- package/dist/auth/example.d.ts +0 -40
- package/dist/auth/example.js +0 -104
- package/dist/client/ErrorBoundary.d.ts +0 -16
- package/dist/client/ErrorBoundary.js +0 -181
- package/dist/client/routerContext.d.ts +0 -26
- package/dist/client/routerContext.js +0 -62
- package/dist/eslint/index.d.ts +0 -32
- package/dist/eslint/index.js +0 -15
- package/dist/eslint/use-client-rule.d.ts +0 -19
- package/dist/eslint/use-client-rule.js +0 -99
- package/dist/eslintSetup.d.ts +0 -0
- package/dist/eslintSetup.js +0 -1
- package/dist/example/src/web/routes/index.d.ts +0 -3
- package/dist/example/src/web/routes/index.js +0 -15
- package/dist/hightweb-global.d.ts +0 -0
- package/dist/hightweb-global.js +0 -1
- package/dist/ssl/selfSigned.d.ts +0 -0
- package/dist/ssl/selfSigned.js +0 -1
- package/dist/types/websocket.d.ts +0 -27
- package/dist/types/websocket.js +0 -2
- package/dist/typescript/use-client-plugin.d.ts +0 -5
- package/dist/typescript/use-client-plugin.js +0 -113
- package/dist/validation.d.ts +0 -0
- package/dist/validation.js +0 -1
- package/src/hightweb-global.ts +0 -1
- package/src/ssl/selfSigned.ts +0 -2
package/README.md
CHANGED
|
@@ -20,19 +20,7 @@ Caso tenha alguma dúvida, entre em contato por uma das redes abaixo:
|
|
|
20
20
|
|
|
21
21
|
- [✨ Principais Recursos](#-principais-recursos)
|
|
22
22
|
- [🚀 Início Rápido](#-início-rápido)
|
|
23
|
-
- [
|
|
24
|
-
- [🖥️ Rotas Frontend (Páginas)](#-rotas-frontend)
|
|
25
|
-
- [🌐 Rotas Backend (API)](#-rotas-backend)
|
|
26
|
-
- [🛜 WebSocket](#-websocket)
|
|
27
|
-
- [🧩 Middlewares](#-middlewares)
|
|
28
|
-
- [🔐 Autenticação (HightJS/auth)](#-autenticação-hightjsauth)
|
|
29
|
-
- [🛠️ CLI](#-cli)
|
|
30
|
-
- [📂 Arquivos Especiais](#-arquivos-especiais)
|
|
31
|
-
- [🧱 Adapters](#-adapters)
|
|
32
|
-
- [🔐 Segurança Interna](#-segurança-interna)
|
|
33
|
-
- [♻️ Hot Reload](#-hot-reload)
|
|
34
|
-
- [❓ FAQ Rápido](#-faq-rápido)
|
|
35
|
-
- [✅ Checklist Mental](#-checklist-mental)
|
|
23
|
+
- [📚 Documentação](#-documentação)
|
|
36
24
|
- [🪪 Licença](#-licença)
|
|
37
25
|
---
|
|
38
26
|
|
|
@@ -125,560 +113,30 @@ Acesse: [http://localhost:3000](http://localhost:3000)
|
|
|
125
113
|
|
|
126
114
|
---
|
|
127
115
|
|
|
128
|
-
##
|
|
116
|
+
## 📚 Documentação
|
|
129
117
|
|
|
130
|
-
|
|
131
|
-
src/
|
|
132
|
-
web/
|
|
133
|
-
layout.tsx // Layout global (opcional)
|
|
134
|
-
notFound.tsx // Página 404 customizada (opcional)
|
|
135
|
-
routes/
|
|
136
|
-
index.tsx // Página inicial "/"
|
|
137
|
-
about.tsx // Página "/about"
|
|
138
|
-
blog.tsx // Rota dinâmica "/blog/123"
|
|
139
|
-
backend/
|
|
140
|
-
routes/
|
|
141
|
-
middleware.ts // Middlewares globais da pasta
|
|
142
|
-
version.ts // Endpoint "/version"
|
|
143
|
-
users/
|
|
144
|
-
middleware.ts // Middlewares só desse grupo
|
|
145
|
-
list.ts // Endpoint "/users/list"
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## 🖥️ Rotas Frontend
|
|
151
|
-
|
|
152
|
-
Cada arquivo em `src/web/routes` é uma página.
|
|
153
|
-
|
|
154
|
-
```tsx
|
|
155
|
-
import { RouteConfig } from 'hightjs/client';
|
|
156
|
-
import React from 'react';
|
|
157
|
-
|
|
158
|
-
function Component() {
|
|
159
|
-
return <h1>HELLO WORLD</h1>;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const config: RouteConfig = {
|
|
163
|
-
pattern: '/thanks2',
|
|
164
|
-
component: Component,
|
|
165
|
-
generateMetadata: () => ({ title: 'HightJS | Thanks' })
|
|
166
|
-
};
|
|
167
|
-
export default config;
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Rotas Dinâmicas com Parâmetros
|
|
171
|
-
|
|
172
|
-
```tsx
|
|
173
|
-
import {RouteConfig} from "hightjs/client";
|
|
174
|
-
import React from "react";
|
|
175
|
-
|
|
176
|
-
function PostPage({ params }: { params: { id: string } }) {
|
|
177
|
-
const id = params.id
|
|
178
|
-
return (
|
|
179
|
-
<div>
|
|
180
|
-
<h1>Post ID: {id}</h1>
|
|
181
|
-
<p>This is the content of post {id}.</p>
|
|
182
|
-
</div>
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const config: RouteConfig = {
|
|
187
|
-
pattern: '/post/[id]',
|
|
188
|
-
component: PostPage,
|
|
189
|
-
generateMetadata: async (params) => ({ title: `Post ${params.id}` })
|
|
190
|
-
};
|
|
191
|
-
export default config
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Layout Global
|
|
196
|
-
|
|
197
|
-
`src/web/layout.tsx`:
|
|
198
|
-
|
|
199
|
-
```tsx
|
|
200
|
-
export const metadata = { title: 'Meu App', description: 'Descrição global' };
|
|
201
|
-
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
202
|
-
return <div>{children}</div>;
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Página 404
|
|
207
|
-
|
|
208
|
-
`src/web/notFound.tsx`:
|
|
209
|
-
|
|
210
|
-
```tsx
|
|
211
|
-
export default function NotFound() {
|
|
212
|
-
return <h1>Página não encontrada</h1>;
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
---
|
|
118
|
+
Documentação completa disponível na pasta `docs/`:
|
|
217
119
|
|
|
218
|
-
|
|
120
|
+
### Fundamentos
|
|
121
|
+
- [📦 Estrutura Recomendada](./docs/estrutura.md)
|
|
122
|
+
- [🖥️ Rotas Frontend](./docs/rotas-frontend.md)
|
|
123
|
+
- [🌐 Rotas Backend](./docs/rotas-backend.md)
|
|
219
124
|
|
|
220
|
-
|
|
221
|
-
|
|
125
|
+
### Recursos Avançados
|
|
126
|
+
- [🛜 WebSocket](./docs/websocket.md)
|
|
127
|
+
- [🧩 Middlewares](./docs/middlewares.md)
|
|
128
|
+
- [🔐 Autenticação](./docs/autenticacao.md)
|
|
222
129
|
|
|
223
|
-
###
|
|
130
|
+
### Ferramentas e Configuração
|
|
131
|
+
- [🛠️ CLI](./docs/cli.md)
|
|
132
|
+
- [📂 Arquivos Especiais](./docs/arquivos-especiais.md)
|
|
133
|
+
- [🧱 Adapters](./docs/adapters.md)
|
|
134
|
+
- [🔐 Segurança Interna](./docs/seguranca.md)
|
|
135
|
+
- [♻️ Hot Reload](./docs/hot-reload.md)
|
|
224
136
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
import { HightJSRequest, HightJSResponse, BackendRouteConfig } from 'hightjs';
|
|
229
|
-
|
|
230
|
-
const route: BackendRouteConfig = {
|
|
231
|
-
pattern: '/version',
|
|
232
|
-
GET: async (_req: HightJSRequest) => {
|
|
233
|
-
return HightJSResponse.json({
|
|
234
|
-
version: '1.0.0',
|
|
235
|
-
name: 'HightJS',
|
|
236
|
-
description: 'Framework web full-stack moderno para Node.js'
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
export default route;
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Suporte a Métodos
|
|
244
|
-
|
|
245
|
-
Defina `GET`, `POST`, `PUT`, `DELETE` (ou só os necessários).
|
|
246
|
-
|
|
247
|
-
### Rotas Dinâmicas Backend
|
|
248
|
-
|
|
249
|
-
`src/web/backend/routes/users/[id].ts` → `/users/123`
|
|
250
|
-
|
|
251
|
-
```ts
|
|
252
|
-
import { BackendRouteConfig, HightJSResponse } from "hightjs";
|
|
253
|
-
|
|
254
|
-
const route: BackendRouteConfig = {
|
|
255
|
-
pattern: '/users/[id]',
|
|
256
|
-
GET: async (req, params) => {
|
|
257
|
-
return HightJSResponse.json({ userId: params.id });
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
export default route;
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
---
|
|
264
|
-
|
|
265
|
-
## 🛜 WebSocket
|
|
266
|
-
|
|
267
|
-
O HightJS possui suporte nativo a WebSockets nas rotas do backend.
|
|
268
|
-
|
|
269
|
-
### Exemplo Prático
|
|
270
|
-
|
|
271
|
-
`src/web/backend/routes/chat.ts`:
|
|
272
|
-
|
|
273
|
-
```ts
|
|
274
|
-
import {BackendRouteConfig, HightJSResponse} from 'hightjs';
|
|
275
|
-
|
|
276
|
-
const route: BackendRouteConfig = {
|
|
277
|
-
pattern: '/api/chat',
|
|
278
|
-
GET: async () => {
|
|
279
|
-
return HightJSResponse.json({ message: 'Chat HTTP endpoint' });
|
|
280
|
-
},
|
|
281
|
-
WS: (ctx) => {
|
|
282
|
-
console.log('Nova conexão WebSocket no chat');
|
|
283
|
-
|
|
284
|
-
ctx.send({
|
|
285
|
-
type: 'welcome',
|
|
286
|
-
message: 'Bem-vindo ao chat!'
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
ctx.ws.on('message', (data) => {
|
|
290
|
-
const message = JSON.parse(data.toString());
|
|
291
|
-
console.log(message)
|
|
292
|
-
// Broadcast para todos exceto o remetente
|
|
293
|
-
ctx.broadcast({
|
|
294
|
-
type: 'message',
|
|
295
|
-
user: message.user,
|
|
296
|
-
text: message.text,
|
|
297
|
-
timestamp: new Date().toISOString()
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
ctx.ws.on('close', () => {
|
|
302
|
-
console.log('Cliente desconectado');
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
export default route;
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
---
|
|
311
|
-
|
|
312
|
-
## 🧩 Middlewares
|
|
313
|
-
|
|
314
|
-
Adicione middlewares:
|
|
315
|
-
|
|
316
|
-
- Direto na rota: `middleware: [...]`
|
|
317
|
-
- Arquivo `middleware.ts` na pasta (auto-carregado)
|
|
318
|
-
|
|
319
|
-
### Interface
|
|
320
|
-
|
|
321
|
-
```ts
|
|
322
|
-
export type HightMiddleware = (
|
|
323
|
-
request: HightJSRequest,
|
|
324
|
-
params: { [key: string]: string },
|
|
325
|
-
next: () => Promise<HightJSResponse>
|
|
326
|
-
) => Promise<HightJSResponse> | HightJSResponse;
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Exemplo por Pasta
|
|
330
|
-
|
|
331
|
-
`src/web/backend/routes/middleware.ts`:
|
|
332
|
-
|
|
333
|
-
```ts
|
|
334
|
-
import {HightJSRequest, HightJSResponse} from 'hightjs';
|
|
335
|
-
|
|
336
|
-
export async function log(
|
|
337
|
-
request: HightJSRequest,
|
|
338
|
-
params: { [key: string]: string },
|
|
339
|
-
next: () => Promise<HightJSResponse>
|
|
340
|
-
): Promise<HightJSResponse> {
|
|
341
|
-
|
|
342
|
-
console.log('[API]', request.method, request.url);
|
|
343
|
-
return next();
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
export async function blockLegacy(
|
|
348
|
-
request: HightJSRequest,
|
|
349
|
-
params: { [key: string]: string },
|
|
350
|
-
next: () => Promise<HightJSResponse>
|
|
351
|
-
): Promise<HightJSResponse> {
|
|
352
|
-
if (request.header('user-agent')?.includes('IE 8')) {
|
|
353
|
-
return HightJSResponse.json({ error: 'Navegador não suportado' }, {status: 400});
|
|
354
|
-
}
|
|
355
|
-
return next();
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
export default [log, blockLegacy];
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Exemplo por Rota
|
|
362
|
-
|
|
363
|
-
```ts
|
|
364
|
-
import {BackendRouteConfig, HightJSRequest, HightJSResponse} from 'hightjs';
|
|
365
|
-
|
|
366
|
-
async function authCheck(
|
|
367
|
-
request: HightJSRequest,
|
|
368
|
-
params: { [key: string]: string },
|
|
369
|
-
next: () => Promise<HightJSResponse>
|
|
370
|
-
): Promise<HightJSResponse> {
|
|
371
|
-
if(!request.header("authorization")) {
|
|
372
|
-
return HightJSResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
373
|
-
}
|
|
374
|
-
return next();
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const route: BackendRouteConfig = {
|
|
378
|
-
pattern: '/secure/data',
|
|
379
|
-
middleware: [authCheck],
|
|
380
|
-
GET: async () => HightJSResponse.json({ secret: true })
|
|
381
|
-
};
|
|
382
|
-
export default route;
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
---
|
|
386
|
-
|
|
387
|
-
## 🔐 Autenticação (HightJS/auth)
|
|
388
|
-
|
|
389
|
-
Autenticação JWT embutida, fácil de configurar.
|
|
390
|
-
O jeito recomendado é criar as rotas diretamente no `auth.ts` e importar onde quiser.
|
|
391
|
-
|
|
392
|
-
### Configuração Básica & Rotas
|
|
393
|
-
|
|
394
|
-
`src/auth.ts`:
|
|
395
|
-
|
|
396
|
-
```ts
|
|
397
|
-
import { CredentialsProvider, DiscordProvider, createAuthRoutes } from 'hightjs/auth';
|
|
398
|
-
import type { AuthConfig } from 'hightjs/auth';
|
|
399
|
-
|
|
400
|
-
export const authConfig: AuthConfig = {
|
|
401
|
-
providers: [
|
|
402
|
-
new CredentialsProvider({
|
|
403
|
-
id: 'credentials',
|
|
404
|
-
name: 'Credentials',
|
|
405
|
-
credentials: {
|
|
406
|
-
username: { label: 'Username', type: 'text', placeholder: 'Digite seu usuário' },
|
|
407
|
-
password: { label: 'Password', type: 'password', placeholder: 'Digite sua senha' }
|
|
408
|
-
},
|
|
409
|
-
async authorize(credentials) {
|
|
410
|
-
if (credentials.username === 'admin' && credentials.password === 'admin') {
|
|
411
|
-
return {
|
|
412
|
-
id: '1',
|
|
413
|
-
username: 'admin',
|
|
414
|
-
email: 'admin@test.com',
|
|
415
|
-
name: 'Administrador',
|
|
416
|
-
testeeee: 'sdondsfndsfndsfodsfo'
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
return null;
|
|
420
|
-
}
|
|
421
|
-
}),
|
|
422
|
-
new DiscordProvider({
|
|
423
|
-
clientId: "ID",
|
|
424
|
-
clientSecret: "TOKEN",
|
|
425
|
-
callbackUrl: "http://localhost:3000/api/auth/callback/discord",
|
|
426
|
-
scope: ['identify', 'email', 'guilds'],
|
|
427
|
-
successUrl: "http://localhost:3000/"
|
|
428
|
-
})
|
|
429
|
-
],
|
|
430
|
-
session: {
|
|
431
|
-
strategy: 'jwt',
|
|
432
|
-
maxAge: 24 * 60 * 60, // 24 horas
|
|
433
|
-
},
|
|
434
|
-
pages: {
|
|
435
|
-
signIn: '/login',
|
|
436
|
-
signOut: '/'
|
|
437
|
-
},
|
|
438
|
-
secret: 'hweb-test-secret-key-change-in-production'
|
|
439
|
-
};
|
|
440
|
-
|
|
441
|
-
// Cria as rotas de autenticação automaticamente
|
|
442
|
-
export const authRoutes = createAuthRoutes(authConfig);
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### Exportando as rotas
|
|
446
|
-
|
|
447
|
-
`src/web/backend/routes/auth.ts`:
|
|
448
|
-
|
|
449
|
-
```ts
|
|
450
|
-
import { authRoutes } from "../../../auth";
|
|
451
|
-
export default authRoutes;
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
### Configurando o Frontend
|
|
455
|
-
|
|
456
|
-
Para usar autenticação no frontend, você precisa configurar o `SessionProvider` no layout:
|
|
457
|
-
|
|
458
|
-
`src/web/layout.tsx`:
|
|
459
|
-
|
|
460
|
-
```tsx
|
|
461
|
-
import { SessionProvider } from 'hightjs/auth/react';
|
|
462
|
-
|
|
463
|
-
export const metadata = { title: 'Meu App', description: 'Descrição global' };
|
|
464
|
-
|
|
465
|
-
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
466
|
-
return (
|
|
467
|
-
<SessionProvider>
|
|
468
|
-
{children}
|
|
469
|
-
</SessionProvider>
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### Fazendo Login no Frontend
|
|
475
|
-
|
|
476
|
-
Exemplo de como implementar login com credenciais e Discord:
|
|
477
|
-
|
|
478
|
-
```tsx
|
|
479
|
-
import { useSession } from 'hightjs/auth/react';
|
|
480
|
-
import React, { useState } from 'react';
|
|
481
|
-
|
|
482
|
-
function LoginPage() {
|
|
483
|
-
const { signIn } = useSession();
|
|
484
|
-
const [username, setUsername] = useState('');
|
|
485
|
-
const [password, setPassword] = useState('');
|
|
486
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
487
|
-
const [error, setError] = useState<string | null>(null);
|
|
488
|
-
|
|
489
|
-
const handleDiscordLogin = async () => {
|
|
490
|
-
await signIn('discord', { redirect: true });
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
const handleLogin = async (e: React.FormEvent) => {
|
|
494
|
-
e.preventDefault();
|
|
495
|
-
setIsLoading(true);
|
|
496
|
-
setError(null);
|
|
497
|
-
|
|
498
|
-
try {
|
|
499
|
-
const result = await signIn('credentials', {
|
|
500
|
-
username: username,
|
|
501
|
-
password: password,
|
|
502
|
-
callbackUrl: '/'
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
if (!result || result.error) {
|
|
506
|
-
setError('Credenciais inválidas. Verifique seus dados e senha.');
|
|
507
|
-
setIsLoading(false);
|
|
508
|
-
return;
|
|
509
|
-
}
|
|
510
|
-
router.push("/")
|
|
511
|
-
} catch (err) {
|
|
512
|
-
setError('Ocorreu um erro inesperado. Tente novamente.');
|
|
513
|
-
setIsLoading(false);
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
return (
|
|
518
|
-
<div>
|
|
519
|
-
<form onSubmit={handleLogin}>
|
|
520
|
-
<input
|
|
521
|
-
type="text"
|
|
522
|
-
value={username}
|
|
523
|
-
onChange={(e) => setUsername(e.target.value)}
|
|
524
|
-
placeholder="Username"
|
|
525
|
-
/>
|
|
526
|
-
<input
|
|
527
|
-
type="password"
|
|
528
|
-
value={password}
|
|
529
|
-
onChange={(e) => setPassword(e.target.value)}
|
|
530
|
-
placeholder="Password"
|
|
531
|
-
/>
|
|
532
|
-
<button type="submit" disabled={isLoading}>Login</button>
|
|
533
|
-
</form>
|
|
534
|
-
|
|
535
|
-
<button onClick={handleDiscordLogin}>Login com Discord</button>
|
|
536
|
-
|
|
537
|
-
{error && <p style={{color: 'red'}}>{error}</p>}
|
|
538
|
-
</div>
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
### Acessando Dados do Usuário
|
|
544
|
-
|
|
545
|
-
Para acessar informações do usuário autenticado:
|
|
546
|
-
|
|
547
|
-
```tsx
|
|
548
|
-
import { useSession } from 'hightjs/auth/react';
|
|
549
|
-
|
|
550
|
-
function UserProfile() {
|
|
551
|
-
const { data: session, status, signOut } = useSession();
|
|
552
|
-
|
|
553
|
-
if (status === 'loading') return <p>Carregando...</p>;
|
|
554
|
-
|
|
555
|
-
if (!session) return <p>Não autenticado</p>;
|
|
556
|
-
|
|
557
|
-
return (
|
|
558
|
-
<div>
|
|
559
|
-
<h1>Bem-vindo, {session.user?.name}</h1>
|
|
560
|
-
<p>Email: {session.user?.email}</p>
|
|
561
|
-
<button onClick={() => signOut()}>Logout</button>
|
|
562
|
-
</div>
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
### Protegendo rotas backend
|
|
568
|
-
|
|
569
|
-
```ts
|
|
570
|
-
import { HightJSRequest } from "hightjs";
|
|
571
|
-
import { BackendRouteConfig, HightJSResponse } from "hightjs";
|
|
572
|
-
import { authRoutes } from "../../../../auth";
|
|
573
|
-
|
|
574
|
-
const route: BackendRouteConfig = {
|
|
575
|
-
pattern: "/api/version",
|
|
576
|
-
GET: async (req: HightJSRequest, params: any) => {
|
|
577
|
-
const session = await authRoutes.auth.getSession(req)
|
|
578
|
-
if (!session) {
|
|
579
|
-
return HightJSResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
580
|
-
}
|
|
581
|
-
return HightJSResponse.json({
|
|
582
|
-
version: "1.0.0",
|
|
583
|
-
name: "HightJS",
|
|
584
|
-
description: "Um framework web full-stack moderno para Node.js",
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
export default route;
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
### Métodos principais
|
|
592
|
-
|
|
593
|
-
- `signIn()` - Fazer login (credenciais ou provider)
|
|
594
|
-
- `signOut()` - Fazer logout
|
|
595
|
-
- `useSession()` - Hook para acessar sessão no frontend
|
|
596
|
-
- `authRoutes.auth.getSession()` - Verificar sessão no backend
|
|
597
|
-
- `authRoutes.auth.isAuthenticated()` - Verificar se está autenticado
|
|
598
|
-
|
|
599
|
-
---
|
|
600
|
-
|
|
601
|
-
## 🛠️ CLI
|
|
602
|
-
|
|
603
|
-
Comandos principais:
|
|
604
|
-
|
|
605
|
-
| Comando | Descrição |
|
|
606
|
-
|--------------------|-------------------------------------------|
|
|
607
|
-
| `npx hight dev` | Modo desenvolvimento (hot reload) |
|
|
608
|
-
| `npx hight start` | Modo produção (usa build gerado) |
|
|
609
|
-
|
|
610
|
-
### Opções
|
|
611
|
-
|
|
612
|
-
- `--port` Porta (default 3000)
|
|
613
|
-
- `--hostname` Host (default 0.0.0.0)
|
|
614
|
-
- `--framework` `native` | `express` | `fastify` (default: native)
|
|
615
|
-
|
|
616
|
-
### Produção
|
|
617
|
-
|
|
618
|
-
```bash
|
|
619
|
-
npx hight start -p 8080
|
|
620
|
-
```
|
|
621
|
-
|
|
622
|
-
---
|
|
623
|
-
|
|
624
|
-
## 📂 Arquivos Especiais
|
|
625
|
-
|
|
626
|
-
| Arquivo | Localização | Função |
|
|
627
|
-
|-----------------------------|---------------------------------------|------------------------------------------------|
|
|
628
|
-
| `layout.tsx` | `/src/web` | Layout global + `export const metadata` |
|
|
629
|
-
| `notFound.tsx` | `/src/web` | Página 404 customizada |
|
|
630
|
-
| `middleware.ts` | dentro de `/src/web/backend/routes` | Middlewares globais por pasta backend |
|
|
631
|
-
| `hightweb.ts` / `.tsx` | `/src/hightweb` | Instrumentação opcional executada no boot |
|
|
632
|
-
| `public/` | `/public` | Arquivos estáticos servidos diretamente |
|
|
633
|
-
|
|
634
|
-
---
|
|
635
|
-
|
|
636
|
-
## 🧱 Adapters
|
|
637
|
-
|
|
638
|
-
Inicie via: `--framework native|express|fastify`
|
|
639
|
-
|
|
640
|
-
- Native: zero dependências extras
|
|
641
|
-
- Express/Fastify: instale peer deps (express ou fastify)
|
|
642
|
-
|
|
643
|
-
---
|
|
644
|
-
|
|
645
|
-
## 🔐 Segurança Interna
|
|
646
|
-
|
|
647
|
-
- Sanitização de headers, cookies e body
|
|
648
|
-
- Limites de tamanho configuráveis
|
|
649
|
-
- Proteção contra JSON malformado
|
|
650
|
-
- Timeout de requisição / body parser nativo
|
|
651
|
-
- JWT com HS256, verificação constant-time
|
|
652
|
-
|
|
653
|
-
---
|
|
654
|
-
|
|
655
|
-
## ♻️ Hot Reload
|
|
656
|
-
|
|
657
|
-
Em modo dev, o cliente abre WebSocket `/hweb-hotreload/`.
|
|
658
|
-
Mudanças em rotas frontend ou backend recarregam automaticamente.
|
|
659
|
-
|
|
660
|
-
---
|
|
661
|
-
|
|
662
|
-
## ❓ FAQ Rápido
|
|
663
|
-
|
|
664
|
-
| Pergunta | Resposta |
|
|
665
|
-
|--------------------------------|-----------------------------------------------------|
|
|
666
|
-
| Precisa Next/Vite? | Não, bundler interno via esbuild. |
|
|
667
|
-
| Dá para usar React 19? | Sim (peer dependency). |
|
|
668
|
-
| Tem SSR? | Atualmente só client-side hydration. |
|
|
669
|
-
| Posso usar CSS/SCSS? | Import normal nos componentes. |
|
|
670
|
-
| Rota de API conflita com página?| Não, rotas backend podem ser qualquer path. |
|
|
671
|
-
|
|
672
|
-
---
|
|
673
|
-
|
|
674
|
-
## ✅ Checklist Mental
|
|
675
|
-
|
|
676
|
-
1. Precisa de página? Crie em `src/web/routes/...`
|
|
677
|
-
2. Precisa de endpoint? Crie em `src/web/backend/routes/...`
|
|
678
|
-
3. Precisa proteger? Use autenticação nas rotas
|
|
679
|
-
4. Precisa middleware? `middleware.ts` ou `middleware: []` na rota
|
|
680
|
-
5. Metadata? `generateMetadata` ou `metadata` no layout
|
|
681
|
-
6. Deploy? `npx hight start`
|
|
137
|
+
### Ajuda
|
|
138
|
+
- [❓ FAQ Rápido](./docs/faq.md)
|
|
139
|
+
- [✅ Checklist Mental](./docs/checklist.md)
|
|
682
140
|
|
|
683
141
|
---
|
|
684
142
|
|
|
@@ -690,3 +148,5 @@ Este projeto está licenciado sob a [Licença Apache 2.0](LICENSE).
|
|
|
690
148
|
|
|
691
149
|
---
|
|
692
150
|
|
|
151
|
+
|
|
152
|
+
|