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.
- package/.idea/HightJS.iml +9 -0
- package/.idea/copilot.data.migration.agent.xml +6 -0
- package/.idea/copilot.data.migration.ask.xml +6 -0
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/copilot.data.migration.edit.xml +6 -0
- package/.idea/inspectionProfiles/Project_Default.xml +13 -0
- package/.idea/libraries/test_package.xml +9 -0
- package/.idea/libraries/ts_commonjs_default_export.xml +9 -0
- package/.idea/misc.xml +7 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/LICENSE +13 -0
- package/README.md +508 -0
- package/dist/adapters/express.d.ts +7 -0
- package/dist/adapters/express.js +63 -0
- package/dist/adapters/factory.d.ts +23 -0
- package/dist/adapters/factory.js +122 -0
- package/dist/adapters/fastify.d.ts +25 -0
- package/dist/adapters/fastify.js +61 -0
- package/dist/adapters/native.d.ts +8 -0
- package/dist/adapters/native.js +203 -0
- package/dist/adapters/starters/express.d.ts +0 -0
- package/dist/adapters/starters/express.js +1 -0
- package/dist/adapters/starters/factory.d.ts +0 -0
- package/dist/adapters/starters/factory.js +1 -0
- package/dist/adapters/starters/fastify.d.ts +0 -0
- package/dist/adapters/starters/fastify.js +1 -0
- package/dist/adapters/starters/index.d.ts +0 -0
- package/dist/adapters/starters/index.js +1 -0
- package/dist/adapters/starters/native.d.ts +0 -0
- package/dist/adapters/starters/native.js +1 -0
- package/dist/api/console.d.ts +92 -0
- package/dist/api/console.js +276 -0
- package/dist/api/http.d.ts +180 -0
- package/dist/api/http.js +467 -0
- package/dist/auth/client.d.ts +14 -0
- package/dist/auth/client.js +68 -0
- package/dist/auth/components.d.ts +29 -0
- package/dist/auth/components.js +84 -0
- package/dist/auth/core.d.ts +38 -0
- package/dist/auth/core.js +124 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.js +27 -0
- package/dist/auth/jwt.d.ts +41 -0
- package/dist/auth/jwt.js +169 -0
- package/dist/auth/providers.d.ts +5 -0
- package/dist/auth/providers.js +14 -0
- package/dist/auth/react/index.d.ts +6 -0
- package/dist/auth/react/index.js +32 -0
- package/dist/auth/react.d.ts +22 -0
- package/dist/auth/react.js +175 -0
- package/dist/auth/routes.d.ts +16 -0
- package/dist/auth/routes.js +104 -0
- package/dist/auth/types.d.ts +62 -0
- package/dist/auth/types.js +2 -0
- package/dist/bin/hightjs.d.ts +2 -0
- package/dist/bin/hightjs.js +35 -0
- package/dist/builder.d.ts +32 -0
- package/dist/builder.js +341 -0
- package/dist/client/DefaultNotFound.d.ts +1 -0
- package/dist/client/DefaultNotFound.js +53 -0
- package/dist/client/ErrorBoundary.d.ts +16 -0
- package/dist/client/ErrorBoundary.js +181 -0
- package/dist/client/clientRouter.d.ts +58 -0
- package/dist/client/clientRouter.js +116 -0
- package/dist/client/entry.client.d.ts +1 -0
- package/dist/client/entry.client.js +271 -0
- package/dist/client/routerContext.d.ts +26 -0
- package/dist/client/routerContext.js +62 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +8 -0
- package/dist/components/Link.d.ts +7 -0
- package/dist/components/Link.js +13 -0
- package/dist/eslint/index.d.ts +32 -0
- package/dist/eslint/index.js +15 -0
- package/dist/eslint/use-client-rule.d.ts +19 -0
- package/dist/eslint/use-client-rule.js +99 -0
- package/dist/eslintSetup.d.ts +0 -0
- package/dist/eslintSetup.js +1 -0
- package/dist/example/src/web/routes/index.d.ts +3 -0
- package/dist/example/src/web/routes/index.js +15 -0
- package/dist/helpers.d.ts +18 -0
- package/dist/helpers.js +318 -0
- package/dist/hotReload.d.ts +23 -0
- package/dist/hotReload.js +292 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +480 -0
- package/dist/renderer.d.ts +14 -0
- package/dist/renderer.js +106 -0
- package/dist/router.d.ts +78 -0
- package/dist/router.js +359 -0
- package/dist/types/framework.d.ts +37 -0
- package/dist/types/framework.js +2 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.js +2 -0
- package/dist/typescript/use-client-plugin.d.ts +5 -0
- package/dist/typescript/use-client-plugin.js +113 -0
- package/dist/validation.d.ts +0 -0
- package/dist/validation.js +1 -0
- package/package.json +72 -0
- package/src/adapters/express.ts +70 -0
- package/src/adapters/factory.ts +96 -0
- package/src/adapters/fastify.ts +88 -0
- package/src/adapters/native.ts +223 -0
- package/src/api/console.ts +285 -0
- package/src/api/http.ts +515 -0
- package/src/auth/client.ts +74 -0
- package/src/auth/components.tsx +109 -0
- package/src/auth/core.ts +143 -0
- package/src/auth/index.ts +9 -0
- package/src/auth/jwt.ts +194 -0
- package/src/auth/providers.ts +13 -0
- package/src/auth/react/index.ts +9 -0
- package/src/auth/react.tsx +209 -0
- package/src/auth/routes.ts +133 -0
- package/src/auth/types.ts +73 -0
- package/src/bin/hightjs.js +40 -0
- package/src/builder.js +362 -0
- package/src/client/DefaultNotFound.tsx +68 -0
- package/src/client/clientRouter.ts +137 -0
- package/src/client/entry.client.tsx +302 -0
- package/src/client.ts +8 -0
- package/src/components/Link.tsx +22 -0
- package/src/helpers.ts +316 -0
- package/src/hotReload.ts +289 -0
- package/src/index.ts +514 -0
- package/src/renderer.tsx +122 -0
- package/src/router.ts +400 -0
- package/src/types/framework.ts +42 -0
- package/src/types.ts +54 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="JAVA_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
+
<exclude-output />
|
|
5
|
+
<content url="file://$MODULE_DIR$" />
|
|
6
|
+
<orderEntry type="inheritedJdk" />
|
|
7
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
8
|
+
</component>
|
|
9
|
+
</module>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<component name="InspectionProjectProfileManager">
|
|
2
|
+
<profile version="1.0">
|
|
3
|
+
<option name="myName" value="Project Default" />
|
|
4
|
+
<inspection_tool class="D" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
|
5
|
+
<inspection_tool class="IncorrectHttpHeaderInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
|
6
|
+
<option name="customHeaders">
|
|
7
|
+
<set>
|
|
8
|
+
<option value="Authorization Bearer {{TOKEN}}" />
|
|
9
|
+
</set>
|
|
10
|
+
</option>
|
|
11
|
+
</inspection_tool>
|
|
12
|
+
</profile>
|
|
13
|
+
</component>
|
package/.idea/misc.xml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="KubernetesApiProvider"><![CDATA[{}]]></component>
|
|
4
|
+
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="ms-21" project-jdk-type="JavaSDK">
|
|
5
|
+
<output url="file://$PROJECT_DIR$/out" />
|
|
6
|
+
</component>
|
|
7
|
+
</project>
|
package/.idea/vcs.xml
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2025 itsmuzin
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
# HightJS
|
|
2
|
+
|
|
3
|
+
> Um framework web full‑stack moderno para Node.js, focado em simplicidade, DX e velocidade. Bundler via esbuild, hot reload, roteamento automático, APIs, autenticação JWT, CLI e muito mais.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📑 Índice
|
|
8
|
+
|
|
9
|
+
- [✨ Principais Recursos](#-principais-recursos)
|
|
10
|
+
- [🚀 Início Rápido](#-início-rápido)
|
|
11
|
+
- [📦 Estrutura Recomendada](#-estrutura-recomendada)
|
|
12
|
+
- [🖥️ Rotas Frontend (Páginas)](#-rotas-frontend)
|
|
13
|
+
- [🌐 Rotas Backend (API)](#-rotas-backend)
|
|
14
|
+
- [🧩 Middlewares](#-middlewares)
|
|
15
|
+
- [🔐 Autenticação (HightJS/auth)](#-autenticação-hightjsauth)
|
|
16
|
+
- [🛠️ CLI](#-cli)
|
|
17
|
+
- [📂 Arquivos Especiais](#-arquivos-especiais)
|
|
18
|
+
- [🧱 Adapters](#-adapters)
|
|
19
|
+
- [🔐 Segurança Interna](#-segurança-interna)
|
|
20
|
+
- [♻️ Hot Reload](#-hot-reload)
|
|
21
|
+
- [❓ FAQ Rápido](#-faq-rápido)
|
|
22
|
+
- [✅ Checklist Mental](#-checklist-mental)
|
|
23
|
+
- [🪪 Licença](#-licença)
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## ✨ Principais Recursos
|
|
27
|
+
|
|
28
|
+
- **Roteamento automático** de páginas [`src/web/routes`] e APIs [`src/web/backend/routes`]
|
|
29
|
+
- **Middlewares** por pasta ou rota
|
|
30
|
+
- **Hot Reload** nativo (WebSocket interno) em dev
|
|
31
|
+
- **Layouts globais** e página 404 customizada
|
|
32
|
+
- **Metadata** dinâmica por página
|
|
33
|
+
- **Build inteligente** (single bundle ou chunks)
|
|
34
|
+
- **Adapters**: Native, Express, Fastify
|
|
35
|
+
- **Autenticação** JWT embutida (HWebAuth)
|
|
36
|
+
- **CLI própria** (`hight`) para dev e produção
|
|
37
|
+
- **Entrega de estáticos** (`public/`)
|
|
38
|
+
- Segurança, saneamento e limitações nativas
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🚀 Início Rápido
|
|
43
|
+
|
|
44
|
+
> O mínimo para rodar!
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm init -y
|
|
48
|
+
npm install typescript --save-dev
|
|
49
|
+
npx tsc --init
|
|
50
|
+
npm install hightjs react@19 react-dom@19 ts-node
|
|
51
|
+
npm install --save-dev @types/react
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Crie um `tsconfig.json` na raiz do projeto:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"compilerOptions": {
|
|
59
|
+
"target": "ES6",
|
|
60
|
+
"module": "CommonJS",
|
|
61
|
+
"jsx": "react",
|
|
62
|
+
"strict": true,
|
|
63
|
+
"esModuleInterop": true,
|
|
64
|
+
"resolveJsonModule": true,
|
|
65
|
+
"skipLibCheck": true,
|
|
66
|
+
"forceConsistentCasingInFileNames": true,
|
|
67
|
+
"outDir": "./dist",
|
|
68
|
+
"moduleResolution": "nodenext"
|
|
69
|
+
},
|
|
70
|
+
"include": ["src/**/*"]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Estrutura mínima:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
src/
|
|
78
|
+
web/
|
|
79
|
+
routes/
|
|
80
|
+
index.tsx
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Exemplo de página inicial em `src/web/routes/index.tsx`:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { RouteConfig } from 'hightjs/client';
|
|
87
|
+
import React from 'react';
|
|
88
|
+
|
|
89
|
+
function Home() {
|
|
90
|
+
return <h1>Bem-vindo ao HightJS 🚀</h1>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const config: RouteConfig = {
|
|
94
|
+
pattern: '/',
|
|
95
|
+
component: Home,
|
|
96
|
+
generateMetadata: () => ({ title: 'HightJS | Home' })
|
|
97
|
+
};
|
|
98
|
+
export default config;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Rode em modo dev:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npx hight dev
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Acesse: [http://localhost:3000](http://localhost:3000)
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 📦 Estrutura Recomendada
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
src/
|
|
115
|
+
web/
|
|
116
|
+
layout.tsx // Layout global (opcional)
|
|
117
|
+
notFound.tsx // Página 404 customizada (opcional)
|
|
118
|
+
routes/
|
|
119
|
+
index.tsx // Página inicial "/"
|
|
120
|
+
about.tsx // Página "/about"
|
|
121
|
+
blog[id].tsx // Rota dinâmica "/blog/123"
|
|
122
|
+
backend/
|
|
123
|
+
routes/
|
|
124
|
+
middleware.ts // Middlewares globais da pasta
|
|
125
|
+
version.ts // Endpoint "/version"
|
|
126
|
+
users/
|
|
127
|
+
middleware.ts // Middlewares só desse grupo
|
|
128
|
+
list.ts // Endpoint "/users/list"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 🖥️ Rotas Frontend
|
|
134
|
+
|
|
135
|
+
Cada arquivo em `src/web/routes` é uma página.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
import { RouteConfig } from 'hightjs/client';
|
|
139
|
+
import React from 'react';
|
|
140
|
+
|
|
141
|
+
function Component() {
|
|
142
|
+
return <h1>HELLO WORLD</h1>;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const config: RouteConfig = {
|
|
146
|
+
pattern: '/thanks2',
|
|
147
|
+
component: Component,
|
|
148
|
+
generateMetadata: () => ({ title: 'HightJS | Thanks' })
|
|
149
|
+
};
|
|
150
|
+
export default config;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Rotas Dinâmicas com Parâmetros
|
|
154
|
+
|
|
155
|
+
Use colchetes: `blog/[slug].tsx` → `/blog/post`.
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import {RouteConfig} from "hightjs/client";
|
|
159
|
+
import React from "react";
|
|
160
|
+
|
|
161
|
+
function PostPage({ params }: { params: { id: string } }) {
|
|
162
|
+
const id = params.id
|
|
163
|
+
return (
|
|
164
|
+
<div>
|
|
165
|
+
<h1>Post ID: {id}</h1>
|
|
166
|
+
<p>This is the content of post {id}.</p>
|
|
167
|
+
</div>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const config: RouteConfig = {
|
|
172
|
+
pattern: '/post/[id]',
|
|
173
|
+
component: PostPage,
|
|
174
|
+
generateMetadata: async (params) => ({ title: `Post ${params.id}` })
|
|
175
|
+
};
|
|
176
|
+
export default config
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Layout Global
|
|
181
|
+
|
|
182
|
+
`src/web/layout.tsx`:
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
export const metadata = { title: 'Meu App', description: 'Descrição global' };
|
|
186
|
+
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
187
|
+
return <div>{children}</div>;
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Página 404
|
|
192
|
+
|
|
193
|
+
`src/web/notFound.tsx`:
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
export default function NotFound() {
|
|
197
|
+
return <h1>Página não encontrada</h1>;
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 🌐 Rotas Backend
|
|
204
|
+
|
|
205
|
+
Qualquer arquivo em `src/web/backend/routes` vira endpoint backend.
|
|
206
|
+
O _pattern_ pode ser qualquer caminho, não só `/api/...`!
|
|
207
|
+
|
|
208
|
+
### Exemplo Simples
|
|
209
|
+
|
|
210
|
+
`src/web/backend/routes/version.ts`:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import { HightJSRequest, HightJSResponse, BackendRouteConfig } from 'hightjs';
|
|
214
|
+
|
|
215
|
+
const route: BackendRouteConfig = {
|
|
216
|
+
pattern: '/version',
|
|
217
|
+
GET: async (_req: HightJSRequest) => {
|
|
218
|
+
return HightJSResponse.json({
|
|
219
|
+
version: '1.0.0',
|
|
220
|
+
name: 'HightJS',
|
|
221
|
+
description: 'Framework web full-stack moderno para Node.js'
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
export default route;
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Suporte a Métodos
|
|
229
|
+
|
|
230
|
+
Defina `GET`, `POST`, `PUT`, `DELETE` (ou só os necessários).
|
|
231
|
+
|
|
232
|
+
### Rotas Dinâmicas Backend
|
|
233
|
+
|
|
234
|
+
`src/web/backend/routes/users/[id].ts` → `/users/123`
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
import { BackendRouteConfig, HightJSResponse } from "hightjs";
|
|
238
|
+
|
|
239
|
+
const route: BackendRouteConfig = {
|
|
240
|
+
pattern: '/users/[id]',
|
|
241
|
+
GET: async (req, params) => {
|
|
242
|
+
return HightJSResponse.json({ userId: params.id });
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
export default route;
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 🧩 Middlewares
|
|
251
|
+
|
|
252
|
+
Adicione middlewares:
|
|
253
|
+
|
|
254
|
+
- Direto na rota: `middleware: [...]`
|
|
255
|
+
- Arquivo `middleware.ts` na pasta (auto-carregado)
|
|
256
|
+
|
|
257
|
+
### Interface
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
export type HightMiddleware = (
|
|
261
|
+
request: HightJSRequest,
|
|
262
|
+
params: { [key: string]: string },
|
|
263
|
+
next: () => Promise<HightJSResponse>
|
|
264
|
+
) => Promise<HightJSResponse> | HightJSResponse;
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Exemplo por Pasta
|
|
268
|
+
|
|
269
|
+
`src/web/backend/routes/middleware.ts`:
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import {HightJSRequest, HightJSResponse} from 'hightjs';
|
|
273
|
+
|
|
274
|
+
export async function log(
|
|
275
|
+
request: HightJSRequest,
|
|
276
|
+
params: { [key: string]: string },
|
|
277
|
+
next: () => Promise<HightJSResponse>
|
|
278
|
+
): Promise<HightJSResponse> {
|
|
279
|
+
|
|
280
|
+
console.log('[API]', request.method, request.url);
|
|
281
|
+
return next();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
export async function blockLegacy(
|
|
286
|
+
request: HightJSRequest,
|
|
287
|
+
params: { [key: string]: string },
|
|
288
|
+
next: () => Promise<HightJSResponse>
|
|
289
|
+
): Promise<HightJSResponse> {
|
|
290
|
+
if (request.header('user-agent')?.includes('IE 8')) {
|
|
291
|
+
return HightJSResponse.json({ error: 'Navegador não suportado' }, {status: 400});
|
|
292
|
+
}
|
|
293
|
+
return next();
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export default [log, blockLegacy];
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Exemplo por Rota
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
import {BackendRouteConfig, HightJSRequest, HightJSResponse} from 'hightjs';
|
|
303
|
+
|
|
304
|
+
async function authCheck(
|
|
305
|
+
request: HightJSRequest,
|
|
306
|
+
params: { [key: string]: string },
|
|
307
|
+
next: () => Promise<HightJSResponse>
|
|
308
|
+
): Promise<HightJSResponse> {
|
|
309
|
+
if(!request.header("authorization")) {
|
|
310
|
+
return HightJSResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
311
|
+
}
|
|
312
|
+
return next();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const route: BackendRouteConfig = {
|
|
316
|
+
pattern: '/secure/data',
|
|
317
|
+
middleware: [authCheck],
|
|
318
|
+
GET: async () => HightJSResponse.json({ secret: true })
|
|
319
|
+
};
|
|
320
|
+
export default route;
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 🔐 Autenticação (HightJS/auth)
|
|
326
|
+
|
|
327
|
+
Autenticação JWT embutida, fácil de configurar.
|
|
328
|
+
O jeito recomendado é criar as rotas diretamente no `auth.ts` e importar onde quiser.
|
|
329
|
+
|
|
330
|
+
### Configuração Básica & Rotas
|
|
331
|
+
|
|
332
|
+
`src/auth.ts`:
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
import { CredentialsProvider, createAuthRoutes } from 'hightjs/auth';
|
|
336
|
+
import type { AuthConfig } from 'hightjs/auth';
|
|
337
|
+
|
|
338
|
+
export const authConfig: AuthConfig = {
|
|
339
|
+
providers: [
|
|
340
|
+
CredentialsProvider({
|
|
341
|
+
id: 'credentials',
|
|
342
|
+
name: 'Credentials',
|
|
343
|
+
credentials: {
|
|
344
|
+
username: { label: 'Username', type: 'text', placeholder: 'Digite seu usuário' },
|
|
345
|
+
password: { label: 'Password', type: 'password', placeholder: 'Digite sua senha' }
|
|
346
|
+
},
|
|
347
|
+
async authorize(credentials) {
|
|
348
|
+
if (credentials.username === 'admin' && credentials.password === 'admin') {
|
|
349
|
+
return {
|
|
350
|
+
id: '1',
|
|
351
|
+
username: 'admin',
|
|
352
|
+
email: 'admin@test.com',
|
|
353
|
+
name: 'Administrador',
|
|
354
|
+
testeeee: 'sdondsfndsfndsfodsfo'
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
}),
|
|
360
|
+
],
|
|
361
|
+
session: {
|
|
362
|
+
strategy: 'jwt',
|
|
363
|
+
maxAge: 24 * 60 * 60, // 24 horas
|
|
364
|
+
},
|
|
365
|
+
pages: {
|
|
366
|
+
signIn: '/login',
|
|
367
|
+
signOut: '/'
|
|
368
|
+
},
|
|
369
|
+
secret: 'hweb-test-secret-key-change-in-production'
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// Cria as rotas de autenticação automaticamente
|
|
373
|
+
export const authRoutes = createAuthRoutes(authConfig);
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Exportando as rotas
|
|
377
|
+
|
|
378
|
+
`src/web/backend/routes/auth.ts`:
|
|
379
|
+
|
|
380
|
+
```ts
|
|
381
|
+
import { authRoutes } from "../../../auth";
|
|
382
|
+
export default authRoutes;
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Protegendo rotas backend
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
import { HightJSRequest } from "hightjs";
|
|
389
|
+
import { BackendRouteConfig, HightJSResponse } from "hightjs";
|
|
390
|
+
import { authRoutes } from "../../../../auth";
|
|
391
|
+
|
|
392
|
+
const route: BackendRouteConfig = {
|
|
393
|
+
pattern: "/api/version",
|
|
394
|
+
GET: async (req: HightJSRequest, params: any) => {
|
|
395
|
+
const session = await authRoutes.auth.getSession(req)
|
|
396
|
+
if (!session) {
|
|
397
|
+
return HightJSResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
398
|
+
}
|
|
399
|
+
return HightJSResponse.json({
|
|
400
|
+
version: "1.0.0",
|
|
401
|
+
name: "HightJS",
|
|
402
|
+
description: "Um framework web full-stack moderno para Node.js",
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
export default route;
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Métodos principais
|
|
410
|
+
|
|
411
|
+
- `authRoutes.auth.signIn()`
|
|
412
|
+
- `authRoutes.auth.signOut()`
|
|
413
|
+
- `authRoutes.auth.getSession()`
|
|
414
|
+
- `authRoutes.auth.isAuthenticated()`
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## 🛠️ CLI
|
|
419
|
+
|
|
420
|
+
Comandos principais:
|
|
421
|
+
|
|
422
|
+
| Comando | Descrição |
|
|
423
|
+
|--------------------|-------------------------------------------|
|
|
424
|
+
| `npx hight dev` | Modo desenvolvimento (hot reload) |
|
|
425
|
+
| `npx hight start` | Modo produção (usa build gerado) |
|
|
426
|
+
|
|
427
|
+
### Opções
|
|
428
|
+
|
|
429
|
+
- `--port` Porta (default 3000)
|
|
430
|
+
- `--hostname` Host (default 0.0.0.0)
|
|
431
|
+
- `--framework` `native` | `express` | `fastify` (default: native)
|
|
432
|
+
|
|
433
|
+
### Produção
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
npx hight start -p 8080
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## 📂 Arquivos Especiais
|
|
442
|
+
|
|
443
|
+
| Arquivo | Localização | Função |
|
|
444
|
+
|-----------------------------|---------------------------------------|------------------------------------------------|
|
|
445
|
+
| `layout.tsx` | `/src/web` | Layout global + `export const metadata` |
|
|
446
|
+
| `notFound.tsx` | `/src/web` | Página 404 customizada |
|
|
447
|
+
| `middleware.ts` | dentro de `/src/web/backend/routes` | Middlewares globais por pasta backend |
|
|
448
|
+
| `hightweb.ts` / `.tsx` | `/src/hightweb` | Instrumentação opcional executada no boot |
|
|
449
|
+
| `public/` | `/public` | Arquivos estáticos servidos diretamente |
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## 🧱 Adapters
|
|
454
|
+
|
|
455
|
+
Inicie via: `--framework native|express|fastify`
|
|
456
|
+
|
|
457
|
+
- Native: zero dependências extras
|
|
458
|
+
- Express/Fastify: instale peer deps (express ou fastify)
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## 🔐 Segurança Interna
|
|
463
|
+
|
|
464
|
+
- Sanitização de headers, cookies e body
|
|
465
|
+
- Limites de tamanho configuráveis
|
|
466
|
+
- Proteção contra JSON malformado
|
|
467
|
+
- Timeout de requisição / body parser nativo
|
|
468
|
+
- JWT com HS256, verificação constant-time
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## ♻️ Hot Reload
|
|
473
|
+
|
|
474
|
+
Em modo dev, o cliente abre WebSocket `/hweb-hotreload/`.
|
|
475
|
+
Mudanças em rotas frontend ou backend recarregam automaticamente.
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## ❓ FAQ Rápido
|
|
480
|
+
|
|
481
|
+
| Pergunta | Resposta |
|
|
482
|
+
|--------------------------------|-----------------------------------------------------|
|
|
483
|
+
| Precisa Next/Vite? | Não, bundler interno via esbuild. |
|
|
484
|
+
| Dá para usar React 19? | Sim (peer dependency). |
|
|
485
|
+
| Tem SSR? | Atualmente só client-side hydration. |
|
|
486
|
+
| Posso usar CSS/SCSS? | Import normal nos componentes. |
|
|
487
|
+
| Rota de API conflita com página?| Não, rotas backend podem ser qualquer path. |
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## ✅ Checklist Mental
|
|
492
|
+
|
|
493
|
+
1. Precisa de página? Crie em `src/web/routes/...`
|
|
494
|
+
2. Precisa de endpoint? Crie em `src/web/backend/routes/...`
|
|
495
|
+
3. Precisa proteger? Use autenticação nas rotas
|
|
496
|
+
4. Precisa middleware? `middleware.ts` ou `middleware: []` na rota
|
|
497
|
+
5. Metadata? `generateMetadata` ou `metadata` no layout
|
|
498
|
+
6. Deploy? `npx hight start`
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## 🪪 Licença
|
|
503
|
+
|
|
504
|
+
Copyright 2025 itsmuzin
|
|
505
|
+
|
|
506
|
+
Este projeto está licenciado sob a [Licença Apache 2.0](LICENSE).
|
|
507
|
+
|
|
508
|
+
---
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Request as ExpressRequest, Response as ExpressResponse } from 'express';
|
|
2
|
+
import { GenericRequest, GenericResponse, FrameworkAdapter } from '../types/framework';
|
|
3
|
+
export declare class ExpressAdapter implements FrameworkAdapter {
|
|
4
|
+
type: "express";
|
|
5
|
+
parseRequest(req: ExpressRequest): GenericRequest;
|
|
6
|
+
createResponse(res: ExpressResponse): GenericResponse;
|
|
7
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExpressAdapter = void 0;
|
|
4
|
+
class ExpressAdapter {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.type = 'express';
|
|
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(res) {
|
|
21
|
+
return new ExpressResponseWrapper(res);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ExpressAdapter = ExpressAdapter;
|
|
25
|
+
class ExpressResponseWrapper {
|
|
26
|
+
constructor(res) {
|
|
27
|
+
this.res = res;
|
|
28
|
+
}
|
|
29
|
+
get raw() {
|
|
30
|
+
return this.res;
|
|
31
|
+
}
|
|
32
|
+
status(code) {
|
|
33
|
+
this.res.status(code);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
header(name, value) {
|
|
37
|
+
this.res.setHeader(name, value);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
cookie(name, value, options) {
|
|
41
|
+
this.res.cookie(name, value, options || {});
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
clearCookie(name, options) {
|
|
45
|
+
// Filter out the deprecated 'expires' option to avoid Express deprecation warning
|
|
46
|
+
const { expires, ...filteredOptions } = options || {};
|
|
47
|
+
this.res.clearCookie(name, filteredOptions);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
json(data) {
|
|
51
|
+
this.res.json(data);
|
|
52
|
+
}
|
|
53
|
+
text(data) {
|
|
54
|
+
this.res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
55
|
+
this.res.send(data);
|
|
56
|
+
}
|
|
57
|
+
send(data) {
|
|
58
|
+
this.res.send(data);
|
|
59
|
+
}
|
|
60
|
+
redirect(url) {
|
|
61
|
+
this.res.redirect(url);
|
|
62
|
+
}
|
|
63
|
+
}
|