@vesk/vesk-cli 0.2.70 → 0.2.72
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/dist/cli.js +164 -66
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -53010,6 +53010,142 @@ function installResponsePipeline(res, req, options = {}) {
|
|
|
53010
53010
|
});
|
|
53011
53011
|
}
|
|
53012
53012
|
|
|
53013
|
+
// ../adapter/src/web-request.ts
|
|
53014
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
53015
|
+
function bodyTooLarge(maxBytes) {
|
|
53016
|
+
const err = new Error(`Request body exceeds limit (${maxBytes} bytes)`);
|
|
53017
|
+
err.status = 413;
|
|
53018
|
+
return err;
|
|
53019
|
+
}
|
|
53020
|
+
function makeWebRequest(nodeReq, url, maxBodyBytes = DEFAULT_MAX_BODY_BYTES) {
|
|
53021
|
+
const parsedUrl = new URL(url, `http://${nodeReq.headers.host || "localhost"}`);
|
|
53022
|
+
const method = nodeReq.method || "GET";
|
|
53023
|
+
let cachedBody = null;
|
|
53024
|
+
let streamTaken = false;
|
|
53025
|
+
let streamEnded = false;
|
|
53026
|
+
const endWaiters = [];
|
|
53027
|
+
const settleEnd = (body) => {
|
|
53028
|
+
if (body !== null) cachedBody = body;
|
|
53029
|
+
streamEnded = true;
|
|
53030
|
+
for (const resolve41 of endWaiters.splice(0)) resolve41();
|
|
53031
|
+
};
|
|
53032
|
+
function createBodyStream() {
|
|
53033
|
+
streamTaken = true;
|
|
53034
|
+
const cache2 = [];
|
|
53035
|
+
let total = 0;
|
|
53036
|
+
return new ReadableStream({
|
|
53037
|
+
start(controller) {
|
|
53038
|
+
nodeReq.on("data", (chunk) => {
|
|
53039
|
+
total += chunk.length;
|
|
53040
|
+
if (total > maxBodyBytes) {
|
|
53041
|
+
settleEnd(Buffer2.concat(cache2));
|
|
53042
|
+
cache2.length = 0;
|
|
53043
|
+
try {
|
|
53044
|
+
controller.error(bodyTooLarge(maxBodyBytes));
|
|
53045
|
+
} catch {
|
|
53046
|
+
}
|
|
53047
|
+
nodeReq.destroy();
|
|
53048
|
+
return;
|
|
53049
|
+
}
|
|
53050
|
+
cache2.push(chunk);
|
|
53051
|
+
try {
|
|
53052
|
+
controller.enqueue(new Uint8Array(chunk));
|
|
53053
|
+
} catch {
|
|
53054
|
+
}
|
|
53055
|
+
});
|
|
53056
|
+
nodeReq.on("end", () => {
|
|
53057
|
+
settleEnd(Buffer2.concat(cache2));
|
|
53058
|
+
cache2.length = 0;
|
|
53059
|
+
try {
|
|
53060
|
+
controller.close();
|
|
53061
|
+
} catch {
|
|
53062
|
+
}
|
|
53063
|
+
});
|
|
53064
|
+
nodeReq.on("error", (e) => {
|
|
53065
|
+
settleEnd(Buffer2.concat(cache2));
|
|
53066
|
+
cache2.length = 0;
|
|
53067
|
+
try {
|
|
53068
|
+
controller.error(e);
|
|
53069
|
+
} catch {
|
|
53070
|
+
}
|
|
53071
|
+
});
|
|
53072
|
+
}
|
|
53073
|
+
});
|
|
53074
|
+
}
|
|
53075
|
+
async function getBody() {
|
|
53076
|
+
if (cachedBody) return cachedBody;
|
|
53077
|
+
if (streamTaken) {
|
|
53078
|
+
while (!streamEnded) await new Promise((r) => endWaiters.push(r));
|
|
53079
|
+
return cachedBody || Buffer2.alloc(0);
|
|
53080
|
+
}
|
|
53081
|
+
const chunks = [];
|
|
53082
|
+
let total = 0;
|
|
53083
|
+
for await (const chunk of nodeReq) {
|
|
53084
|
+
total += chunk.byteLength;
|
|
53085
|
+
if (total > maxBodyBytes) throw bodyTooLarge(maxBodyBytes);
|
|
53086
|
+
chunks.push(Buffer2.from(chunk));
|
|
53087
|
+
}
|
|
53088
|
+
cachedBody = Buffer2.concat(chunks);
|
|
53089
|
+
return cachedBody;
|
|
53090
|
+
}
|
|
53091
|
+
const webRequest = new Request(parsedUrl, {
|
|
53092
|
+
method,
|
|
53093
|
+
headers: nodeReq.headers,
|
|
53094
|
+
body: null
|
|
53095
|
+
});
|
|
53096
|
+
let bodyStream = null;
|
|
53097
|
+
Object.defineProperty(webRequest, "body", {
|
|
53098
|
+
configurable: true,
|
|
53099
|
+
enumerable: false,
|
|
53100
|
+
get: () => {
|
|
53101
|
+
if (bodyStream) return bodyStream;
|
|
53102
|
+
if (method === "GET" || method === "HEAD") return null;
|
|
53103
|
+
bodyStream = createBodyStream();
|
|
53104
|
+
return bodyStream;
|
|
53105
|
+
}
|
|
53106
|
+
});
|
|
53107
|
+
webRequest.json = async () => {
|
|
53108
|
+
try {
|
|
53109
|
+
return JSON.parse((await getBody()).toString());
|
|
53110
|
+
} catch {
|
|
53111
|
+
return null;
|
|
53112
|
+
}
|
|
53113
|
+
};
|
|
53114
|
+
webRequest.text = async () => (await getBody()).toString("utf-8");
|
|
53115
|
+
webRequest.formData = async () => {
|
|
53116
|
+
const body = await getBody();
|
|
53117
|
+
const ct = String(nodeReq.headers["content-type"] || "");
|
|
53118
|
+
if (ct.includes("multipart/form-data")) {
|
|
53119
|
+
const temp = new Request("http://localhost", { method: "POST", headers: nodeReq.headers, body });
|
|
53120
|
+
return temp.formData();
|
|
53121
|
+
}
|
|
53122
|
+
const fd = new FormData();
|
|
53123
|
+
if (ct.includes("x-www-form-urlencoded")) {
|
|
53124
|
+
for (const [k, v] of new URLSearchParams(body.toString()).entries()) fd.append(k, v);
|
|
53125
|
+
}
|
|
53126
|
+
return fd;
|
|
53127
|
+
};
|
|
53128
|
+
webRequest.clone = () => webRequest;
|
|
53129
|
+
const cookies2 = {};
|
|
53130
|
+
for (const part of String(nodeReq.headers.cookie || "").split(";")) {
|
|
53131
|
+
const eq = part.indexOf("=");
|
|
53132
|
+
if (eq === -1) continue;
|
|
53133
|
+
const name = part.slice(0, eq).trim();
|
|
53134
|
+
if (!name) continue;
|
|
53135
|
+
const raw2 = part.slice(eq + 1).trim();
|
|
53136
|
+
try {
|
|
53137
|
+
cookies2[name] = decodeURIComponent(raw2);
|
|
53138
|
+
} catch {
|
|
53139
|
+
cookies2[name] = raw2;
|
|
53140
|
+
}
|
|
53141
|
+
}
|
|
53142
|
+
webRequest.cookies = cookies2;
|
|
53143
|
+
const query = {};
|
|
53144
|
+
for (const [k, v] of parsedUrl.searchParams.entries()) query[k] = v;
|
|
53145
|
+
webRequest.query = query;
|
|
53146
|
+
return webRequest;
|
|
53147
|
+
}
|
|
53148
|
+
|
|
53013
53149
|
// ../adapter/src/prod-server.ts
|
|
53014
53150
|
init_platform_output();
|
|
53015
53151
|
var __dirname4 = dirname11(fileURLToPath3(import.meta.url));
|
|
@@ -53067,65 +53203,10 @@ function pumpRemaining(res, reader) {
|
|
|
53067
53203
|
res.end();
|
|
53068
53204
|
})();
|
|
53069
53205
|
}
|
|
53070
|
-
function bodyTooLarge(maxBytes) {
|
|
53071
|
-
const err = new Error(`Request body exceeds limit (${maxBytes} bytes)`);
|
|
53072
|
-
err.status = 413;
|
|
53073
|
-
return err;
|
|
53074
|
-
}
|
|
53075
53206
|
function errorStatus(e, fallback) {
|
|
53076
53207
|
const s = e?.status ?? e?.statusCode;
|
|
53077
53208
|
return typeof s === "number" && s >= 400 && s < 600 ? s : fallback;
|
|
53078
53209
|
}
|
|
53079
|
-
function makeWebRequest(nodeReq, url, maxBodyBytes = DEFAULT_MAX_BODY_BYTES) {
|
|
53080
|
-
const parsedUrl = new URL(url, `http://${nodeReq.headers.host || "localhost"}`);
|
|
53081
|
-
const method = nodeReq.method || "GET";
|
|
53082
|
-
let _bodyBuffer = null;
|
|
53083
|
-
async function getBody() {
|
|
53084
|
-
if (_bodyBuffer) return _bodyBuffer;
|
|
53085
|
-
const chunks = [];
|
|
53086
|
-
let total = 0;
|
|
53087
|
-
for await (const chunk of nodeReq) {
|
|
53088
|
-
total += chunk.byteLength;
|
|
53089
|
-
if (total > maxBodyBytes) throw bodyTooLarge(maxBodyBytes);
|
|
53090
|
-
chunks.push(Buffer.from(chunk));
|
|
53091
|
-
}
|
|
53092
|
-
_bodyBuffer = Buffer.concat(chunks);
|
|
53093
|
-
return _bodyBuffer;
|
|
53094
|
-
}
|
|
53095
|
-
const webRequest = new Request(parsedUrl, { method, headers: nodeReq.headers, body: null });
|
|
53096
|
-
webRequest.json = async () => {
|
|
53097
|
-
try {
|
|
53098
|
-
return JSON.parse((await getBody()).toString());
|
|
53099
|
-
} catch {
|
|
53100
|
-
return null;
|
|
53101
|
-
}
|
|
53102
|
-
};
|
|
53103
|
-
webRequest.text = async () => (await getBody()).toString("utf-8");
|
|
53104
|
-
webRequest.formData = async () => {
|
|
53105
|
-
const body = await getBody();
|
|
53106
|
-
const ct = String(nodeReq.headers["content-type"] || "");
|
|
53107
|
-
if (ct.includes("multipart/form-data")) {
|
|
53108
|
-
const temp = new Request("http://localhost", { method: "POST", headers: nodeReq.headers, body });
|
|
53109
|
-
return temp.formData();
|
|
53110
|
-
}
|
|
53111
|
-
const fd = new FormData();
|
|
53112
|
-
if (ct.includes("x-www-form-urlencoded")) {
|
|
53113
|
-
for (const [k, v] of new URLSearchParams(body.toString()).entries()) fd.append(k, v);
|
|
53114
|
-
}
|
|
53115
|
-
return fd;
|
|
53116
|
-
};
|
|
53117
|
-
webRequest.clone = () => webRequest;
|
|
53118
|
-
const cookies2 = {};
|
|
53119
|
-
for (const [k, v] of String(nodeReq.headers.cookie || "").split(";").map((s) => s.trim()).filter(Boolean)) {
|
|
53120
|
-
const eq = k.indexOf("=");
|
|
53121
|
-
if (eq > -1) cookies2[k.slice(0, eq)] = decodeURIComponent(k.slice(eq + 1));
|
|
53122
|
-
}
|
|
53123
|
-
webRequest.cookies = cookies2;
|
|
53124
|
-
const query = {};
|
|
53125
|
-
for (const [k, v] of parsedUrl.searchParams.entries()) query[k] = v;
|
|
53126
|
-
webRequest.query = query;
|
|
53127
|
-
return webRequest;
|
|
53128
|
-
}
|
|
53129
53210
|
async function startProdServer(outDir, options) {
|
|
53130
53211
|
const port = options?.port || 3e3;
|
|
53131
53212
|
const host = options?.host || "127.0.0.1";
|
|
@@ -53196,15 +53277,22 @@ async function startProdServer(outDir, options) {
|
|
|
53196
53277
|
}
|
|
53197
53278
|
}
|
|
53198
53279
|
const functionCache = /* @__PURE__ */ new Map();
|
|
53280
|
+
const functionFailures = /* @__PURE__ */ new Map();
|
|
53281
|
+
function functionFailure(funcPath) {
|
|
53282
|
+
return functionFailures.get(funcPath);
|
|
53283
|
+
}
|
|
53199
53284
|
async function loadFunction(funcPath) {
|
|
53200
53285
|
if (functionCache.has(funcPath)) return functionCache.get(funcPath);
|
|
53286
|
+
if (functionFailures.has(funcPath)) return null;
|
|
53201
53287
|
const fullPath = resolve14(outDir, funcPath);
|
|
53202
53288
|
if (!existsSync16(fullPath)) return null;
|
|
53203
53289
|
try {
|
|
53204
53290
|
const mod = await import(`${fullPath}?t=${Date.now()}`);
|
|
53205
53291
|
functionCache.set(funcPath, mod);
|
|
53206
53292
|
return mod;
|
|
53207
|
-
} catch {
|
|
53293
|
+
} catch (e) {
|
|
53294
|
+
console.error(`vesk start: failed to load ${funcPath}:`, e instanceof Error ? e.message : e);
|
|
53295
|
+
functionFailures.set(funcPath, e);
|
|
53208
53296
|
return null;
|
|
53209
53297
|
}
|
|
53210
53298
|
}
|
|
@@ -53467,18 +53555,24 @@ async function startProdServer(outDir, options) {
|
|
|
53467
53555
|
const params = matchPath(route.path, url.pathname);
|
|
53468
53556
|
if (params) {
|
|
53469
53557
|
const mod = await loadFunction(route.function);
|
|
53470
|
-
if (mod) {
|
|
53471
|
-
|
|
53472
|
-
|
|
53473
|
-
|
|
53474
|
-
await deliverResponse(res, response);
|
|
53475
|
-
return;
|
|
53476
|
-
} catch (e) {
|
|
53477
|
-
const status = errorStatus(e, 500);
|
|
53478
|
-
res.writeHead(status, { "Content-Type": "application/json" });
|
|
53479
|
-
res.end(JSON.stringify({ error: status === 500 ? "Internal Server Error" : e instanceof Error ? e.message : String(e) }));
|
|
53558
|
+
if (!mod) {
|
|
53559
|
+
if (functionFailure(route.function)) {
|
|
53560
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
53561
|
+
res.end(JSON.stringify({ error: "Internal Server Error" }));
|
|
53480
53562
|
return;
|
|
53481
53563
|
}
|
|
53564
|
+
continue;
|
|
53565
|
+
}
|
|
53566
|
+
try {
|
|
53567
|
+
const webRequest = makeWebRequest(req, url.href, maxBodyBytes);
|
|
53568
|
+
const response = await withSecurityScope(() => mod.handle(webRequest));
|
|
53569
|
+
await deliverResponse(res, response);
|
|
53570
|
+
return;
|
|
53571
|
+
} catch (e) {
|
|
53572
|
+
const status = errorStatus(e, 500);
|
|
53573
|
+
res.writeHead(status, { "Content-Type": "application/json" });
|
|
53574
|
+
res.end(JSON.stringify({ error: status === 500 ? "Internal Server Error" : e instanceof Error ? e.message : String(e) }));
|
|
53575
|
+
return;
|
|
53482
53576
|
}
|
|
53483
53577
|
}
|
|
53484
53578
|
}
|
|
@@ -65138,6 +65232,10 @@ var PACKAGES = {
|
|
|
65138
65232
|
// servers on fresh checkouts (CI).
|
|
65139
65233
|
"plugin-pwa": { name: "@vesk/plugin-pwa", entry: "index" },
|
|
65140
65234
|
"plugin-tailwind": { name: "@vesk/plugin-tailwind", entry: "index" },
|
|
65235
|
+
// The multipart plugin ships as a real published package: an app route imports
|
|
65236
|
+
// it by name, so its dist must exist for the API-function bundler to resolve it
|
|
65237
|
+
// on a fresh checkout (CI).
|
|
65238
|
+
"plugin-multipart": { name: "@vesk/plugin-multipart", entry: "index" },
|
|
65141
65239
|
// testing last — it depends on the compiler.
|
|
65142
65240
|
testing: { name: "@vesk/testing", entry: "index" }
|
|
65143
65241
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/vesk-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.72",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk — compiler-first framework for the post-VDOM web. vesk dev, vesk build.",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/cli.js",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@vesk/adapter": "^0.2.
|
|
12
|
-
"@vesk/compiler": "^0.2.
|
|
13
|
-
"@vesk/plugin-tailwind": "^0.2.
|
|
14
|
-
"@vesk/runtime": "^0.2.
|
|
11
|
+
"@vesk/adapter": "^0.2.72",
|
|
12
|
+
"@vesk/compiler": "^0.2.72",
|
|
13
|
+
"@vesk/plugin-tailwind": "^0.2.72",
|
|
14
|
+
"@vesk/runtime": "^0.2.72",
|
|
15
15
|
"esrap": "^2.3.0",
|
|
16
16
|
"typescript": "^5.8.0",
|
|
17
17
|
"ws": "^8.18.0",
|