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,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RouterProvider = RouterProvider;
|
|
4
|
+
exports.useRouter = useRouter;
|
|
5
|
+
exports.usePathname = usePathname;
|
|
6
|
+
exports.useSearchParams = useSearchParams;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const clientRouter_1 = require("./clientRouter");
|
|
10
|
+
const RouterContext = (0, react_1.createContext)(null);
|
|
11
|
+
function RouterProvider({ children }) {
|
|
12
|
+
const [pathname, setPathname] = (0, react_1.useState)(clientRouter_1.router.pathname);
|
|
13
|
+
const [query, setQuery] = (0, react_1.useState)(clientRouter_1.router.query);
|
|
14
|
+
(0, react_1.useEffect)(() => {
|
|
15
|
+
const updateRoute = () => {
|
|
16
|
+
setPathname(clientRouter_1.router.pathname);
|
|
17
|
+
setQuery(clientRouter_1.router.query);
|
|
18
|
+
};
|
|
19
|
+
// Subscribe to router changes
|
|
20
|
+
const unsubscribe = clientRouter_1.router.subscribe(updateRoute);
|
|
21
|
+
// Also listen to browser back/forward
|
|
22
|
+
window.addEventListener('popstate', updateRoute);
|
|
23
|
+
return () => {
|
|
24
|
+
unsubscribe();
|
|
25
|
+
window.removeEventListener('popstate', updateRoute);
|
|
26
|
+
};
|
|
27
|
+
}, []);
|
|
28
|
+
const value = {
|
|
29
|
+
pathname,
|
|
30
|
+
query,
|
|
31
|
+
push: clientRouter_1.router.push.bind(clientRouter_1.router),
|
|
32
|
+
replace: clientRouter_1.router.replace.bind(clientRouter_1.router),
|
|
33
|
+
back: clientRouter_1.router.back.bind(clientRouter_1.router),
|
|
34
|
+
forward: clientRouter_1.router.forward.bind(clientRouter_1.router),
|
|
35
|
+
refresh: clientRouter_1.router.refresh.bind(clientRouter_1.router),
|
|
36
|
+
};
|
|
37
|
+
return ((0, jsx_runtime_1.jsx)(RouterContext.Provider, { value: value, children: children }));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Hook para acessar o router dentro de componentes React
|
|
41
|
+
*/
|
|
42
|
+
function useRouter() {
|
|
43
|
+
const context = (0, react_1.useContext)(RouterContext);
|
|
44
|
+
if (!context) {
|
|
45
|
+
throw new Error('useRouter deve ser usado dentro de um RouterProvider');
|
|
46
|
+
}
|
|
47
|
+
return context;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Hook para acessar apenas o pathname atual
|
|
51
|
+
*/
|
|
52
|
+
function usePathname() {
|
|
53
|
+
const { pathname } = useRouter();
|
|
54
|
+
return pathname;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Hook para acessar apenas os query parameters
|
|
58
|
+
*/
|
|
59
|
+
function useSearchParams() {
|
|
60
|
+
const { query } = useRouter();
|
|
61
|
+
return query;
|
|
62
|
+
}
|
package/dist/client.d.ts
ADDED
package/dist/client.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.router = exports.Link = void 0;
|
|
4
|
+
// Este arquivo exporta apenas código seguro para o cliente (navegador)
|
|
5
|
+
var Link_1 = require("./components/Link");
|
|
6
|
+
Object.defineProperty(exports, "Link", { enumerable: true, get: function () { return Link_1.Link; } });
|
|
7
|
+
var clientRouter_1 = require("./client/clientRouter");
|
|
8
|
+
Object.defineProperty(exports, "router", { enumerable: true, get: function () { return clientRouter_1.router; } });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type AnchorHTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
3
|
+
href: string;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare function Link({ href, children, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Link = Link;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const clientRouter_1 = require("../client/clientRouter");
|
|
6
|
+
function Link({ href, children, ...props }) {
|
|
7
|
+
const handleClick = async (e) => {
|
|
8
|
+
e.preventDefault();
|
|
9
|
+
// Usa o novo sistema de router
|
|
10
|
+
await clientRouter_1.router.push(href);
|
|
11
|
+
};
|
|
12
|
+
return ((0, jsx_runtime_1.jsx)("a", { href: href, ...props, onClick: handleClick, children: children }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export let rules: {
|
|
2
|
+
'require-use-client': {
|
|
3
|
+
meta: {
|
|
4
|
+
type: string;
|
|
5
|
+
docs: {
|
|
6
|
+
description: string;
|
|
7
|
+
category: string;
|
|
8
|
+
recommended: boolean;
|
|
9
|
+
};
|
|
10
|
+
fixable: string;
|
|
11
|
+
schema: never[];
|
|
12
|
+
messages: {
|
|
13
|
+
missingUseClient: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
create(context: any): {
|
|
17
|
+
Program(node: any): void;
|
|
18
|
+
ImportDeclaration(node: any): void;
|
|
19
|
+
CallExpression(node: any): void;
|
|
20
|
+
'Program:exit'(): void;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export namespace configs {
|
|
25
|
+
namespace recommended {
|
|
26
|
+
export let plugins: string[];
|
|
27
|
+
let rules_1: {
|
|
28
|
+
'hightjs/require-use-client': string;
|
|
29
|
+
};
|
|
30
|
+
export { rules_1 as rules };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const useClientRule = require('./use-client-rule');
|
|
3
|
+
module.exports = {
|
|
4
|
+
rules: {
|
|
5
|
+
'require-use-client': useClientRule,
|
|
6
|
+
},
|
|
7
|
+
configs: {
|
|
8
|
+
recommended: {
|
|
9
|
+
plugins: ['hightjs'],
|
|
10
|
+
rules: {
|
|
11
|
+
'hightjs/require-use-client': 'error',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export namespace meta {
|
|
2
|
+
let type: string;
|
|
3
|
+
namespace docs {
|
|
4
|
+
let description: string;
|
|
5
|
+
let category: string;
|
|
6
|
+
let recommended: boolean;
|
|
7
|
+
}
|
|
8
|
+
let fixable: string;
|
|
9
|
+
let schema: never[];
|
|
10
|
+
namespace messages {
|
|
11
|
+
let missingUseClient: string;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function create(context: any): {
|
|
15
|
+
Program(node: any): void;
|
|
16
|
+
ImportDeclaration(node: any): void;
|
|
17
|
+
CallExpression(node: any): void;
|
|
18
|
+
'Program:exit'(): void;
|
|
19
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ESLint rule: require-use-client
|
|
4
|
+
* Força o uso de "use client" quando React ou hooks são importados
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
meta: {
|
|
8
|
+
type: 'problem',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Require "use client" directive when importing React or React hooks',
|
|
11
|
+
category: 'Best Practices',
|
|
12
|
+
recommended: true,
|
|
13
|
+
},
|
|
14
|
+
fixable: 'code',
|
|
15
|
+
schema: [],
|
|
16
|
+
messages: {
|
|
17
|
+
missingUseClient: 'Arquivos que importam React ou hooks devem começar com "use client"',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
let hasReactImport = false;
|
|
22
|
+
let hasReactHooks = false;
|
|
23
|
+
let hasUseClient = false;
|
|
24
|
+
let firstNode = null;
|
|
25
|
+
// Lista de hooks do React que requerem "use client"
|
|
26
|
+
const reactHooks = [
|
|
27
|
+
'useState', 'useEffect', 'useContext', 'useReducer',
|
|
28
|
+
'useCallback', 'useMemo', 'useRef', 'useImperativeHandle',
|
|
29
|
+
'useLayoutEffect', 'useDebugValue', 'useDeferredValue',
|
|
30
|
+
'useTransition', 'useId', 'useSyncExternalStore',
|
|
31
|
+
'useInsertionEffect'
|
|
32
|
+
];
|
|
33
|
+
return {
|
|
34
|
+
Program(node) {
|
|
35
|
+
firstNode = node;
|
|
36
|
+
// Verifica se já tem "use client" no início do arquivo
|
|
37
|
+
const sourceCode = context.getSourceCode();
|
|
38
|
+
const firstToken = sourceCode.getFirstToken(node);
|
|
39
|
+
if (firstToken && firstToken.type === 'String') {
|
|
40
|
+
const value = firstToken.value;
|
|
41
|
+
if (value === '"use client"' || value === "'use client'") {
|
|
42
|
+
hasUseClient = true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Também verifica comentários
|
|
46
|
+
const comments = sourceCode.getAllComments();
|
|
47
|
+
if (comments.length > 0) {
|
|
48
|
+
const firstComment = comments[0];
|
|
49
|
+
if (firstComment.value.trim() === 'use client') {
|
|
50
|
+
hasUseClient = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
ImportDeclaration(node) {
|
|
55
|
+
const source = node.source.value;
|
|
56
|
+
// Verifica se importa do React
|
|
57
|
+
if (source === 'react' || source === 'react/jsx-runtime') {
|
|
58
|
+
hasReactImport = true;
|
|
59
|
+
// Verifica se importa hooks específicos
|
|
60
|
+
if (node.specifiers) {
|
|
61
|
+
for (const specifier of node.specifiers) {
|
|
62
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
63
|
+
reactHooks.includes(specifier.imported.name)) {
|
|
64
|
+
hasReactHooks = true;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
CallExpression(node) {
|
|
72
|
+
// Verifica se usa hooks do React diretamente
|
|
73
|
+
if (node.callee.type === 'Identifier' &&
|
|
74
|
+
reactHooks.includes(node.callee.name)) {
|
|
75
|
+
hasReactHooks = true;
|
|
76
|
+
}
|
|
77
|
+
// Verifica se usa React.useState, React.useEffect, etc.
|
|
78
|
+
if (node.callee.type === 'MemberExpression' &&
|
|
79
|
+
node.callee.object.name === 'React' &&
|
|
80
|
+
reactHooks.includes(node.callee.property.name)) {
|
|
81
|
+
hasReactHooks = true;
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
'Program:exit'() {
|
|
85
|
+
// Se importa React ou usa hooks mas não tem "use client"
|
|
86
|
+
if ((hasReactImport || hasReactHooks) && !hasUseClient) {
|
|
87
|
+
context.report({
|
|
88
|
+
node: firstNode,
|
|
89
|
+
messageId: 'missingUseClient',
|
|
90
|
+
fix(fixer) {
|
|
91
|
+
// Auto-fix: adiciona "use client" no início do arquivo
|
|
92
|
+
return fixer.insertTextBefore(firstNode, '"use client";\n\n');
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
function Home() {
|
|
6
|
+
return ((0, jsx_runtime_1.jsx)("h1", { children: "OL\u00C1 MUNDINHO MEU AMIGUINHO, VAMOS TRANSA?" }));
|
|
7
|
+
}
|
|
8
|
+
exports.config = {
|
|
9
|
+
pattern: '/',
|
|
10
|
+
component: Home,
|
|
11
|
+
generateMetadata: () => ({
|
|
12
|
+
title: 'HightJS | Home'
|
|
13
|
+
})
|
|
14
|
+
};
|
|
15
|
+
exports.default = exports.config;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HightJSOptions } from './types';
|
|
2
|
+
export default app;
|
|
3
|
+
export declare function app(options?: HightJSOptions): {
|
|
4
|
+
/**
|
|
5
|
+
* Integra com uma aplicação de qualquer framework (Express, Fastify, etc)
|
|
6
|
+
*/
|
|
7
|
+
integrate: (serverApp: any) => Promise<any>;
|
|
8
|
+
/**
|
|
9
|
+
* Inicia um servidor HightJS fechado (o usuário não tem acesso ao framework)
|
|
10
|
+
*/
|
|
11
|
+
init: () => Promise<any>;
|
|
12
|
+
prepare: () => Promise<void>;
|
|
13
|
+
executeInstrumentation: () => void;
|
|
14
|
+
getRequestHandler: () => import("./types").RequestHandler;
|
|
15
|
+
setupWebSocket: (server: any) => void;
|
|
16
|
+
build: () => Promise<void>;
|
|
17
|
+
stop: () => void;
|
|
18
|
+
};
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.app = app;
|
|
40
|
+
// Helpers para integração com diferentes frameworks
|
|
41
|
+
const index_1 = __importStar(require("./index"));
|
|
42
|
+
const os_1 = __importDefault(require("os"));
|
|
43
|
+
const console_1 = __importStar(require("./api/console"));
|
|
44
|
+
function getLocalExternalIp() {
|
|
45
|
+
const interfaces = os_1.default.networkInterfaces();
|
|
46
|
+
for (const name of Object.keys(interfaces)) {
|
|
47
|
+
for (const iface of interfaces[name]) {
|
|
48
|
+
if (iface.family === 'IPv4' && !iface.internal) {
|
|
49
|
+
return iface.address;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return 'localhost';
|
|
54
|
+
}
|
|
55
|
+
const sendBox = (options) => {
|
|
56
|
+
const isDev = options.dev ? "Rodando em modo de desenvolvimento" : null;
|
|
57
|
+
const messages = [
|
|
58
|
+
` ${console_1.Colors.FgMagenta}● ${console_1.Colors.Reset}Local: ${console_1.Colors.FgGreen}http://localhost:${options.port}${console_1.Colors.Reset}`,
|
|
59
|
+
` ${console_1.Colors.FgMagenta}● ${console_1.Colors.Reset}Rede: ${console_1.Colors.FgGreen}http://${getLocalExternalIp()}:${options.port}${console_1.Colors.Reset}`,
|
|
60
|
+
];
|
|
61
|
+
if (isDev) {
|
|
62
|
+
messages.push(` ${console_1.Colors.FgMagenta}● ${console_1.Colors.Reset}${isDev}`);
|
|
63
|
+
}
|
|
64
|
+
console_1.default.box(messages.join("\n"), { title: "Acesse o HightJS em:" });
|
|
65
|
+
};
|
|
66
|
+
exports.default = app;
|
|
67
|
+
function app(options = {}) {
|
|
68
|
+
const framework = options.framework || 'native'; // Mudando o padrão para 'native'
|
|
69
|
+
index_1.FrameworkAdapterFactory.setFramework(framework);
|
|
70
|
+
const hwebApp = (0, index_1.default)(options);
|
|
71
|
+
return {
|
|
72
|
+
...hwebApp,
|
|
73
|
+
/**
|
|
74
|
+
* Integra com uma aplicação de qualquer framework (Express, Fastify, etc)
|
|
75
|
+
*/
|
|
76
|
+
integrate: async (serverApp) => {
|
|
77
|
+
await hwebApp.prepare();
|
|
78
|
+
const handler = hwebApp.getRequestHandler();
|
|
79
|
+
if (framework === 'express') {
|
|
80
|
+
// Express integration
|
|
81
|
+
serverApp.use(handler);
|
|
82
|
+
hwebApp.setupWebSocket(serverApp);
|
|
83
|
+
}
|
|
84
|
+
else if (framework === 'fastify') {
|
|
85
|
+
// Fastify integration
|
|
86
|
+
await serverApp.register(async (fastify) => {
|
|
87
|
+
fastify.all('*', handler);
|
|
88
|
+
});
|
|
89
|
+
hwebApp.setupWebSocket(serverApp);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Generic integration - assume Express-like
|
|
93
|
+
serverApp.use(handler);
|
|
94
|
+
hwebApp.setupWebSocket(serverApp);
|
|
95
|
+
}
|
|
96
|
+
hwebApp.executeInstrumentation();
|
|
97
|
+
return serverApp;
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* Inicia um servidor HightJS fechado (o usuário não tem acesso ao framework)
|
|
101
|
+
*/
|
|
102
|
+
init: async () => {
|
|
103
|
+
console.log(`${console_1.Colors.FgMagenta}
|
|
104
|
+
_ _ _ _ _ _ _____
|
|
105
|
+
| | | (_) | | | | | |/ ____|
|
|
106
|
+
| |__| |_ __ _| |__ | |_ | | (___
|
|
107
|
+
| __ | |/ _\` | '_ \\| __| _ | |\\___ \\
|
|
108
|
+
| | | | | (_| | | | | |_ | |__| |____) |
|
|
109
|
+
|_| |_|_|\\__, |_| |_|\\__| \\____/|_____/
|
|
110
|
+
__/ |
|
|
111
|
+
|___/ ${console_1.Colors.Reset}`);
|
|
112
|
+
const actualPort = options.port || 3000;
|
|
113
|
+
const actualHostname = options.hostname || "0.0.0.0";
|
|
114
|
+
if (framework === 'express') {
|
|
115
|
+
return await initExpressServer(hwebApp, options, actualPort, actualHostname);
|
|
116
|
+
}
|
|
117
|
+
else if (framework === 'fastify') {
|
|
118
|
+
return await initFastifyServer(hwebApp, options, actualPort, actualHostname);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Default to Native
|
|
122
|
+
return await initNativeServer(hwebApp, options, actualPort, actualHostname);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Inicializa servidor Express fechado
|
|
129
|
+
*/
|
|
130
|
+
async function initExpressServer(hwebApp, options, port, hostname) {
|
|
131
|
+
const msg = console_1.default.dynamicLine(` ${console_1.Colors.FgCyan}● ${console_1.Colors.Reset}Iniciando HightJS com Express...`);
|
|
132
|
+
const express = require('express');
|
|
133
|
+
const app = express();
|
|
134
|
+
// Middlewares básicos para Express
|
|
135
|
+
app.use(express.json());
|
|
136
|
+
app.use(express.urlencoded({ extended: true }));
|
|
137
|
+
// Cookie parser se disponível
|
|
138
|
+
try {
|
|
139
|
+
const cookieParser = require('cookie-parser');
|
|
140
|
+
app.use(cookieParser());
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
console_1.default.error("Não foi possivel achar cookie-parser");
|
|
144
|
+
}
|
|
145
|
+
await hwebApp.prepare();
|
|
146
|
+
const handler = hwebApp.getRequestHandler();
|
|
147
|
+
app.use(handler);
|
|
148
|
+
const server = app.listen(port, hostname, () => {
|
|
149
|
+
sendBox({ ...options, port });
|
|
150
|
+
msg.end(` ${console_1.Colors.FgCyan}● ${console_1.Colors.Reset}Servidor Express iniciado (compatibilidade)`);
|
|
151
|
+
});
|
|
152
|
+
// Configura WebSocket para hot reload
|
|
153
|
+
hwebApp.setupWebSocket(server);
|
|
154
|
+
hwebApp.executeInstrumentation();
|
|
155
|
+
return server;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Inicializa servidor Fastify fechado
|
|
159
|
+
*/
|
|
160
|
+
async function initFastifyServer(hwebApp, options, port, hostname) {
|
|
161
|
+
const msg = console_1.default.dynamicLine(` ${console_1.Colors.FgCyan}● ${console_1.Colors.Reset}Iniciando HightJS com Fastify...`);
|
|
162
|
+
const fastify = require('fastify')({ logger: false });
|
|
163
|
+
// Registra plugins básicos para Fastify
|
|
164
|
+
try {
|
|
165
|
+
await fastify.register(require('@fastify/cookie'));
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
console_1.default.error("Não foi possivel achar @fastify/cookie");
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
await fastify.register(require('@fastify/formbody'));
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
console_1.default.error("Não foi possivel achar @fastify/formbody");
|
|
175
|
+
}
|
|
176
|
+
await hwebApp.prepare();
|
|
177
|
+
const handler = hwebApp.getRequestHandler();
|
|
178
|
+
// Registra o handler do hweb
|
|
179
|
+
await fastify.register(async (fastify) => {
|
|
180
|
+
fastify.all('*', handler);
|
|
181
|
+
});
|
|
182
|
+
hwebApp.setupWebSocket(fastify);
|
|
183
|
+
const address = await fastify.listen({ port, host: hostname });
|
|
184
|
+
sendBox({ ...options, port });
|
|
185
|
+
msg.end(` ${console_1.Colors.FgCyan}● ${console_1.Colors.Reset}Servidor Fastify iniciado (compatibilidade)`);
|
|
186
|
+
hwebApp.executeInstrumentation();
|
|
187
|
+
return fastify;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Inicializa servidor nativo do HightJS usando HTTP puro
|
|
191
|
+
*/
|
|
192
|
+
async function initNativeServer(hwebApp, options, port, hostname) {
|
|
193
|
+
const msg = console_1.default.dynamicLine(` ${console_1.Colors.FgMagenta}⚡ ${console_1.Colors.Reset}${console_1.Colors.Bright}Iniciando HightJS em modo NATIVO${console_1.Colors.Reset}`);
|
|
194
|
+
const http = require('http');
|
|
195
|
+
const { parse: parseUrl } = require('url');
|
|
196
|
+
const { parse: parseQuery } = require('querystring');
|
|
197
|
+
await hwebApp.prepare();
|
|
198
|
+
const handler = hwebApp.getRequestHandler();
|
|
199
|
+
// Middleware para parsing do body com proteções de segurança
|
|
200
|
+
const parseBody = (req) => {
|
|
201
|
+
return new Promise((resolve, reject) => {
|
|
202
|
+
if (req.method === 'GET' || req.method === 'HEAD') {
|
|
203
|
+
resolve(null);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
let body = '';
|
|
207
|
+
let totalSize = 0;
|
|
208
|
+
const maxBodySize = 10 * 1024 * 1024; // 10MB limite
|
|
209
|
+
// Timeout para requisições que demoram muito
|
|
210
|
+
const timeout = setTimeout(() => {
|
|
211
|
+
req.destroy();
|
|
212
|
+
reject(new Error('Request timeout'));
|
|
213
|
+
}, 30000); // 30 segundos
|
|
214
|
+
req.on('data', (chunk) => {
|
|
215
|
+
totalSize += chunk.length;
|
|
216
|
+
// Proteção contra ataques de DoS por body muito grande
|
|
217
|
+
if (totalSize > maxBodySize) {
|
|
218
|
+
clearTimeout(timeout);
|
|
219
|
+
req.destroy();
|
|
220
|
+
reject(new Error('Request body too large'));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
body += chunk.toString();
|
|
224
|
+
});
|
|
225
|
+
req.on('end', () => {
|
|
226
|
+
clearTimeout(timeout);
|
|
227
|
+
try {
|
|
228
|
+
const contentType = req.headers['content-type'] || '';
|
|
229
|
+
if (contentType.includes('application/json')) {
|
|
230
|
+
// Validação adicional para JSON
|
|
231
|
+
if (body.length > 1024 * 1024) { // 1MB limite para JSON
|
|
232
|
+
reject(new Error('JSON body too large'));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
resolve(JSON.parse(body));
|
|
236
|
+
}
|
|
237
|
+
else if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
238
|
+
resolve(parseQuery(body));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
resolve(body);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
resolve(body); // Fallback para string se parsing falhar
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
req.on('error', (error) => {
|
|
249
|
+
clearTimeout(timeout);
|
|
250
|
+
reject(error);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
// Cria o servidor HTTP nativo com configurações de segurança
|
|
255
|
+
const server = http.createServer(async (req, res) => {
|
|
256
|
+
// Configurações de segurança básicas
|
|
257
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
258
|
+
res.setHeader('X-Frame-Options', 'DENY');
|
|
259
|
+
res.setHeader('X-XSS-Protection', '1; mode=block');
|
|
260
|
+
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
261
|
+
// Timeout para requisições
|
|
262
|
+
req.setTimeout(30000, () => {
|
|
263
|
+
res.statusCode = 408; // Request Timeout
|
|
264
|
+
res.end('Request timeout');
|
|
265
|
+
});
|
|
266
|
+
try {
|
|
267
|
+
// Validação básica de URL para prevenir ataques
|
|
268
|
+
const url = req.url || '/';
|
|
269
|
+
if (url.length > 2048) {
|
|
270
|
+
res.statusCode = 414; // URI Too Long
|
|
271
|
+
res.end('URL too long');
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
// Parse do body com proteções
|
|
275
|
+
req.body = await parseBody(req);
|
|
276
|
+
// Adiciona host se não existir
|
|
277
|
+
req.headers.host = req.headers.host || `localhost:${port}`;
|
|
278
|
+
// Chama o handler do HightJS
|
|
279
|
+
await handler(req, res);
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
console_1.default.error('Erro no servidor nativo:', error);
|
|
283
|
+
if (!res.headersSent) {
|
|
284
|
+
res.statusCode = 500;
|
|
285
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
286
|
+
if (error instanceof Error) {
|
|
287
|
+
if (error.message.includes('too large')) {
|
|
288
|
+
res.statusCode = 413; // Payload Too Large
|
|
289
|
+
res.end('Request too large');
|
|
290
|
+
}
|
|
291
|
+
else if (error.message.includes('timeout')) {
|
|
292
|
+
res.statusCode = 408; // Request Timeout
|
|
293
|
+
res.end('Request timeout');
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
res.end('Internal server error');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
res.end('Internal server error');
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
// Configurações de segurança do servidor
|
|
306
|
+
server.setTimeout(35000); // Timeout geral do servidor
|
|
307
|
+
server.maxHeadersCount = 100; // Limita número de headers
|
|
308
|
+
server.headersTimeout = 60000; // Timeout para headers
|
|
309
|
+
server.requestTimeout = 30000; // Timeout para requisições
|
|
310
|
+
server.listen(port, hostname, () => {
|
|
311
|
+
sendBox({ ...options, port });
|
|
312
|
+
msg.end(` ${console_1.Colors.FgGreen}⚡ ${console_1.Colors.Reset}${console_1.Colors.Bright}Servidor HightJS NATIVO ativo!${console_1.Colors.Reset}`);
|
|
313
|
+
});
|
|
314
|
+
// Configura WebSocket para hot reload
|
|
315
|
+
hwebApp.setupWebSocket(server);
|
|
316
|
+
hwebApp.executeInstrumentation();
|
|
317
|
+
return server;
|
|
318
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IncomingMessage } from 'http';
|
|
2
|
+
export declare class HotReloadManager {
|
|
3
|
+
private wss;
|
|
4
|
+
private watchers;
|
|
5
|
+
private projectDir;
|
|
6
|
+
private clients;
|
|
7
|
+
private pingInterval;
|
|
8
|
+
private backendApiChangeCallback;
|
|
9
|
+
private frontendChangeCallback;
|
|
10
|
+
constructor(projectDir: string);
|
|
11
|
+
start(): Promise<void>;
|
|
12
|
+
handleUpgrade(request: IncomingMessage, socket: any, head: Buffer): void;
|
|
13
|
+
private setupWebSocketServer;
|
|
14
|
+
private setupWatchers;
|
|
15
|
+
private notifyClients;
|
|
16
|
+
private restartServer;
|
|
17
|
+
stop(): void;
|
|
18
|
+
getClientScript(): string;
|
|
19
|
+
private clearBackendCache;
|
|
20
|
+
onBackendApiChange(callback: () => void): void;
|
|
21
|
+
onFrontendChange(callback: () => void): void;
|
|
22
|
+
private checkFrontendBuild;
|
|
23
|
+
}
|