@marko/run 0.2.7 → 0.2.8

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.
@@ -48,6 +48,227 @@ var import_url2 = require("url");
48
48
 
49
49
  // src/adapter/dev-server.ts
50
50
  var import_vite = require("vite");
51
+
52
+ // src/adapter/polyfill.ts
53
+ var webStream = __toESM(require("stream/web"), 1);
54
+ var import_crypto = require("crypto");
55
+ var undici = __toESM(require("undici"), 1);
56
+ globalThis.crypto ?? (globalThis.crypto = import_crypto.webcrypto);
57
+ globalThis.fetch ?? (globalThis.fetch = undici.fetch);
58
+ globalThis.Response ?? (globalThis.Response = undici.Response);
59
+ globalThis.Request ?? (globalThis.Request = undici.Request);
60
+ globalThis.Headers ?? (globalThis.Headers = undici.Headers);
61
+ globalThis.ReadableStream ?? (globalThis.ReadableStream = webStream.ReadableStream);
62
+ globalThis.TransformStream ?? (globalThis.TransformStream = webStream.TransformStream);
63
+ globalThis.WritableStream ?? (globalThis.WritableStream = webStream.WritableStream);
64
+ globalThis.FormData ?? (globalThis.FormData = undici.FormData);
65
+ globalThis.File ?? (globalThis.File = undici.File);
66
+
67
+ // src/adapter/middleware.ts
68
+ function getForwardedHeader(req, name) {
69
+ const value = req.headers["x-forwarded-" + name];
70
+ if (value) {
71
+ if (typeof value === "string") {
72
+ const index = value.indexOf(",");
73
+ return index < 0 ? value : value.slice(0, index);
74
+ }
75
+ return value[0];
76
+ }
77
+ }
78
+ function getOrigin(req, trustProxy) {
79
+ const protocol = req.protocol || trustProxy && getForwardedHeader(req, "proto") || (req.socket.encrypted ? "https" : "http");
80
+ let host = req.headers.host || trustProxy && getForwardedHeader(req, "host");
81
+ if (!host) {
82
+ if (process.env.NODE_ENV !== "production") {
83
+ host = "localhost";
84
+ console.warn(
85
+ `Could not automatically determine the origin host, using 'localhost'. Use the 'origin' option or the 'ORIGIN' environment variable to set the origin explicitly.`
86
+ );
87
+ } else {
88
+ throw new Error(
89
+ `Could not automatically determine the origin host. Use the 'origin' option or the 'ORIGIN' environment variable to set the origin explicitly.`
90
+ );
91
+ }
92
+ }
93
+ return `${protocol}://${host}`;
94
+ }
95
+ var inExpiresDateRgs = /Expires\s*=\s*(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*$/i;
96
+ function setResponseHeaders(response, res) {
97
+ for (const [key, value] of response.headers) {
98
+ if (key !== "set-cookie") {
99
+ res.setHeader(key, value);
100
+ }
101
+ }
102
+ const setCookies = getSetCookie(response.headers);
103
+ if (setCookies == null ? void 0 : setCookies.length) {
104
+ res.setHeader("set-cookie", setCookies);
105
+ }
106
+ }
107
+ var getSetCookie = Headers.prototype.getSetCookie ? getSetCookie_platform : getSetCookie_fallback;
108
+ function getSetCookie_platform(headers) {
109
+ return headers.getSetCookie();
110
+ }
111
+ function getSetCookie_fallback(headers) {
112
+ const value = headers.get("set-cookie");
113
+ if (!value)
114
+ return void 0;
115
+ let sepIndex = value.indexOf(",") + 1;
116
+ if (!sepIndex)
117
+ return value;
118
+ let index = 0;
119
+ let setCookie = void 0;
120
+ let setCookies = void 0;
121
+ do {
122
+ const valuePart = value.slice(index, sepIndex - 1);
123
+ if (!inExpiresDateRgs.test(valuePart)) {
124
+ if (setCookies) {
125
+ setCookies.push(valuePart);
126
+ } else if (setCookie) {
127
+ setCookies = [setCookie, valuePart];
128
+ } else {
129
+ setCookie = valuePart;
130
+ }
131
+ index = sepIndex;
132
+ while (value.charCodeAt(index) === 32)
133
+ index++;
134
+ }
135
+ sepIndex = value.indexOf(",", sepIndex) + 1;
136
+ } while (sepIndex);
137
+ if (index) {
138
+ const valuePart = value.slice(index);
139
+ if (setCookies) {
140
+ setCookies.push(valuePart);
141
+ return setCookies;
142
+ }
143
+ return [setCookie, valuePart];
144
+ }
145
+ return value;
146
+ }
147
+ function createMiddleware(fetch2, options = {}) {
148
+ const {
149
+ origin = process.env.ORIGIN,
150
+ trustProxy = process.env.TRUST_PROXY === "1"
151
+ } = options;
152
+ return async (req, res, next) => {
153
+ var _a;
154
+ const controller = new AbortController();
155
+ const { signal } = controller;
156
+ const url = new URL(req.url, origin || getOrigin(req, trustProxy));
157
+ const ip = req.ip || trustProxy && getForwardedHeader(req, "for") || req.socket.remoteAddress || "";
158
+ req.on("error", onErrorOrClose);
159
+ req.socket.on("error", onErrorOrClose);
160
+ res.on("error", onErrorOrClose);
161
+ res.on("close", onErrorOrClose);
162
+ signal.addEventListener("abort", onSignalAborted);
163
+ function onErrorOrClose(err) {
164
+ req.off("error", onErrorOrClose);
165
+ req.socket.off("error", onErrorOrClose);
166
+ res.off("error", onErrorOrClose);
167
+ res.off("close", onErrorOrClose);
168
+ if (err) {
169
+ signal.removeEventListener("abort", onSignalAborted);
170
+ controller.abort(err);
171
+ }
172
+ }
173
+ function onSignalAborted() {
174
+ if (next) {
175
+ next(signal.reason);
176
+ } else {
177
+ if (!res.destroyed && res.socket) {
178
+ res.socket.destroySoon();
179
+ }
180
+ console.error(signal.reason);
181
+ }
182
+ }
183
+ let setDevClientId;
184
+ if (process.env.NODE_ENV !== "production" && globalThis.__marko_run_dev__ && ((_a = req.headers.accept) == null ? void 0 : _a.includes("text/html"))) {
185
+ setDevClientId = globalThis.__marko_run_dev__.onClient((ws) => {
186
+ if (signal.aborted) {
187
+ sendError();
188
+ } else {
189
+ signal.addEventListener("abort", sendError);
190
+ }
191
+ function sendError() {
192
+ const { message, stack = "" } = signal.reason;
193
+ ws.send(
194
+ JSON.stringify({
195
+ type: "error",
196
+ err: { message, stack }
197
+ })
198
+ );
199
+ }
200
+ });
201
+ }
202
+ let body;
203
+ if (req.method !== "GET" && req.method !== "HEAD") {
204
+ if (req.readableDidRead) {
205
+ body = bodyConsumedErrorStream;
206
+ } else {
207
+ body = req;
208
+ }
209
+ }
210
+ const request = new Request(url, {
211
+ method: req.method,
212
+ headers: req.headers,
213
+ body,
214
+ // @ts-expect-error: Node requires this for streams
215
+ duplex: "half",
216
+ signal
217
+ });
218
+ const response = await fetch2(request, {
219
+ ip,
220
+ request: req,
221
+ response: res
222
+ });
223
+ if (!response) {
224
+ if (next) {
225
+ next();
226
+ }
227
+ return;
228
+ }
229
+ if (process.env.NODE_ENV !== "production" && setDevClientId) {
230
+ setDevClientId(response);
231
+ }
232
+ res.statusCode = response.status;
233
+ setResponseHeaders(response, res);
234
+ if (!response.body) {
235
+ if (!response.headers.has("content-length")) {
236
+ res.setHeader("content-length", "0");
237
+ }
238
+ res.end();
239
+ return;
240
+ } else if (res.destroyed) {
241
+ controller.abort(new Error("Response stream destroyed"));
242
+ return;
243
+ }
244
+ writeResponse(response.body.getReader(), res, controller);
245
+ };
246
+ }
247
+ async function writeResponse(reader, res, controller) {
248
+ try {
249
+ while (!controller.signal.aborted) {
250
+ const { done, value } = await reader.read();
251
+ if (done) {
252
+ res.end();
253
+ return;
254
+ } else if (!res.write(value)) {
255
+ res.once("drain", () => writeResponse(reader, res, controller));
256
+ return;
257
+ } else if (res.flush) {
258
+ res.flush();
259
+ }
260
+ }
261
+ } catch (err) {
262
+ controller.abort(err);
263
+ }
264
+ }
265
+ var bodyConsumedErrorStream = new ReadableStream({
266
+ start(controller) {
267
+ controller.error(new Error("The request body stream was already consumed by something before Marko Run."));
268
+ }
269
+ });
270
+
271
+ // src/adapter/dev-server.ts
51
272
  var import_strip_ansi = __toESM(require("strip-ansi"), 1);
52
273
  function createViteDevMiddleware(devServer, load, factory) {
53
274
  let value;
@@ -82,22 +303,25 @@ async function createViteDevServer(config2) {
82
303
  }
83
304
  async function createDevServer(config2) {
84
305
  const devServer = await createViteDevServer(config2);
85
- const { createMiddleware } = await devServer.ssrLoadModule(
86
- "@marko/run/adapter/middleware"
87
- );
88
- let fetch;
89
- const nodeMiddleware = createMiddleware(
90
- (request, platform) => fetch(request, platform)
306
+ const routerMiddleware = createMiddleware(
307
+ (request, platform) => globalThis.__marko_run__.fetch(request, platform)
91
308
  );
92
- const middleware = createViteDevMiddleware(
93
- devServer,
94
- async () => await devServer.ssrLoadModule("@marko/run/router"),
95
- (module2) => {
96
- fetch = module2.fetch;
97
- return nodeMiddleware;
98
- }
99
- );
100
- devServer.middlewares.use(middleware);
309
+ devServer.middlewares.use(async (req, res, next) => {
310
+ await devServer.ssrLoadModule("@marko/run/router");
311
+ routerMiddleware(req, res, (err) => {
312
+ if (err) {
313
+ res.statusCode = 500;
314
+ if (err instanceof Error) {
315
+ devServer.ssrFixStacktrace(err);
316
+ res.end(err.stack && (0, import_strip_ansi.default)(err.stack));
317
+ } else {
318
+ res.end();
319
+ }
320
+ } else {
321
+ next == null ? void 0 : next();
322
+ }
323
+ });
324
+ });
101
325
  return devServer;
102
326
  }
103
327
  var ClientIdCookieName = "marko-run-client-id";
@@ -168,6 +392,147 @@ function getDevGlobal() {
168
392
  return devGlobal;
169
393
  }
170
394
 
395
+ // src/adapter/utils.ts
396
+ var import_supports_color = __toESM(require("supports-color"), 1);
397
+ var import_kleur = __toESM(require("kleur"), 1);
398
+ function logInfoBox(address) {
399
+ const color = !!import_supports_color.default.stdout;
400
+ let message = import_kleur.default.bold("Marko Run");
401
+ if (true) {
402
+ message += ` v${"0.2.8"}`;
403
+ }
404
+ message += "\n\n";
405
+ message += import_kleur.default.dim("Server listening at");
406
+ message += "\n";
407
+ message += import_kleur.default.cyan(import_kleur.default.underline(address));
408
+ const lines = drawMarkoBox(message, { color, fill: color });
409
+ console.log(lines.join("\n"));
410
+ }
411
+ function drawMarkoBox(message, options) {
412
+ const textPaddingWidth = 3;
413
+ const logoPaddingWidth = 2;
414
+ const textPadding = " ".repeat(textPaddingWidth);
415
+ const logoPadding = " ".repeat(logoPaddingWidth);
416
+ const logo = drawMarkoLogo(options);
417
+ const textLines = message.split(/\n/);
418
+ const textWidths = textLines.map(
419
+ (line) => line.replace(/\x1b\[\d+m/g, "").length
420
+ );
421
+ const textWidth = Math.max(...textWidths);
422
+ const height = Math.max(textLines.length + 2, logo.lines.length);
423
+ const width = textPaddingWidth * 2 + logoPaddingWidth + textWidth + logo.width;
424
+ const hBorder = "\u2500".repeat(width);
425
+ const vBorder = "\u2502";
426
+ const lineDiff = logo.lines.length - textLines.length;
427
+ const textStartLine = lineDiff > 0 ? Math.floor(lineDiff / 2) : 1;
428
+ const textEndLine = height - (lineDiff > 0 ? Math.ceil(lineDiff / 2) : 1);
429
+ const logoEndLine = logo.lines.length;
430
+ const logoFill = " ".repeat(logo.width);
431
+ const textFill = " ".repeat(textWidth);
432
+ const lines = [`\u256D${hBorder}\u256E`];
433
+ for (let i = 0; i < height; i++) {
434
+ let line = vBorder;
435
+ line += logoPadding;
436
+ if (i < logoEndLine) {
437
+ line += logo.lines[i];
438
+ } else {
439
+ line += logoFill;
440
+ }
441
+ line += textPadding;
442
+ if (i >= textStartLine && i < textEndLine) {
443
+ let index = i - textStartLine;
444
+ line += textLines[index];
445
+ line += " ".repeat(textWidth - textWidths[index]);
446
+ } else {
447
+ line += textFill;
448
+ }
449
+ line += textPadding;
450
+ line += vBorder;
451
+ lines.push(line);
452
+ }
453
+ lines.push(`\u2570${hBorder}\u256F`);
454
+ return lines;
455
+ }
456
+ function drawMarkoLogo(options = {}) {
457
+ const { fill = true, color = true } = options;
458
+ const source = `
459
+ TT____ YY____ R____
460
+ C\u2571T\u2572 \u2572G\u2571Y\u2572 \u2572 R\u2572 \u2572
461
+ C\u2571 T\u2572 G\u2571 Y\u2572 \u2572 R\u2572 \u2572
462
+ C\u2571 \u2571T\u2572G\u2571 \u2571Y\u2572 \u2572 R\u2572 \u2572
463
+ B\u2572 \u2572 GG\u203E\u203E\u203E\u203E O\u2571 \u2571 P\u2571 \u2571
464
+ B\u2572 \u2572 OOO\u2571 \u2571 P\u2571 \u2571
465
+ B\u2572 \u2572 OOO\u2571 \u2571 P\u2571 \u2571
466
+ B\u203E\u203E\u203E\u203E OOO\u203E\u203E\u203E\u203E P\u203E\u203E\u203E\u203E
467
+ `;
468
+ const resetEscape = "\x1B[0m";
469
+ const colorEscapeCodes = Object.entries({
470
+ B: "#06cfe5",
471
+ C: "#05a5f0",
472
+ T: "#19d89c",
473
+ G: "#81dc09",
474
+ Y: "#ffd900",
475
+ O: "#ff9500",
476
+ R: "#f3154d",
477
+ P: "#ce176c"
478
+ }).reduce((acc, [key, hex]) => {
479
+ const r = parseInt(hex.slice(1, 3), 16);
480
+ const g = parseInt(hex.slice(3, 5), 16);
481
+ const b = parseInt(hex.slice(5, 7), 16);
482
+ acc[key] = `\x1B[38;2;${r};${g};${b}m`;
483
+ return acc;
484
+ }, {});
485
+ const lines = [];
486
+ const lineWidths = [];
487
+ let line = "";
488
+ let lineWidth = 0;
489
+ let width = 0;
490
+ for (let i = 0; i < source.length; i++) {
491
+ let char = source[i];
492
+ if (char === "\n") {
493
+ if (line) {
494
+ if (color) {
495
+ line += resetEscape;
496
+ }
497
+ width = Math.max(lineWidth, width);
498
+ lines.push(line);
499
+ lineWidths.push(lineWidth);
500
+ line = "";
501
+ lineWidth = 0;
502
+ }
503
+ } else if (/[A-Z]/.test(char)) {
504
+ while (source[i + 1] === char)
505
+ i++;
506
+ if (color) {
507
+ line += colorEscapeCodes[char];
508
+ }
509
+ if (fill) {
510
+ let fillChar = "";
511
+ for (; i < source.length; i++) {
512
+ char = source[i + 1];
513
+ if (fillChar && char !== " ") {
514
+ break;
515
+ } else if (!fillChar) {
516
+ fillChar = char;
517
+ }
518
+ line += fillChar;
519
+ lineWidth++;
520
+ }
521
+ }
522
+ } else {
523
+ line += char;
524
+ lineWidth++;
525
+ }
526
+ }
527
+ for (let i = 0; i < lines.length; i++) {
528
+ const padding = width - lineWidths[i];
529
+ if (padding > 0) {
530
+ lines[i] += " ".repeat(width - lineWidths[i]);
531
+ }
532
+ }
533
+ return { lines, width };
534
+ }
535
+
171
536
  // src/vite/utils/server.ts
172
537
  var import_net = __toESM(require("net"), 1);
173
538
  var import_child_process = __toESM(require("child_process"), 1);
@@ -323,6 +688,7 @@ function adapter() {
323
688
  },
324
689
  async startDev(entry, config2, options) {
325
690
  const { port = 3e3, envFile } = options;
691
+ globalThis.__marko_run_vite_config__ = config2;
326
692
  if (entry) {
327
693
  const { nodeArgs } = (0, import_parse_node_args.default)(options.args);
328
694
  let worker;
@@ -366,7 +732,7 @@ function adapter() {
366
732
  return new Promise((resolve) => {
367
733
  const listener = devServer.middlewares.listen(port, () => {
368
734
  const address = listener.address();
369
- console.log(`Dev server started: http://localhost:${address.port}`);
735
+ logInfoBox(`http://localhost:${address.port}`);
370
736
  resolve({
371
737
  port,
372
738
  async close() {
@@ -381,7 +747,9 @@ function adapter() {
381
747
  const { nodeArgs } = (0, import_parse_node_args.default)(options.args);
382
748
  const args = [...nodeArgs, entry];
383
749
  const server = await spawnServer("node", args, port, envFile);
384
- console.log(`Preview server started: http://localhost:${server.port}`);
750
+ if (!options.sourceEntry) {
751
+ logInfoBox(`http://localhost:${port}`);
752
+ }
385
753
  return server;
386
754
  }
387
755
  };
@@ -1,7 +1,7 @@
1
1
  import type { Adapter } from "../vite";
2
2
  import { type MarkoRunDev } from "./dev-server";
3
3
  import { type SpawnedServer } from "../vite/utils/server";
4
- export { getDevGlobal, createDevServer, createViteDevServer, createViteDevMiddleware, type MarkoRunDev } from "./dev-server";
4
+ export { getDevGlobal, createDevServer, createViteDevServer, createViteDevMiddleware, type MarkoRunDev, } from "./dev-server";
5
5
  export type { Adapter, SpawnedServer };
6
6
  export type { NodePlatformInfo } from "./middleware";
7
7
  export type MarkoRunDevAccessor = () => MarkoRunDev;