@mauroandre/velojs 0.0.54 → 0.0.55

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 CHANGED
@@ -159,6 +159,8 @@ export const Component = () => {
159
159
  npm run dev # http://localhost:3000
160
160
  ```
161
161
 
162
+ To expose the dev server beyond loopback — a VPS behind a reverse proxy, an app reached by hostname — set `HOST=0.0.0.0`, in the shell or in the project's `.env`; no `--host` flag by hand. The security trade-off: a broad bind in dev (`0.0.0.0`, `::`, or `--host` with no value) turns Vite's Host check off, so a request whose `Host` header carries that domain is served instead of 403'd — the DNS-rebinding protection you get on loopback is consciously given up. Stay on localhost unless you are behind a proxy; a `server.allowedHosts` declared in `vite.config.ts` still pins the allowed list.
163
+
162
164
  ### Configuration
163
165
 
164
166
  ```typescript
@@ -167,6 +169,7 @@ veloPlugin({
167
169
  routesFile: "routes.tsx", // default
168
170
  serverInit: "server.tsx", // default
169
171
  clientInit: "client.tsx", // default
172
+ hostname: "127.0.0.1", // bind interface, dev and production (the HOST env wins)
170
173
  });
171
174
  ```
172
175
 
@@ -1272,6 +1275,7 @@ Callbacks queue until the server starts. If called after startup, executes immed
1272
1275
  | Variable | Default | Description |
1273
1276
  |----------|---------|-------------|
1274
1277
  | `PORT` | `3000` | Server port. Overrides the `port` set in `defineConfig` |
1278
+ | `HOST` | — | Bind interface, in dev and production. Overrides `defineConfig`'s `hostname`; in dev an explicit `--host`/`server.host` still wins |
1275
1279
  | `NODE_ENV` | — | Set automatically by `velojs start`. Enables static file serving |
1276
1280
  | `STATIC_BASE_URL` | `""` | CDN/bucket prefix for static assets |
1277
1281
 
@@ -1475,6 +1479,8 @@ interface VeloConfig {
1475
1479
  routesFile?: string; // default: "routes.tsx"
1476
1480
  serverInit?: string; // default: "server.tsx"
1477
1481
  clientInit?: string; // default: "client.tsx"
1482
+ port?: number; // default: 3000; the PORT env wins
1483
+ hostname?: string; // bind interface, dev and production; the HOST env wins
1478
1484
  }
1479
1485
  ```
1480
1486
 
@@ -175,6 +175,8 @@ npm run dev
175
175
 
176
176
  Open `http://localhost:3000` in your browser. Changes to your code will hot-reload instantly.
177
177
 
178
+ The dev server binds loopback by default. To expose it beyond that — a VPS behind a reverse proxy, an app reached by a real hostname — set `HOST=0.0.0.0`, in the shell or in the project's `.env`; no `--host` flag by hand. A broad bind in dev (`0.0.0.0`, `::`, or `--host` with no value) also turns Vite's Host check off, so a request whose `Host` header carries that domain is served instead of 403'd — the DNS-rebinding protection you get on loopback is consciously traded away. A `server.allowedHosts` declared in `vite.config.ts` still pins the allowed list.
179
+
178
180
  ## Configuration
179
181
 
180
182
  The `veloPlugin()` accepts optional configuration:
@@ -79,6 +79,12 @@ By default `velojs start` binds to **all interfaces** (`::`) — the norm for No
79
79
  2. The `hostname` field in `defineConfig`.
80
80
  3. The Node default (all interfaces).
81
81
 
82
+ The same declaration covers the dev server, with one extra step at the top: `velojs dev --host <value>` (or a `server.host` in `vite.config.ts`) wins, then `HOST`, then `hostname`, then Vite's default (loopback). `HOST=0.0.0.0` in the shell or in the project's `.env` therefore lifts `velojs dev` beyond loopback with no flag by hand.
83
+
84
+ ### Dev behind a reverse proxy: the Host check
85
+
86
+ When a dev server binds broad it sits behind the proxy (or is reached by hostname), and requests arrive carrying the proxy's domain in the `Host` header. Vite's DNS-rebinding protection answers `403 Blocked request. This host is not allowed.` for any host outside its allow list — so the framework opens it whenever the declared bind is broad (`0.0.0.0`, `::`, or `--host` with no value): any `Host` is served. That is a conscious trade-off — the guard exists for loopback development, and leaving loopback means giving it up. If the project declared `server.allowedHosts`, that list wins and stays restrictive even on a broad bind.
87
+
82
88
  ### Secure bind for local/sensitive apps
83
89
 
84
90
  If your app is **local and single-user** — a cockpit with a terminal, file access, real user data — it must listen on loopback only. An all-interfaces bind exposes that surface to the whole network without any error: the developer finds out by scanning, not by the app telling them.
@@ -151,5 +151,6 @@ Callbacks registered with `onServer` queue until the server starts. If called af
151
151
  | Variable | Default | Description |
152
152
  |----------|---------|-------------|
153
153
  | `PORT` | `3000` | The port the server listens on. Overrides `defineConfig`'s `port`. |
154
+ | `HOST` | — | The bind interface, in dev and production. Overrides `defineConfig`'s `hostname`; in dev an explicit `--host`/`server.host` still wins. |
154
155
  | `NODE_ENV` | — | Set automatically by `velojs start` to `production` |
155
156
  | `STATIC_BASE_URL` | `""` | CDN/bucket prefix for static assets |
@@ -138,5 +138,6 @@ interface VeloConfig {
138
138
  serverInit?: string; // default: "server.tsx"
139
139
  clientInit?: string; // default: "client.tsx"
140
140
  port?: number; // default: 3000 (the PORT env always wins)
141
+ hostname?: string; // bind interface, dev and production; the HOST env wins
141
142
  }
142
143
  ```
package/dist/config.d.ts CHANGED
@@ -26,9 +26,11 @@ export interface VeloConfig {
26
26
  */
27
27
  port?: number;
28
28
  /**
29
- * Interface de bind do servidor de produção. A env `HOST` tem precedência.
30
- * Default do Node: todas as interfaces (o que Docker/cloud esperam).
31
- * Apps locais/sensíveis devem declarar "127.0.0.1".
29
+ * Interface de bind do servidor, em dev e em produção. A env `HOST` tem
30
+ * precedência nos dois modos; em dev a ordem é: `server.host` do Vite
31
+ * (`--host`/vite.config) > env `HOST` > este campo. Default do Node:
32
+ * todas as interfaces (o que Docker/cloud esperam). Apps
33
+ * locais/sensíveis devem declarar "127.0.0.1".
32
34
  */
33
35
  hostname?: string;
34
36
  /**
package/dist/vite.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { PluginOption } from "vite";
1
+ import { type PluginOption } from "vite";
2
2
  import type { VeloConfig } from "./config.js";
3
3
  import * as t from "@babel/types";
4
4
  export declare function injectMetadata(code: string, moduleId: string, fullPath?: string, path?: string): string;
package/dist/vite.js CHANGED
@@ -1,60 +1,61 @@
1
+ import { loadEnv as R } from "vite";
1
2
  import d from "node:path";
2
- import g from "node:fs";
3
- import R from "@preact/preset-vite";
4
- import $, { defaultOptions as J } from "@hono/vite-dev-server";
5
- import { parse as _ } from "@babel/parser";
6
- import j from "@babel/traverse";
7
- import L from "@babel/generator";
3
+ import S from "node:fs";
4
+ import $ from "@preact/preset-vite";
5
+ import H, { defaultOptions as J } from "@hono/vite-dev-server";
6
+ import { parse as v } from "@babel/parser";
7
+ import A from "@babel/traverse";
8
+ import N from "@babel/generator";
8
9
  import * as e from "@babel/types";
9
10
  import { buildGraph as U } from "./graph.js";
10
- const m = typeof j == "function" ? j : j.default, h = typeof L == "function" ? L : L.default;
11
- function W(u, o, n, i) {
12
- const l = _(u, {
11
+ const m = typeof A == "function" ? A : A.default, _ = typeof N == "function" ? N : N.default;
12
+ function W(p, s, r, i) {
13
+ const l = v(p, {
13
14
  sourceType: "module",
14
15
  plugins: ["typescript", "jsx"]
15
16
  });
16
17
  let t = !1;
17
18
  if (m(l, {
18
19
  // Procura: export const metadata = { ... }
19
- ExportNamedDeclaration(s) {
20
- const c = s.node.declaration;
20
+ ExportNamedDeclaration(o) {
21
+ const c = o.node.declaration;
21
22
  if (e.isVariableDeclaration(c) && c.declarations.length === 1) {
22
- const r = c.declarations[0];
23
- if (r && e.isIdentifier(r.id, { name: "metadata" }) && e.isObjectExpression(r.init)) {
23
+ const n = c.declarations[0];
24
+ if (n && e.isIdentifier(n.id, { name: "metadata" }) && e.isObjectExpression(n.init)) {
24
25
  t = !0;
25
- const f = r.init.properties.filter((v) => e.isObjectProperty(v) && e.isIdentifier(v.key) ? v.key.name !== "moduleId" && v.key.name !== "fullPath" && v.key.name !== "path" : !0), y = [
26
+ const f = n.init.properties.filter((y) => e.isObjectProperty(y) && e.isIdentifier(y.key) ? y.key.name !== "moduleId" && y.key.name !== "fullPath" && y.key.name !== "path" : !0), h = [
26
27
  e.objectProperty(
27
28
  e.identifier("moduleId"),
28
- e.stringLiteral(o)
29
+ e.stringLiteral(s)
29
30
  )
30
31
  ];
31
- n !== void 0 && y.push(
32
+ r !== void 0 && h.push(
32
33
  e.objectProperty(
33
34
  e.identifier("fullPath"),
34
- e.stringLiteral(n)
35
+ e.stringLiteral(r)
35
36
  )
36
- ), i !== void 0 && y.push(
37
+ ), i !== void 0 && h.push(
37
38
  e.objectProperty(
38
39
  e.identifier("path"),
39
40
  e.stringLiteral(i)
40
41
  )
41
- ), r.init.properties = [...y, ...f];
42
+ ), n.init.properties = [...h, ...f];
42
43
  }
43
44
  }
44
45
  }
45
46
  }), !t) {
46
- const s = [
47
+ const o = [
47
48
  e.objectProperty(
48
49
  e.identifier("moduleId"),
49
- e.stringLiteral(o)
50
+ e.stringLiteral(s)
50
51
  )
51
52
  ];
52
- n !== void 0 && s.push(
53
+ r !== void 0 && o.push(
53
54
  e.objectProperty(
54
55
  e.identifier("fullPath"),
55
- e.stringLiteral(n)
56
+ e.stringLiteral(r)
56
57
  )
57
- ), i !== void 0 && s.push(
58
+ ), i !== void 0 && o.push(
58
59
  e.objectProperty(
59
60
  e.identifier("path"),
60
61
  e.stringLiteral(i)
@@ -64,51 +65,51 @@ function W(u, o, n, i) {
64
65
  e.variableDeclaration("const", [
65
66
  e.variableDeclarator(
66
67
  e.identifier("metadata"),
67
- e.objectExpression(s)
68
+ e.objectExpression(o)
68
69
  )
69
70
  ])
70
71
  );
71
72
  l.program.body.unshift(c);
72
73
  }
73
- return h(l, { retainLines: !0 }).code;
74
+ return _(l, { retainLines: !0 }).code;
74
75
  }
75
- function M(u, o) {
76
- const n = _(u, {
76
+ function B(p, s) {
77
+ const r = v(p, {
77
78
  sourceType: "module",
78
79
  plugins: ["typescript", "jsx"]
79
80
  });
80
- return m(n, {
81
+ return m(r, {
81
82
  CallExpression(l) {
82
- const t = l.node.callee, a = e.isIdentifier(t, { name: "Loader" }) || e.isTSInstantiationExpression(t) && e.isIdentifier(t.expression, { name: "Loader" }), s = e.isIdentifier(t, { name: "useLoader" }) || e.isTSInstantiationExpression(t) && e.isIdentifier(t.expression, { name: "useLoader" });
83
- if (!a && !s) return;
84
- const c = l.node.arguments, r = e.stringLiteral(o), p = c[0];
85
- e.isStringLiteral(p) && p.value.includes("/") || (l.node.arguments = [r, ...c]);
83
+ const t = l.node.callee, a = e.isIdentifier(t, { name: "Loader" }) || e.isTSInstantiationExpression(t) && e.isIdentifier(t.expression, { name: "Loader" }), o = e.isIdentifier(t, { name: "useLoader" }) || e.isTSInstantiationExpression(t) && e.isIdentifier(t.expression, { name: "useLoader" });
84
+ if (!a && !o) return;
85
+ const c = l.node.arguments, n = e.stringLiteral(s), u = c[0];
86
+ e.isStringLiteral(u) && u.value.includes("/") || (l.node.arguments = [n, ...c]);
86
87
  }
87
- }), h(n, { retainLines: !0 }).code;
88
+ }), _(r, { retainLines: !0 }).code;
88
89
  }
89
- function B(u, o) {
90
- const n = _(u, {
90
+ function M(p, s) {
91
+ const r = v(p, {
91
92
  sourceType: "module",
92
93
  plugins: ["typescript", "jsx"]
93
94
  });
94
- return m(n, {
95
+ return m(r, {
95
96
  ExportNamedDeclaration(l) {
96
97
  const t = l.node.declaration;
97
98
  if (!e.isVariableDeclaration(t)) return;
98
99
  const a = t.declarations[0];
99
100
  if (!a || !e.isIdentifier(a.id)) return;
100
- const s = a.id.name;
101
- if (!s.startsWith("action_")) return;
102
- const c = s.replace("action_", ""), r = a.init;
103
- if (!e.isArrowFunctionExpression(r) || !r.async) return;
104
- const p = r.params, f = H(o, c, p);
105
- r.body = e.blockStatement([e.returnStatement(f)]), G(r, p);
101
+ const o = a.id.name;
102
+ if (!o.startsWith("action_")) return;
103
+ const c = o.replace("action_", ""), n = a.init;
104
+ if (!e.isArrowFunctionExpression(n) || !n.async) return;
105
+ const u = n.params, f = G(s, c, u);
106
+ n.body = e.blockStatement([e.returnStatement(f)]), z(n, u);
106
107
  }
107
- }), h(n, { retainLines: !0 }).code;
108
+ }), _(r, { retainLines: !0 }).code;
108
109
  }
109
- function H(u, o, n) {
110
- const i = `/_action/${u}/${o}`;
111
- return n.length === 0 ? e.callExpression(
110
+ function G(p, s, r) {
111
+ const i = `/_action/${p}/${s}`;
112
+ return r.length === 0 ? e.callExpression(
112
113
  e.memberExpression(
113
114
  e.callExpression(e.identifier("fetch"), [
114
115
  e.stringLiteral(i),
@@ -176,13 +177,13 @@ function H(u, o, n) {
176
177
  ]
177
178
  );
178
179
  }
179
- function G(u, o) {
180
- if (o.length === 0) return;
181
- const n = o[0];
182
- if (e.isObjectPattern(n)) {
180
+ function z(p, s) {
181
+ if (s.length === 0) return;
182
+ const r = s[0];
183
+ if (e.isObjectPattern(r)) {
183
184
  let i = null;
184
- if (e.isTSTypeAnnotation(n.typeAnnotation) && e.isTSTypeReference(n.typeAnnotation.typeAnnotation)) {
185
- const a = n.typeAnnotation.typeAnnotation;
185
+ if (e.isTSTypeAnnotation(r.typeAnnotation) && e.isTSTypeReference(r.typeAnnotation.typeAnnotation)) {
186
+ const a = r.typeAnnotation.typeAnnotation;
186
187
  e.isIdentifier(a.typeName, { name: "ActionArgs" }) && a.typeParameters?.params[0] && (i = a.typeParameters.params[0]);
187
188
  }
188
189
  const l = e.objectProperty(
@@ -199,23 +200,23 @@ function G(u, o) {
199
200
  e.tsTypeAnnotation(i)
200
201
  )
201
202
  ])
202
- )), u.params = [t];
203
+ )), p.params = [t];
203
204
  }
204
205
  }
205
- function z(u, o) {
206
- const n = _(u, {
206
+ function Y(p, s) {
207
+ const r = v(p, {
207
208
  sourceType: "module",
208
209
  plugins: ["typescript", "jsx"]
209
210
  });
210
- return m(n, {
211
+ return m(r, {
211
212
  ExportNamedDeclaration(l) {
212
213
  const t = l.node.declaration;
213
214
  if (!e.isVariableDeclaration(t)) return;
214
215
  const a = t.declarations[0];
215
216
  if (!a || !e.isIdentifier(a.id)) return;
216
- const s = a.id.name;
217
- if (!s.startsWith("stream_")) return;
218
- const c = s.replace("stream_", ""), r = `/_event/${o}/${c}`;
217
+ const o = a.id.name;
218
+ if (!o.startsWith("stream_")) return;
219
+ const c = o.replace("stream_", ""), n = `/_event/${s}/${c}`;
219
220
  a.init = e.objectExpression([
220
221
  e.objectProperty(
221
222
  e.identifier("__isVeloEventStream"),
@@ -223,26 +224,26 @@ function z(u, o) {
223
224
  ),
224
225
  e.objectProperty(
225
226
  e.identifier("__path"),
226
- e.stringLiteral(r)
227
+ e.stringLiteral(n)
227
228
  )
228
229
  ]), a.id.typeAnnotation = null;
229
230
  }
230
- }), h(n, { retainLines: !0 }).code;
231
+ }), _(r, { retainLines: !0 }).code;
231
232
  }
232
- function Y(u, o) {
233
- const n = _(u, {
233
+ function X(p, s) {
234
+ const r = v(p, {
234
235
  sourceType: "module",
235
236
  plugins: ["typescript", "jsx"]
236
237
  });
237
- return m(n, {
238
+ return m(r, {
238
239
  ExportNamedDeclaration(l) {
239
240
  const t = l.node.declaration;
240
241
  if (!e.isVariableDeclaration(t)) return;
241
242
  const a = t.declarations[0];
242
243
  if (!a || !e.isIdentifier(a.id)) return;
243
- const s = a.id.name;
244
- if (!s.startsWith("socket_")) return;
245
- const c = s.replace("socket_", ""), r = `/_socket/${o}/${c}`;
244
+ const o = a.id.name;
245
+ if (!o.startsWith("socket_")) return;
246
+ const c = o.replace("socket_", ""), n = `/_socket/${s}/${c}`;
246
247
  a.init = e.objectExpression([
247
248
  e.objectProperty(
248
249
  e.identifier("__isVeloSocket"),
@@ -250,300 +251,303 @@ function Y(u, o) {
250
251
  ),
251
252
  e.objectProperty(
252
253
  e.identifier("__path"),
253
- e.stringLiteral(r)
254
+ e.stringLiteral(n)
254
255
  )
255
256
  ]), a.id.typeAnnotation = null;
256
257
  }
257
- }), h(n, { retainLines: !0 }).code;
258
+ }), _(r, { retainLines: !0 }).code;
258
259
  }
259
- function X(u) {
260
- const o = _(u, {
260
+ function q(p) {
261
+ const s = v(p, {
261
262
  sourceType: "module",
262
263
  plugins: ["typescript", "jsx"]
263
264
  });
264
- return m(o, {
265
+ return m(s, {
265
266
  ExportNamedDeclaration(i) {
266
267
  const l = i.node.declaration;
267
268
  if (!e.isVariableDeclaration(l)) return;
268
269
  const t = l.declarations[0];
269
270
  !t || !e.isIdentifier(t.id) || t.id.name === "loader" && i.remove();
270
271
  }
271
- }), h(o, { retainLines: !0 }).code;
272
+ }), _(s, { retainLines: !0 }).code;
272
273
  }
273
- function q(u) {
274
- const o = _(u, {
274
+ function K(p) {
275
+ const s = v(p, {
275
276
  sourceType: "module",
276
277
  plugins: ["typescript", "jsx"]
277
- }), n = /* @__PURE__ */ new Set();
278
- x(o.program, n);
278
+ }), r = /* @__PURE__ */ new Set();
279
+ I(s.program, r);
279
280
  let i = !1;
280
- return m(o, {
281
+ return m(s, {
281
282
  ImportDeclaration(t) {
282
283
  const a = t.node.specifiers;
283
284
  if (a.length === 0) return;
284
- const s = a.filter((c) => n.has(c.local.name));
285
- s.length !== a.length && (i = !0, s.length === 0 ? t.remove() : t.node.specifiers = s);
285
+ const o = a.filter((c) => r.has(c.local.name));
286
+ o.length !== a.length && (i = !0, o.length === 0 ? t.remove() : t.node.specifiers = o);
286
287
  }
287
- }), i ? h(o, { retainLines: !0 }).code : u;
288
+ }), i ? _(s, { retainLines: !0 }).code : p;
288
289
  }
289
- function K(u) {
290
- const o = _(u, {
290
+ function Q(p) {
291
+ const s = v(p, {
291
292
  sourceType: "module",
292
293
  plugins: ["typescript", "jsx"]
293
- }), n = [];
294
- if (m(o, {
295
- ObjectProperty(s) {
296
- e.isIdentifier(s.node.key, { name: "middlewares" }) && (n.push(s.node.value), s.remove());
294
+ }), r = [];
295
+ if (m(s, {
296
+ ObjectProperty(o) {
297
+ e.isIdentifier(o.node.key, { name: "middlewares" }) && (r.push(o.node.value), o.remove());
297
298
  }
298
- }), n.length === 0) return u;
299
+ }), r.length === 0) return p;
299
300
  const i = /* @__PURE__ */ new Set();
300
- for (const s of n)
301
- x(s, i);
301
+ for (const o of r)
302
+ I(o, i);
302
303
  const l = /* @__PURE__ */ new Set();
303
- x(o.program, l);
304
+ I(s.program, l);
304
305
  const t = /* @__PURE__ */ new Set();
305
- for (const s of i)
306
- l.has(s) || t.add(s);
307
- return t.size > 0 && m(o, {
308
- ImportDeclaration(s) {
309
- const c = s.node.specifiers, r = c.filter((p) => !t.has(p.local.name));
310
- r.length === 0 ? s.remove() : r.length !== c.length && (s.node.specifiers = r);
306
+ for (const o of i)
307
+ l.has(o) || t.add(o);
308
+ return t.size > 0 && m(s, {
309
+ ImportDeclaration(o) {
310
+ const c = o.node.specifiers, n = c.filter((u) => !t.has(u.local.name));
311
+ n.length === 0 ? o.remove() : n.length !== c.length && (o.node.specifiers = n);
311
312
  }
312
- }), h(o, { retainLines: !0 }).code;
313
+ }), _(s, { retainLines: !0 }).code;
313
314
  }
314
- function x(u, o) {
315
- const n = (i) => {
315
+ function I(p, s) {
316
+ const r = (i) => {
316
317
  if (!(!i || typeof i != "object")) {
317
318
  if (Array.isArray(i)) {
318
- for (const l of i) n(l);
319
+ for (const l of i) r(l);
319
320
  return;
320
321
  }
321
322
  if (i.type === "Identifier") {
322
- o.add(i.name), i.typeAnnotation && n(i.typeAnnotation);
323
+ s.add(i.name), i.typeAnnotation && r(i.typeAnnotation);
323
324
  return;
324
325
  }
325
326
  if (i.type === "JSXIdentifier") {
326
- o.add(i.name);
327
+ s.add(i.name);
327
328
  return;
328
329
  }
329
330
  if (i.type === "MemberExpression") {
330
- n(i.object), i.computed && n(i.property);
331
+ r(i.object), i.computed && r(i.property);
331
332
  return;
332
333
  }
333
334
  if ((i.type === "ObjectProperty" || i.type === "ObjectMethod") && !i.computed) {
334
- i.type === "ObjectProperty" ? n(i.value) : n(i.body);
335
+ i.type === "ObjectProperty" ? r(i.value) : r(i.body);
335
336
  return;
336
337
  }
337
338
  if (!(i.type === "ImportSpecifier" || i.type === "ImportDefaultSpecifier" || i.type === "ImportNamespaceSpecifier"))
338
339
  for (const l of Object.keys(i))
339
- l === "loc" || l === "start" || l === "end" || l === "leadingComments" || l === "trailingComments" || l === "innerComments" || n(i[l]);
340
+ l === "loc" || l === "start" || l === "end" || l === "leadingComments" || l === "trailingComments" || l === "innerComments" || r(i[l]);
340
341
  }
341
342
  };
342
- n(u);
343
+ r(p);
343
344
  }
344
- function Q(u) {
345
- for (const o of u.properties)
346
- if (e.isObjectProperty(o) && e.isIdentifier(o.key) && o.key.name === "handler")
345
+ function Z(p) {
346
+ for (const s of p.properties)
347
+ if (e.isObjectProperty(s) && e.isIdentifier(s.key) && s.key.name === "handler")
347
348
  return !0;
348
349
  return !1;
349
350
  }
350
- function Z(u) {
351
- for (const o of u.properties)
352
- if (e.isObjectProperty(o) && e.isIdentifier(o.key) && o.key.name === "children" && e.isArrayExpression(o.value))
353
- return o.value;
351
+ function ee(p) {
352
+ for (const s of p.properties)
353
+ if (e.isObjectProperty(s) && e.isIdentifier(s.key) && s.key.name === "children" && e.isArrayExpression(s.value))
354
+ return s.value;
354
355
  return null;
355
356
  }
356
- function ee(u) {
357
- const o = _(u, {
357
+ function te(p) {
358
+ const s = v(p, {
358
359
  sourceType: "module",
359
360
  plugins: ["typescript", "jsx"]
360
- }), n = [], i = (c) => {
361
- for (let r = c.elements.length - 1; r >= 0; r--) {
362
- const p = c.elements[r];
363
- if (!e.isObjectExpression(p)) continue;
364
- if (Q(p)) {
365
- n.push(p), c.elements.splice(r, 1);
361
+ }), r = [], i = (c) => {
362
+ for (let n = c.elements.length - 1; n >= 0; n--) {
363
+ const u = c.elements[n];
364
+ if (!e.isObjectExpression(u)) continue;
365
+ if (Z(u)) {
366
+ r.push(u), c.elements.splice(n, 1);
366
367
  continue;
367
368
  }
368
- const f = Z(p);
369
+ const f = ee(u);
369
370
  f && i(f);
370
371
  }
371
372
  };
372
- if (m(o, {
373
+ if (m(s, {
373
374
  ExportDefaultDeclaration(c) {
374
- const r = c.node.declaration;
375
- let p = null;
376
- e.isArrayExpression(r) ? p = r : (e.isTSSatisfiesExpression(r) && e.isArrayExpression(r.expression) || e.isTSAsExpression(r) && e.isArrayExpression(r.expression)) && (p = r.expression), p && i(p);
375
+ const n = c.node.declaration;
376
+ let u = null;
377
+ e.isArrayExpression(n) ? u = n : (e.isTSSatisfiesExpression(n) && e.isArrayExpression(n.expression) || e.isTSAsExpression(n) && e.isArrayExpression(n.expression)) && (u = n.expression), u && i(u);
377
378
  }
378
- }), n.length === 0) return u;
379
+ }), r.length === 0) return p;
379
380
  const l = /* @__PURE__ */ new Set();
380
- for (const c of n)
381
- x(c, l);
381
+ for (const c of r)
382
+ I(c, l);
382
383
  const t = /* @__PURE__ */ new Set();
383
- x(o.program, t);
384
+ I(s.program, t);
384
385
  const a = /* @__PURE__ */ new Set();
385
386
  for (const c of l)
386
387
  t.has(c) || a.add(c);
387
- return a.size > 0 && m(o, {
388
+ return a.size > 0 && m(s, {
388
389
  ImportDeclaration(c) {
389
- const r = c.node.specifiers, p = r.filter((f) => !a.has(f.local.name));
390
- p.length === 0 ? c.remove() : p.length !== r.length && (c.node.specifiers = p);
390
+ const n = c.node.specifiers, u = n.filter((f) => !a.has(f.local.name));
391
+ u.length === 0 ? c.remove() : u.length !== n.length && (c.node.specifiers = u);
391
392
  }
392
- }), h(o, { retainLines: !0 }).code;
393
+ }), _(s, { retainLines: !0 }).code;
393
394
  }
394
- function A(u) {
395
- const o = _(u, {
395
+ function w(p) {
396
+ const s = v(p, {
396
397
  sourceType: "module",
397
398
  plugins: ["typescript", "jsx"]
398
- }), n = /* @__PURE__ */ new Map();
399
- m(o, {
399
+ }), r = /* @__PURE__ */ new Map();
400
+ m(s, {
400
401
  ImportDeclaration(t) {
401
402
  const a = t.node.source.value;
402
- for (const s of t.node.specifiers)
403
- e.isImportNamespaceSpecifier(s) && n.set(s.local.name, a);
403
+ for (const o of t.node.specifiers)
404
+ e.isImportNamespaceSpecifier(o) && r.set(o.local.name, a);
404
405
  }
405
406
  });
406
407
  const i = /* @__PURE__ */ new Map();
407
- m(o, {
408
+ m(s, {
408
409
  ExportDefaultDeclaration(t) {
409
410
  const a = t.node.declaration;
410
- let s = null;
411
- e.isArrayExpression(a) ? s = a : (e.isTSSatisfiesExpression(a) || e.isTSAsExpression(a)) && e.isArrayExpression(a.expression) && (s = a.expression), s && C(s.elements, "", i);
411
+ let o = null;
412
+ e.isArrayExpression(a) ? o = a : (e.isTSSatisfiesExpression(a) || e.isTSAsExpression(a)) && e.isArrayExpression(a.expression) && (o = a.expression), o && k(o.elements, "", i);
412
413
  }
413
414
  });
414
415
  const l = /* @__PURE__ */ new Map();
415
416
  for (const [t, a] of i) {
416
- const s = n.get(t);
417
- if (s) {
418
- const c = s.replace(/^\.\//, "").replace(/\.(tsx?|jsx?|js)$/, "");
417
+ const o = r.get(t);
418
+ if (o) {
419
+ const c = o.replace(/^\.\//, "").replace(/\.(tsx?|jsx?|js)$/, "");
419
420
  l.set(c, a);
420
421
  }
421
422
  }
422
423
  return l;
423
424
  }
424
- function C(u, o, n) {
425
- for (const i of u) {
425
+ function k(p, s, r) {
426
+ for (const i of p) {
426
427
  if (!e.isObjectExpression(i)) continue;
427
- let l = "", t = o, a = null, s = null;
428
+ let l = "", t = s, a = null, o = null;
428
429
  for (const c of i.properties) {
429
430
  if (!e.isObjectProperty(c)) continue;
430
- const r = c.key, p = e.isIdentifier(r) ? r.name : null;
431
- p === "path" && e.isStringLiteral(c.value) && (l = c.value.value, l && !l.startsWith("/") ? t = o + "/" + l : t = o + l), p === "module" && e.isIdentifier(c.value) && (a = c.value.name), p === "children" && e.isArrayExpression(c.value) && (s = c.value);
431
+ const n = c.key, u = e.isIdentifier(n) ? n.name : null;
432
+ u === "path" && e.isStringLiteral(c.value) && (l = c.value.value, l && !l.startsWith("/") ? t = s + "/" + l : t = s + l), u === "module" && e.isIdentifier(c.value) && (a = c.value.name), u === "children" && e.isArrayExpression(c.value) && (o = c.value);
432
433
  }
433
434
  if (a) {
434
- const r = !s && l === "/" ? o || "/" : t;
435
- n.set(a, {
436
- fullPath: r,
435
+ const n = !o && l === "/" ? s || "/" : t;
436
+ r.set(a, {
437
+ fullPath: n,
437
438
  path: l
438
439
  });
439
440
  }
440
- s && C(s.elements, t, n);
441
+ o && k(o.elements, t, r);
441
442
  }
442
443
  }
443
- const E = "virtual:velo/server-entry", b = "virtual:velo/client-entry", N = "\0" + E, P = "\0" + b;
444
- function te(u, o) {
445
- let n = d.resolve(process.cwd(), o);
446
- const i = u.routesFile ?? "routes.tsx", l = /* @__PURE__ */ new Map();
444
+ const T = "virtual:velo/server-entry", O = "virtual:velo/client-entry", C = "\0" + T, F = "\0" + O;
445
+ function re(p, s) {
446
+ let r = d.resolve(process.cwd(), s);
447
+ const i = p.routesFile ?? "routes.tsx", l = /* @__PURE__ */ new Map();
447
448
  return {
448
449
  name: "velo:transform",
449
450
  enforce: "pre",
450
451
  configResolved(t) {
451
- n = d.resolve(t.root, o);
452
+ r = d.resolve(t.root, s);
452
453
  },
453
454
  buildStart() {
454
- const t = d.join(n, i);
455
- if (g.existsSync(t)) {
456
- const a = g.readFileSync(t, "utf-8"), s = A(a);
455
+ const t = d.join(r, i);
456
+ if (S.existsSync(t)) {
457
+ const a = S.readFileSync(t, "utf-8"), o = w(a);
457
458
  l.clear();
458
- for (const [c, r] of s)
459
- l.set(c, r);
459
+ for (const [c, n] of o)
460
+ l.set(c, n);
460
461
  }
461
462
  },
462
463
  handleHotUpdate({ file: t, server: a }) {
463
- const s = d.join(n, i);
464
- if (t === s) {
465
- const c = g.readFileSync(s, "utf-8"), r = A(c);
464
+ const o = d.join(r, i);
465
+ if (t === o) {
466
+ const c = S.readFileSync(o, "utf-8"), n = w(c);
466
467
  l.clear();
467
- for (const [p, f] of r)
468
- l.set(p, f);
468
+ for (const [u, f] of n)
469
+ l.set(u, f);
469
470
  return a.ws.send({ type: "full-reload" }), [];
470
471
  }
471
472
  },
472
473
  resolveId(t) {
473
- return t === E || t.endsWith(E) ? N : t === b || t.endsWith(b) || t === "/__velo_client.js" ? P : null;
474
+ return t === T || t.endsWith(T) ? C : t === O || t.endsWith(O) || t === "/__velo_client.js" ? F : null;
474
475
  },
475
476
  load(t) {
476
- const a = u.routesFile ?? "routes.tsx", s = u.serverInit ?? "server.tsx", c = u.clientInit ?? "client.tsx", r = d.join(n, a).replace(/\.tsx?$/, ".js"), p = d.join(n, s).replace(/\.tsx?$/, ".js"), f = d.join(n, c).replace(/\.tsx?$/, ".js");
477
- return t === N ? `
477
+ const a = p.routesFile ?? "routes.tsx", o = p.serverInit ?? "server.tsx", c = p.clientInit ?? "client.tsx", n = d.join(r, a).replace(/\.tsx?$/, ".js"), u = d.join(r, o).replace(/\.tsx?$/, ".js"), f = d.join(r, c).replace(/\.tsx?$/, ".js");
478
+ return t === C ? `
478
479
  globalThis.__veloBuildHash = __VELO_BUILD_HASH__;
479
480
  globalThis.__veloClientJs = __VELO_CLIENT_JS__;
480
481
  globalThis.__veloClientCss = __VELO_CLIENT_CSS__;
481
- import "${p}";
482
- import routes from "${r}";
482
+ import "${u}";
483
+ import routes from "${n}";
483
484
  import { startServer } from "@mauroandre/velojs/server";
484
485
 
485
486
  export { routes };
486
487
  export default await startServer({ routes, port: __VELO_CONFIG_PORT__, hostname: __VELO_CONFIG_HOSTNAME__ });
487
- ` : t === P ? `
488
+ ` : t === F ? `
488
489
  import "${f}";
489
- import routes from "${r}";
490
+ import routes from "${n}";
490
491
  import { startClient } from "@mauroandre/velojs/client";
491
492
 
492
493
  startClient({ routes });
493
494
  ` : null;
494
495
  },
