heliumts 0.2.4 → 0.2.6
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 +12 -37
- package/dist/bin/helium.js +0 -0
- package/dist/server/ipExtractor.d.ts +48 -0
- package/dist/server/ipExtractor.d.ts.map +1 -0
- package/dist/server/ipExtractor.js +96 -0
- package/dist/server/ipExtractor.js.map +1 -0
- package/dist/utils/deepEqual.d.ts +1 -0
- package/dist/utils/deepEqual.d.ts.map +1 -0
- package/dist/utils/deepEqual.js +2 -0
- package/dist/utils/deepEqual.js.map +1 -0
- package/dist/utils/formatError.d.ts +2 -0
- package/dist/utils/formatError.d.ts.map +1 -0
- package/dist/utils/formatError.js +18 -0
- package/dist/utils/formatError.js.map +1 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[]()
|
|
2
|
-
[](https://github.com/heliobentes/heliumts/issues)
|
|
3
|
+
[](https://github.com/heliobentes/heliumts/pulls)
|
|
4
4
|
[](/LICENSE)
|
|
5
5
|
|
|
6
6
|
# HeliumTS
|
|
@@ -31,49 +31,21 @@ HeliumTS is a blazing fast 🚀 and opinionated full-stack React + Vite framewor
|
|
|
31
31
|
|
|
32
32
|
### 1.1. Installation
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
#### 1.1.1. Install React + Vite
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
npm create vite@latest my-helium-app -- --template react-ts
|
|
40
|
-
```
|
|
41
|
-
#### 1.1.2. Install HeliumJS
|
|
34
|
+
The easiest way to get started with HeliumTS is by using the scaffolding tool:
|
|
42
35
|
|
|
43
36
|
```bash
|
|
44
|
-
npm
|
|
37
|
+
npm create heliumts-app@latest my-helium-app
|
|
45
38
|
```
|
|
46
39
|
|
|
47
|
-
|
|
48
|
-
Create or update `vite.config.ts` in the project root to include Helium's Vite plugin:
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
import react from '@vitejs/plugin-react';
|
|
52
|
-
import helium from 'heliumts/vite';
|
|
53
|
-
import { defineConfig } from 'vite';
|
|
40
|
+
Or (to create in the current directory):
|
|
54
41
|
|
|
55
|
-
export default defineConfig({
|
|
56
|
-
plugins: [react(), helium()]
|
|
57
|
-
});
|
|
58
42
|
```
|
|
59
|
-
|
|
60
|
-
#### 1.1.4. Delete **main.tsx**
|
|
61
|
-
Delete the `src/main.tsx` file created by Vite, as HeliumTS handles the client entry point automatically.
|
|
62
|
-
Also, remove its reference from `index.html` if present.
|
|
63
|
-
```html
|
|
64
|
-
<!-- Remove this from index.html -->
|
|
65
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
43
|
+
npm create heliumts-app@latest .
|
|
66
44
|
```
|
|
67
45
|
|
|
68
|
-
|
|
69
|
-
Replace the contents of `src/App.tsx` with the following content:
|
|
70
|
-
```tsx
|
|
71
|
-
import { type AppShellProps } from "heliumts/client";
|
|
46
|
+
This command will guide you through setting up a new project with everything configured for you.
|
|
72
47
|
|
|
73
|
-
|
|
74
|
-
return <Component {...pageProps} />;
|
|
75
|
-
}
|
|
76
|
-
```
|
|
48
|
+
If you prefer to set up the project manually, please refer to the [Manual Installation Guide](./docs/manual-installation.md).
|
|
77
49
|
|
|
78
50
|
### 1.2. Running the Development Server
|
|
79
51
|
|
|
@@ -91,7 +63,7 @@ npx helium build
|
|
|
91
63
|
npx helium start
|
|
92
64
|
```
|
|
93
65
|
|
|
94
|
-
Check the working Example APP at: [https://github.com/heliobentes/
|
|
66
|
+
Check the working Example APP at: [https://github.com/heliobentes/heliumts-example-app](https://github.com/heliobentes/heliumts-example-app)
|
|
95
67
|
|
|
96
68
|
## 2. Project Structure
|
|
97
69
|
|
|
@@ -336,6 +308,9 @@ See [SSG Documentation](./docs/ssg.md) for detailed information including limita
|
|
|
336
308
|
|
|
337
309
|
## 5. More Documentation
|
|
338
310
|
|
|
311
|
+
### Getting Started
|
|
312
|
+
- [Manual Installation](./docs/manual-installation.md) - Step-by-step guide to setting up a HeliumTS project manually
|
|
313
|
+
|
|
339
314
|
### Core Features
|
|
340
315
|
- [Routing & useRouter](./docs/routing.md) - File-based routing, dynamic routes, navigation, and the useRouter hook
|
|
341
316
|
- [Configuration](./docs/helium-config.md) - Configure RPC encoding, compression, security, and proxy settings
|
package/dist/bin/helium.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type http from "http";
|
|
2
|
+
/**
|
|
3
|
+
* Extracts the client IP address from an HTTP request, taking into account proxy configurations.
|
|
4
|
+
*
|
|
5
|
+
* When behind proxies (like Vercel, Cloudflare, AWS ALB, etc.), the X-Forwarded-For header
|
|
6
|
+
* contains a chain of IP addresses. The format is: "client, proxy1, proxy2, ..."
|
|
7
|
+
*
|
|
8
|
+
* @param req - The HTTP request object
|
|
9
|
+
* @param trustProxyDepth - Number of proxy levels to trust
|
|
10
|
+
* - 0: Only use req.socket.remoteAddress (no proxy trust)
|
|
11
|
+
* - 1: Trust 1 proxy level (get the last IP before your server)
|
|
12
|
+
* - 2+: Trust multiple proxy levels (for complex setups)
|
|
13
|
+
*
|
|
14
|
+
* Examples:
|
|
15
|
+
* - trustProxyDepth=0: Direct connection, no proxies
|
|
16
|
+
* X-Forwarded-For: ignored
|
|
17
|
+
* Result: req.socket.remoteAddress
|
|
18
|
+
*
|
|
19
|
+
* - trustProxyDepth=1: Behind one proxy (e.g., Vercel, Netlify)
|
|
20
|
+
* X-Forwarded-For: "203.0.113.1, 198.51.100.1"
|
|
21
|
+
* Result: "203.0.113.1" (client IP)
|
|
22
|
+
*
|
|
23
|
+
* - trustProxyDepth=2: Behind two proxies (e.g., Cloudflare -> Load Balancer)
|
|
24
|
+
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
25
|
+
* Result: "203.0.113.1" (client IP)
|
|
26
|
+
*
|
|
27
|
+
* Common configurations:
|
|
28
|
+
* - Vercel/Netlify/Railway: trustProxyDepth=1
|
|
29
|
+
* - Cloudflare -> Origin: trustProxyDepth=1 or 2 (depending on your setup)
|
|
30
|
+
* - AWS ALB -> EC2: trustProxyDepth=1
|
|
31
|
+
* - Nginx -> Node: trustProxyDepth=1
|
|
32
|
+
* - Cloudflare -> Nginx -> Node: trustProxyDepth=2
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractClientIP(req: http.IncomingMessage, trustProxyDepth?: number): string;
|
|
35
|
+
/**
|
|
36
|
+
* Alternative extraction method that works from the right (trusts the rightmost IPs).
|
|
37
|
+
* This is useful when you want to trust the last N proxies in the chain.
|
|
38
|
+
*
|
|
39
|
+
* @param req - The HTTP request object
|
|
40
|
+
* @param trustProxyDepth - Number of proxy levels to trust from the right
|
|
41
|
+
*
|
|
42
|
+
* Example:
|
|
43
|
+
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
44
|
+
* trustProxyDepth=1: Result is "198.51.100.1" (skip the last trusted proxy)
|
|
45
|
+
* trustProxyDepth=2: Result is "203.0.113.1" (skip the last 2 trusted proxies)
|
|
46
|
+
*/
|
|
47
|
+
export declare function extractClientIPFromRight(req: http.IncomingMessage, trustProxyDepth?: number): string;
|
|
48
|
+
//# sourceMappingURL=ipExtractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipExtractor.d.ts","sourceRoot":"","sources":["../../src/server/ipExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,eAAe,GAAE,MAAU,GAAG,MAAM,CAqC9F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,eAAe,GAAE,MAAU,GAAG,MAAM,CAsBvG"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the client IP address from an HTTP request, taking into account proxy configurations.
|
|
3
|
+
*
|
|
4
|
+
* When behind proxies (like Vercel, Cloudflare, AWS ALB, etc.), the X-Forwarded-For header
|
|
5
|
+
* contains a chain of IP addresses. The format is: "client, proxy1, proxy2, ..."
|
|
6
|
+
*
|
|
7
|
+
* @param req - The HTTP request object
|
|
8
|
+
* @param trustProxyDepth - Number of proxy levels to trust
|
|
9
|
+
* - 0: Only use req.socket.remoteAddress (no proxy trust)
|
|
10
|
+
* - 1: Trust 1 proxy level (get the last IP before your server)
|
|
11
|
+
* - 2+: Trust multiple proxy levels (for complex setups)
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* - trustProxyDepth=0: Direct connection, no proxies
|
|
15
|
+
* X-Forwarded-For: ignored
|
|
16
|
+
* Result: req.socket.remoteAddress
|
|
17
|
+
*
|
|
18
|
+
* - trustProxyDepth=1: Behind one proxy (e.g., Vercel, Netlify)
|
|
19
|
+
* X-Forwarded-For: "203.0.113.1, 198.51.100.1"
|
|
20
|
+
* Result: "203.0.113.1" (client IP)
|
|
21
|
+
*
|
|
22
|
+
* - trustProxyDepth=2: Behind two proxies (e.g., Cloudflare -> Load Balancer)
|
|
23
|
+
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
24
|
+
* Result: "203.0.113.1" (client IP)
|
|
25
|
+
*
|
|
26
|
+
* Common configurations:
|
|
27
|
+
* - Vercel/Netlify/Railway: trustProxyDepth=1
|
|
28
|
+
* - Cloudflare -> Origin: trustProxyDepth=1 or 2 (depending on your setup)
|
|
29
|
+
* - AWS ALB -> EC2: trustProxyDepth=1
|
|
30
|
+
* - Nginx -> Node: trustProxyDepth=1
|
|
31
|
+
* - Cloudflare -> Nginx -> Node: trustProxyDepth=2
|
|
32
|
+
*/
|
|
33
|
+
export function extractClientIP(req, trustProxyDepth = 0) {
|
|
34
|
+
// If not trusting any proxies, return the direct connection IP
|
|
35
|
+
if (trustProxyDepth === 0) {
|
|
36
|
+
return req.socket.remoteAddress || "unknown";
|
|
37
|
+
}
|
|
38
|
+
// Get X-Forwarded-For header
|
|
39
|
+
const forwardedFor = req.headers["x-forwarded-for"];
|
|
40
|
+
if (!forwardedFor) {
|
|
41
|
+
// No X-Forwarded-For header, fall back to direct connection
|
|
42
|
+
return req.socket.remoteAddress || "unknown";
|
|
43
|
+
}
|
|
44
|
+
// Parse X-Forwarded-For header (can be a string or array of strings)
|
|
45
|
+
const forwardedIPs = (Array.isArray(forwardedFor) ? forwardedFor.join(",") : forwardedFor)
|
|
46
|
+
.split(",")
|
|
47
|
+
.map((ip) => ip.trim())
|
|
48
|
+
.filter((ip) => ip.length > 0);
|
|
49
|
+
if (forwardedIPs.length === 0) {
|
|
50
|
+
// Empty X-Forwarded-For, fall back to direct connection
|
|
51
|
+
return req.socket.remoteAddress || "unknown";
|
|
52
|
+
}
|
|
53
|
+
// The client IP is at the beginning of the chain
|
|
54
|
+
// We trust the chain up to trustProxyDepth levels
|
|
55
|
+
// Format: [clientIP, proxy1, proxy2, ..., lastProxy]
|
|
56
|
+
// We want the clientIP, but we need to verify we have enough trusted proxies
|
|
57
|
+
if (forwardedIPs.length < trustProxyDepth) {
|
|
58
|
+
// Not enough IPs in the chain, the chain might be incomplete or spoofed
|
|
59
|
+
// Fall back to direct connection for safety
|
|
60
|
+
return req.socket.remoteAddress || "unknown";
|
|
61
|
+
}
|
|
62
|
+
// Return the client IP (first in the chain)
|
|
63
|
+
return forwardedIPs[0];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Alternative extraction method that works from the right (trusts the rightmost IPs).
|
|
67
|
+
* This is useful when you want to trust the last N proxies in the chain.
|
|
68
|
+
*
|
|
69
|
+
* @param req - The HTTP request object
|
|
70
|
+
* @param trustProxyDepth - Number of proxy levels to trust from the right
|
|
71
|
+
*
|
|
72
|
+
* Example:
|
|
73
|
+
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
74
|
+
* trustProxyDepth=1: Result is "198.51.100.1" (skip the last trusted proxy)
|
|
75
|
+
* trustProxyDepth=2: Result is "203.0.113.1" (skip the last 2 trusted proxies)
|
|
76
|
+
*/
|
|
77
|
+
export function extractClientIPFromRight(req, trustProxyDepth = 0) {
|
|
78
|
+
if (trustProxyDepth === 0) {
|
|
79
|
+
return req.socket.remoteAddress || "unknown";
|
|
80
|
+
}
|
|
81
|
+
const forwardedFor = req.headers["x-forwarded-for"];
|
|
82
|
+
if (!forwardedFor) {
|
|
83
|
+
return req.socket.remoteAddress || "unknown";
|
|
84
|
+
}
|
|
85
|
+
const forwardedIPs = (Array.isArray(forwardedFor) ? forwardedFor.join(",") : forwardedFor)
|
|
86
|
+
.split(",")
|
|
87
|
+
.map((ip) => ip.trim())
|
|
88
|
+
.filter((ip) => ip.length > 0);
|
|
89
|
+
if (forwardedIPs.length === 0) {
|
|
90
|
+
return req.socket.remoteAddress || "unknown";
|
|
91
|
+
}
|
|
92
|
+
// Calculate which IP to trust by skipping the rightmost N trusted proxies
|
|
93
|
+
const clientIPIndex = Math.max(0, forwardedIPs.length - trustProxyDepth - 1);
|
|
94
|
+
return forwardedIPs[clientIPIndex];
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=ipExtractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipExtractor.js","sourceRoot":"","sources":["../../src/server/ipExtractor.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,eAAe,CAAC,GAAyB,EAAE,kBAA0B,CAAC;IAClF,+DAA+D;IAC/D,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,6BAA6B;IAC7B,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,4DAA4D;QAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,qEAAqE;IACrE,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;SACrF,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;SACtB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,wDAAwD;QACxD,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,iDAAiD;IACjD,kDAAkD;IAClD,qDAAqD;IACrD,6EAA6E;IAE7E,IAAI,YAAY,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QACxC,wEAAwE;QACxE,4CAA4C;QAC5C,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,4CAA4C;IAC5C,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAyB,EAAE,kBAA0B,CAAC;IAC3F,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;SACrF,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;SACtB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,0EAA0E;IAC1E,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,GAAG,eAAe,GAAG,CAAC,CAAC,CAAC;IAC7E,OAAO,YAAY,CAAC,aAAa,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=deepEqual.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deepEqual.d.ts","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deepEqual.js","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatError.d.ts","sourceRoot":"","sources":["../../src/utils/formatError.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAgBhD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function formatError(err) {
|
|
2
|
+
console.log("🚀 ~ formatError ~ err:", err);
|
|
3
|
+
if (err instanceof Error) {
|
|
4
|
+
return err.message;
|
|
5
|
+
}
|
|
6
|
+
if (typeof err === "object" && err !== null) {
|
|
7
|
+
if ("message" in err) {
|
|
8
|
+
return String(err.message);
|
|
9
|
+
}
|
|
10
|
+
// Format Record<string, string> errors
|
|
11
|
+
return JSON.stringify(err, null, 2);
|
|
12
|
+
}
|
|
13
|
+
if (typeof err === "string") {
|
|
14
|
+
return err;
|
|
15
|
+
}
|
|
16
|
+
return String(err);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=formatError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatError.js","sourceRoot":"","sources":["../../src/utils/formatError.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,GAAY;IACpC,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC5C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC1C,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;QACD,uCAAuC;QACvC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "heliumts",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "A lightweight full-stack React framework with file-based routing, RPC, and SSG support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/heliobentes/
|
|
18
|
+
"url": "https://github.com/heliobentes/heliumts.git"
|
|
19
19
|
},
|
|
20
|
-
"homepage": "https://
|
|
20
|
+
"homepage": "https://heliumts.com",
|
|
21
21
|
"bugs": {
|
|
22
|
-
"url": "https://github.com/heliobentes/
|
|
22
|
+
"url": "https://github.com/heliobentes/heliumts/issues"
|
|
23
23
|
},
|
|
24
24
|
"bin": {
|
|
25
25
|
"helium": "dist/bin/helium.js"
|