495
- transform(t, a, s) {
496
- const c = s?.ssr === !0;
497
- if (a.startsWith("\0") || a.includes("/.velojs/") || !a.endsWith(".tsx") && !a.endsWith(".ts") || !a.startsWith(n)) return null;
498
- let r = t, p = !1;
499
- const f = /middlewares:\s*\[/.test(t), y = /export\s+(const|function)\s+Component/.test(
496
+ transform(t, a, o) {
497
+ const c = o?.ssr === !0;
498
+ if (a.startsWith("\0") || a.includes("/.velojs/") || !a.endsWith(".tsx") && !a.endsWith(".ts") || !a.startsWith(r)) return null;
499
+ let n = t, u = !1;
500
+ const f = /middlewares:\s*\[/.test(t), h = /export\s+(const|function)\s+Component/.test(
500
501
  t
501
- ), v = /export\s+(const|function)\s+loader/.test(t), D = /export\s+const\s+action_\w+/.test(t), I = /export\s+const\s+stream_\w+/.test(t), T = /export\s+const\s+socket_\w+/.test(t), w = /\bLoader\s*</.test(t) || /\bLoader\s*\(/.test(t), F = /\buseLoader\s*</.test(t) || /\buseLoader\s*\(/.test(t), k = /\bhandler\s*:/.test(t), V = d.join(n, i);
502
- if (!c && f && (r = K(r), p = !0), !c && k && a === V && (r = ee(r), p = !0), y || v || D || I || T || w || F) {
503
- const S = d.relative(n, a).replace(/\.(tsx?|jsx?)$/, "").replace(/\\/g, "/"), O = l.get(S);
504
- r = W(r, S, O?.fullPath, O?.path), r = M(r, S), c || (r = B(
505
- r,
506
- S
507
- )), !c && I && (r = z(
508
- r,
509
- S
510
- )), !c && T && (r = Y(
511
- r,
512
- S
513
- )), c || (r = X(r)), c || (r = q(r)), p = !0;
502
+ ), y = /export\s+(const|function)\s+loader/.test(t), b = /export\s+const\s+action_\w+/.test(t), j = /export\s+const\s+stream_\w+/.test(t), x = /export\s+const\s+socket_\w+/.test(t), L = /\bLoader\s*</.test(t) || /\bLoader\s*\(/.test(t), P = /\buseLoader\s*</.test(t) || /\buseLoader\s*\(/.test(t), E = /\bhandler\s*:/.test(t), V = d.join(r, i);
503
+ if (!c && f && (n = Q(n), u = !0), !c && E && a === V && (n = te(n), u = !0), h || y || b || j || x || L || P) {
504
+ const g = d.relative(r, a).replace(/\.(tsx?|jsx?)$/, "").replace(/\\/g, "/"), D = l.get(g);
505
+ n = W(n, g, D?.fullPath, D?.path), n = B(n, g), c || (n = M(
506
+ n,
507
+ g
508
+ )), !c && j && (n = Y(
509
+ n,
510
+ g
511
+ )), !c && x && (n = X(
512
+ n,
513
+ g
514
+ )), c || (n = q(n)), c || (n = K(n)), u = !0;
514
515
  }
515
- return p ? {
516
- code: r,
516
+ return u ? {
517
+ code: n,
517
518
  map: null
518
519
  } : null;
519
520
  }
520
521
  };
521
522
  }
522
- function re(u) {
523
+ function ne(p) {
523
524
  return {
524
525
  name: "velo:config",
525
- config(o, { mode: n }) {
526
- const i = n === "server", l = n === "development", t = !!process.env.VELO_STATIC, a = o.server?.port ?? (Number(process.env.PORT) || u.port || 3e3);
527
- let s = "client.js", c = "client.css";
526
+ config(s, { mode: r }) {
527
+ const i = r === "server", l = r === "development", t = !!process.env.VELO_STATIC, a = s.server?.port ?? (Number(process.env.PORT) || p.port || 3e3), o = d.resolve(
528
+ process.cwd(),
529
+ s.root ?? "."
530
+ ), c = s.envDir ? d.resolve(o, s.envDir) : o, n = R(r, c, ""), u = process.env.HOST?.trim() || n.HOST?.trim() || void 0, f = s.server?.host ?? u ?? p.hostname, h = f === !0 || f === "0.0.0.0" || f === "::", y = s.server?.allowedHosts ?? (h ? !0 : void 0);
531
+ let b = "client.js", j = "client.css";
528
532
  if (i)
529
533
  try {
530
- const p = d.resolve(process.cwd(), "dist/client/.vite/manifest.json"), y = JSON.parse(g.readFileSync(p, "utf-8"))[b];
531
- y && (s = y.file || s, y.css?.[0] && (c = y.css[0]));
534
+ const L = d.resolve(process.cwd(), "dist/client/.vite/manifest.json"), E = JSON.parse(S.readFileSync(L, "utf-8"))[O];
535
+ E && (b = E.file || b, E.css?.[0] && (j = E.css[0]));
532
536
  } catch {
533
537
  }
534
- const r = {
538
+ const x = {
535
539
  define: {
536
540
  "process.env.NODE_ENV": JSON.stringify(l ? "development" : "production"),
537
541
  "process.env.STATIC_BASE_URL": JSON.stringify(process.env.STATIC_BASE_URL || (t ? "/client" : "")),
538
542
  __VELO_STATIC__: JSON.stringify(t),
539
543
  __VELO_BUILD_HASH__: JSON.stringify(process.env.VELO_BUILD_HASH || Date.now().toString(36)),
540
- __VELO_CLIENT_JS__: JSON.stringify(s),
541
- __VELO_CLIENT_CSS__: JSON.stringify(c),
544
+ __VELO_CLIENT_JS__: JSON.stringify(b),
545
+ __VELO_CLIENT_CSS__: JSON.stringify(j),
542
546
  // Baked into the server bundle as startServer's port fallback.
543
547
  // null when unset → startServer falls back to PORT env / 3000.
544
- __VELO_CONFIG_PORT__: JSON.stringify(u.port ?? null),
548
+ __VELO_CONFIG_PORT__: JSON.stringify(p.port ?? null),
545
549
  // Same for the bind interface: null → HOST env / Node default.
546
- __VELO_CONFIG_HOSTNAME__: JSON.stringify(u.hostname ?? null)
550
+ __VELO_CONFIG_HOSTNAME__: JSON.stringify(p.hostname ?? null)
547
551
  },
548
552
  resolve: {
549
553
  alias: {
@@ -552,11 +556,15 @@ function re(u) {
552
556
  }
553
557
  },
554
558
  server: {
555
- port: a
559
+ port: a,
560
+ // Host and allowedHosts only shape the dev server; in build
561
+ // they are inert, so we keep them out of the build config.
562
+ ...l && f !== void 0 ? { host: f } : {},
563
+ ...l && y !== void 0 ? { allowedHosts: y } : {}
556
564
  }
557
565
  };
558
- return i ? r.build = {
559
- ssr: E,
566
+ return i ? x.build = {
567
+ ssr: T,
560
568
  outDir: "dist",
561
569
  emptyOutDir: !1,
562
570
  copyPublicDir: !1,
@@ -565,107 +573,107 @@ function re(u) {
565
573
  entryFileNames: "server.js"
566
574
  }
567
575
  }
568
- } : l || (r.build = {
576
+ } : l || (x.build = {
569
577
  manifest: !0,
570
578
  outDir: "dist/client",
571
579
  rollupOptions: {
572
- input: b,
580
+ input: O,
573
581
  output: {
574
582
  entryFileNames: "client.[hash].js",
575
- assetFileNames: (p) => p.names?.[0]?.endsWith(".css") ? "client.[hash].css" : "[name].[hash][extname]"
583
+ assetFileNames: (L) => L.names?.[0]?.endsWith(".css") ? "client.[hash].css" : "[name].[hash][extname]"
576
584
  }
577
585
  }
578
- }), r;
586
+ }), x;
579
587
  }
580
588
  };
581
589
  }
582
- function ne() {
590
+ function ie() {
583
591
  return {
584
592
  name: "velo:static-url",
585
593
  apply: "build",
586
594
  enforce: "post",
587
- generateBundle(u, o) {
588
- const n = process.env.STATIC_BASE_URL || "";
589
- if (n)
590
- for (const i of Object.values(o))
595
+ generateBundle(p, s) {
596
+ const r = process.env.STATIC_BASE_URL || "";
597
+ if (r)
598
+ for (const i of Object.values(s))
591
599
  i.type === "asset" && typeof i.source == "string" && i.fileName.endsWith(".css") && (i.source = i.source.replace(
592
600
  /url\(\s*(['"]?)\/(?!\/)/g,
593
- `url($1${n}/`
601
+ `url($1${r}/`
594
602
  ));
595
603
  }
596
604
  };
597
605
  }
598
- function ie(u, o) {
599
- let n = "", i = "", l = !1, t = null;
606
+ function se(p, s) {
607
+ let r = "", i = "", l = !1, t = null;
600
608
  function a() {
601
- if (!n) return;
602
- const s = d.resolve(n, o);
603
- if (!g.existsSync(s)) return;
604
- const c = U(s), r = d.join(n, ".velojs");
605
- g.mkdirSync(r, { recursive: !0 }), g.writeFileSync(
606
- d.join(r, "graph.json"),
609
+ if (!r) return;
610
+ const o = d.resolve(r, s);
611
+ if (!S.existsSync(o)) return;
612
+ const c = U(o), n = d.join(r, ".velojs");
613
+ S.mkdirSync(n, { recursive: !0 }), S.writeFileSync(
614
+ d.join(n, "graph.json"),
607
615
  JSON.stringify(c)
608
616
  );
609
617
  }
610
618
  return {
611
619
  name: "velo:graph",
612
- configResolved(s) {
613
- n = s.root, i = s.mode;
620
+ configResolved(o) {
621
+ r = o.root, i = o.mode;
614
622
  },
615
623
  writeBundle() {
616
624
  i !== "server" && a();
617
625
  },
618
- configureServer(s) {
626
+ configureServer(o) {
619
627
  a(), l = !0;
620
- const c = d.resolve(n, o);
621
- s.watcher.on("all", (r, p) => {
622
- l && p.startsWith(c) && (t && clearTimeout(t), t = setTimeout(() => a(), 500));
628
+ const c = d.resolve(r, s);
629
+ o.watcher.on("all", (n, u) => {
630
+ l && u.startsWith(c) && (t && clearTimeout(t), t = setTimeout(() => a(), 500));
623
631
  });
624
632
  }
625
633
  };
626
634
  }
627
- function se(u) {
635
+ function oe(p) {
628
636
  return [
629
637
  ...J.exclude,
630
638
  /.*\.mjs$/,
631
- ...u.devServerExclude ?? []
639
+ ...p.devServerExclude ?? []
632
640
  ];
633
641
  }
634
- function ye(u) {
635
- const o = u ?? {}, n = o.appDirectory ?? "./app";
642
+ function _e(p) {
643
+ const s = p ?? {}, r = s.appDirectory ?? "./app";
636
644
  return [
637
- re(o),
638
- te(o, n),
639
- ne(),
640
- ie(o, n),
641
- R(),
642
- $({
643
- entry: E,
644
- exclude: se(o)
645
+ ne(s),
646
+ re(s, r),
647
+ ie(),
648
+ se(s, r),
649
+ $(),
650
+ H({
651
+ entry: T,
652
+ exclude: oe(s)
645
653
  }),
646
- oe()
654
+ ae()
647
655
  ];
648
656
  }
649
- function oe() {
657
+ function ae() {
650
658
  return {
651
659
  name: "velo:ws-bridge",
652
- configureServer(u) {
653
- globalThis.__veloDevServer = u.httpServer;
660
+ configureServer(p) {
661
+ globalThis.__veloDevServer = p.httpServer;
654
662
  }
655
663
  };
656
664
  }
657
665
  export {
658
- A as buildFullPathMap,
659
- C as collectFullPaths,
660
- se as devServerExcludeFor,
666
+ w as buildFullPathMap,
667
+ k as collectFullPaths,
668
+ oe as devServerExcludeFor,
661
669
  W as injectMetadata,
662
- q as pruneClientOnlyImports,
663
- ee as removeEndpointRoutes,
664
- X as removeLoaders,
665
- K as removeMiddlewares,
666
- B as transformActionsForClient,
667
- M as transformLoaderFunctions,
668
- Y as transformSocketsForClient,
669
- z as transformStreamsForClient,
670
- ye as veloPlugin
670
+ K as pruneClientOnlyImports,
671
+ te as removeEndpointRoutes,
672
+ q as removeLoaders,
673
+ Q as removeMiddlewares,
674
+ M as transformActionsForClient,
675
+ B as transformLoaderFunctions,
676
+ X as transformSocketsForClient,
677
+ Y as transformStreamsForClient,
678
+ _e as veloPlugin
671
679
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mauroandre/velojs",
3
- "version": "0.0.54",
3
+ "version": "0.0.55",
4
4
  "type": "module",
5
5
  "description": "Fullstack web framework built on Hono + Preact with Vite-powered AST transforms",
6
6
  "keywords": [