@moonsjs/vite 0.3.0 → 0.5.0

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.
@@ -92,10 +92,93 @@ function createFileShell2(options = {}) {
92
92
  };
93
93
  }
94
94
 
95
- // src/server/node.ts
96
- import { Readable } from "node:stream";
97
- import { pipeline } from "node:stream/promises";
98
- import { CLIENT_IP_HEADER } from "@moonsjs/core";
95
+ // src/server/transport.ts
96
+ import { existsSync as existsSync2, readFileSync as readFileSync2, statSync } from "node:fs";
97
+ import { join as join2, resolve as resolve2, sep } from "node:path";
98
+ import { gzipSync } from "node:zlib";
99
+ import { MoonsError as MoonsError2 } from "@moonsjs/core";
100
+
101
+ // src/server/isr.ts
102
+ import { renameSync, writeFileSync } from "node:fs";
103
+
104
+ // src/payload-scan.ts
105
+ var SECRET_KEY_PATTERN = /(SECRET|TOKEN|PASSWORD|PASSWD|PRIVATE|CREDENTIAL|AUTH|API_KEY|ACCESS_KEY|SIGNING)/i;
106
+ var MIN_SECRET_LENGTH = 12;
107
+ function scanPayloadForSecrets(payload, options = {}) {
108
+ const findings = [];
109
+ const canary = options.canary;
110
+ if (canary !== undefined && canary.length > 0 && payload.includes(canary)) {
111
+ findings.push({ kind: "canary", label: "canary" });
112
+ }
113
+ for (const [key, value] of Object.entries(options.env ?? {})) {
114
+ if (typeof value !== "string" || value.length < MIN_SECRET_LENGTH) {
115
+ continue;
116
+ }
117
+ if (!SECRET_KEY_PATTERN.test(key) || /PUBLIC/i.test(key)) {
118
+ continue;
119
+ }
120
+ if (payload.includes(value)) {
121
+ findings.push({ kind: "env", label: key });
122
+ }
123
+ }
124
+ return findings;
125
+ }
126
+
127
+ // src/server/isr.ts
128
+ function shouldRevalidate(input) {
129
+ const now = input.now ?? Date.now();
130
+ return now - input.mtimeMs >= input.revalidateSeconds * 1000;
131
+ }
132
+ var inflight = new Map;
133
+ function revalidatePrerendered(options) {
134
+ const existing = inflight.get(options.pathname);
135
+ if (existing !== undefined) {
136
+ return existing;
137
+ }
138
+ const task = runRevalidate(options).finally(() => {
139
+ inflight.delete(options.pathname);
140
+ });
141
+ inflight.set(options.pathname, task);
142
+ return task;
143
+ }
144
+ async function runRevalidate(options) {
145
+ const log = options.log ?? ((message) => console.log(message));
146
+ try {
147
+ const response = await options.handler(new Request(`http://localhost${options.pathname}`, {
148
+ method: "GET",
149
+ headers: { "x-moons-prerender": "1" }
150
+ }));
151
+ if (response.status !== 200) {
152
+ log(`[moons] isr: skipped ${options.pathname} (status ${response.status})`);
153
+ return;
154
+ }
155
+ const html = await response.text();
156
+ const findings = scanPayloadForSecrets(html, {
157
+ ...options.canary === undefined ? {} : { canary: options.canary },
158
+ env: options.env ?? process.env
159
+ });
160
+ if (findings.length > 0) {
161
+ const labels = findings.map((finding) => finding.kind === "canary" ? "canary" : `env(${finding.label})`).join(", ");
162
+ log(`[moons] isr: NOT writing ${options.pathname} — contains ${labels}`);
163
+ return;
164
+ }
165
+ if (options.storage !== undefined) {
166
+ await options.storage.write(options.pathname, new TextEncoder().encode(html));
167
+ return;
168
+ }
169
+ if (options.file === undefined) {
170
+ log(`[moons] isr: skipped ${options.pathname} — no destination file/storage`);
171
+ return;
172
+ }
173
+ const tmp = `${options.file}.tmp-${process.pid}`;
174
+ writeFileSync(tmp, html);
175
+ renameSync(tmp, options.file);
176
+ } catch (error) {
177
+ log(`[moons] isr: failed to regenerate ${options.pathname}: ${String(error)}`);
178
+ }
179
+ }
180
+
181
+ // src/server/transport.ts
99
182
  var MAX_TRANSPORT_BODY_BYTES = 32 * 1024 * 1024;
100
183
 
101
184
  class InvalidRequestError extends Error {
@@ -113,6 +196,346 @@ class BodyLimitError extends Error {
113
196
  this.limit = limit;
114
197
  }
115
198
  }
199
+ var DEFAULT_SECURITY_HEADERS = {
200
+ "x-content-type-options": "nosniff",
201
+ "referrer-policy": "strict-origin-when-cross-origin"
202
+ };
203
+ function firstHeaderValue(value) {
204
+ if (value === undefined) {
205
+ return null;
206
+ }
207
+ const raw = Array.isArray(value) ? value[0] : value;
208
+ if (raw === undefined) {
209
+ return null;
210
+ }
211
+ const first = raw.split(",")[0]?.trim() ?? "";
212
+ return first.length === 0 ? null : first;
213
+ }
214
+ function forwardedProtocol(value) {
215
+ const first = firstHeaderValue(value)?.toLowerCase() ?? null;
216
+ if (first === "https") {
217
+ return "https";
218
+ }
219
+ if (first === "http") {
220
+ return "http";
221
+ }
222
+ return null;
223
+ }
224
+ function forwardedHost(value) {
225
+ const first = firstHeaderValue(value);
226
+ if (first === null || first.length === 0 || first.length > 255) {
227
+ return null;
228
+ }
229
+ if (!/^[A-Za-z0-9.\-[\]:]+$/.test(first)) {
230
+ return null;
231
+ }
232
+ return first;
233
+ }
234
+ function isPlausibleIp(value) {
235
+ return value.length <= 64 && /^[0-9a-fA-F:.]+$/.test(value);
236
+ }
237
+ function stripZoneId(value) {
238
+ const index = value.indexOf("%");
239
+ return index === -1 ? value : value.slice(0, index);
240
+ }
241
+ function normalizeIp(value) {
242
+ const withoutZone = stripZoneId(value);
243
+ return withoutZone.startsWith("::ffff:") ? withoutZone.slice(7) : withoutZone;
244
+ }
245
+ function resolveClientIpValues(forwardedFor, remoteAddress, trustProxy) {
246
+ if (trustProxy) {
247
+ const forwarded = firstHeaderValue(forwardedFor);
248
+ if (forwarded !== null && isPlausibleIp(forwarded)) {
249
+ return normalizeIp(forwarded);
250
+ }
251
+ }
252
+ return remoteAddress === null ? null : normalizeIp(remoteAddress);
253
+ }
254
+ var MIME_TYPES = {
255
+ ".js": "text/javascript; charset=utf-8",
256
+ ".mjs": "text/javascript; charset=utf-8",
257
+ ".css": "text/css; charset=utf-8",
258
+ ".html": "text/html; charset=utf-8",
259
+ ".json": "application/json; charset=utf-8",
260
+ ".map": "application/json; charset=utf-8",
261
+ ".ico": "image/x-icon",
262
+ ".png": "image/png",
263
+ ".jpg": "image/jpeg",
264
+ ".jpeg": "image/jpeg",
265
+ ".gif": "image/gif",
266
+ ".svg": "image/svg+xml",
267
+ ".webp": "image/webp",
268
+ ".avif": "image/avif",
269
+ ".woff": "font/woff",
270
+ ".woff2": "font/woff2",
271
+ ".ttf": "font/ttf",
272
+ ".txt": "text/plain; charset=utf-8",
273
+ ".wasm": "application/wasm",
274
+ ".xml": "application/xml; charset=utf-8",
275
+ ".csv": "text/csv; charset=utf-8",
276
+ ".md": "text/markdown; charset=utf-8",
277
+ ".pdf": "application/pdf",
278
+ ".mp4": "video/mp4",
279
+ ".webm": "video/webm",
280
+ ".mp3": "audio/mpeg",
281
+ ".wav": "audio/wav",
282
+ ".zip": "application/zip",
283
+ ".gz": "application/gzip"
284
+ };
285
+ var COMPRESSIBLE_FILE = /\.(js|mjs|css|html|json|svg|txt|map|xml)$/i;
286
+ var GZIP_MIN_BYTES = 1024;
287
+ var GZIP_CACHE_MAX = 64;
288
+ var gzipCache = new Map;
289
+ function gzipCached(file, mtimeMs, body) {
290
+ const cached = gzipCache.get(file);
291
+ if (cached !== undefined && cached.mtimeMs === mtimeMs) {
292
+ return cached.gzip;
293
+ }
294
+ const gzip = gzipSync(body);
295
+ if (gzipCache.size >= GZIP_CACHE_MAX) {
296
+ const oldest = gzipCache.keys().next().value;
297
+ if (oldest !== undefined) {
298
+ gzipCache.delete(oldest);
299
+ }
300
+ }
301
+ gzipCache.set(file, { mtimeMs, gzip });
302
+ return gzip;
303
+ }
304
+ function acceptsGzipHeader(value) {
305
+ if (value === null) {
306
+ return false;
307
+ }
308
+ return value.toLowerCase().split(",").map((part) => part.trim()).some((part) => part === "gzip" || part === "*" || part.startsWith("gzip;"));
309
+ }
310
+ function rpcBodyTooLargeText(limit, size) {
311
+ const megabytes = (bytes) => (bytes / 1e6).toFixed(1);
312
+ return new MoonsError2({
313
+ code: "E_RPC_BODY_TOO_LARGE",
314
+ message: size === null ? `body exceeds the ${megabytes(limit)} MB limit` : `body ${megabytes(size)} MB exceeds the ${megabytes(limit)} MB limit`,
315
+ details: "Body exceeds `security.bodyLimitBytes`; reading stops at the transport before the body is fully buffered.",
316
+ suggestions: [
317
+ "Reduce the payload size, or",
318
+ "Increase security.bodyLimitBytes if you really need to"
319
+ ]
320
+ }).format();
321
+ }
322
+
323
+ class RequestTimeoutError extends Error {
324
+ limit;
325
+ constructor(limit) {
326
+ super(`handler did not respond within ${limit} ms`);
327
+ this.name = "RequestTimeoutError";
328
+ this.limit = limit;
329
+ }
330
+ }
331
+ function requestTimeoutText(limit) {
332
+ return new MoonsError2({
333
+ code: "E_REQUEST_TIMEOUT",
334
+ message: `handler did not respond within ${limit} ms`,
335
+ details: "The transport stopped waiting for the handler and answered 504. " + "The handler keeps running until it settles; JavaScript cannot cancel it.",
336
+ suggestions: [
337
+ "Make the handler faster, or move slow work out of the request path",
338
+ "Raise `requestTimeoutMs`, or set it to 0 to disable the timeout"
339
+ ]
340
+ }).format();
341
+ }
342
+ async function runHandlerWithTimeout(handler, request, timeoutMs) {
343
+ if (timeoutMs === undefined || timeoutMs <= 0) {
344
+ return handler(request);
345
+ }
346
+ let timer;
347
+ const timeout = new Promise((_resolve, reject) => {
348
+ timer = setTimeout(() => reject(new RequestTimeoutError(timeoutMs)), timeoutMs);
349
+ });
350
+ try {
351
+ return await Promise.race([handler(request), timeout]);
352
+ } finally {
353
+ if (timer !== undefined) {
354
+ clearTimeout(timer);
355
+ }
356
+ }
357
+ }
358
+ function isAbortLike(error) {
359
+ if (error instanceof DOMException) {
360
+ return error.name === "AbortError" || error.name === "TimeoutError";
361
+ }
362
+ if (error instanceof Error) {
363
+ if (error.name === "AbortError") {
364
+ return true;
365
+ }
366
+ const code = error.code;
367
+ if (code === "ECONNRESET" || code === "EPIPE" || code === "ERR_STREAM_PREMATURE_CLOSE") {
368
+ return true;
369
+ }
370
+ const message = error.message.toLowerCase();
371
+ return message === "aborted" || message.includes("aborted") || message.includes("premature close");
372
+ }
373
+ return false;
374
+ }
375
+ function textResponseWithHeaders(status, text, configured) {
376
+ const headers = new Headers({ "content-type": "text/plain; charset=utf-8" });
377
+ applyStaticHeaders(headers, "/", configured);
378
+ return new Response(text, { status, headers });
379
+ }
380
+ function applyStaticHeaders(target, pathname, configured) {
381
+ for (const [name, value] of Object.entries(configured ?? {})) {
382
+ if (!target.has(name)) {
383
+ target.set(name, value);
384
+ }
385
+ }
386
+ for (const [name, value] of Object.entries(DEFAULT_SECURITY_HEADERS)) {
387
+ if (!target.has(name)) {
388
+ target.set(name, value);
389
+ }
390
+ }
391
+ if (pathname.startsWith("/assets/") && !target.has("cache-control")) {
392
+ target.set("cache-control", "public, max-age=31536000, immutable");
393
+ }
394
+ }
395
+ async function readBodyWithLimit(stream, maxBytes) {
396
+ if (stream === null) {
397
+ return new Uint8Array(0);
398
+ }
399
+ const reader = stream.getReader();
400
+ const chunks = [];
401
+ let size = 0;
402
+ try {
403
+ for (;; ) {
404
+ const { done, value } = await reader.read();
405
+ if (done) {
406
+ break;
407
+ }
408
+ if (value !== undefined) {
409
+ size += value.byteLength;
410
+ if (size > maxBytes) {
411
+ throw new BodyLimitError(maxBytes);
412
+ }
413
+ chunks.push(value);
414
+ }
415
+ }
416
+ } finally {
417
+ try {
418
+ await reader.cancel();
419
+ } catch {}
420
+ }
421
+ const output = new Uint8Array(size);
422
+ let offset = 0;
423
+ for (const chunk of chunks) {
424
+ output.set(chunk, offset);
425
+ offset += chunk.byteLength;
426
+ }
427
+ return output;
428
+ }
429
+ function resolveStaticFile2(clientDir, pathname) {
430
+ const target = staticFileTarget(clientDir, pathname);
431
+ return target !== null && isFile(target) ? target : null;
432
+ }
433
+ function staticFileTarget(clientDir, pathname) {
434
+ let decoded;
435
+ try {
436
+ decoded = decodeURIComponent(pathname);
437
+ } catch {
438
+ return null;
439
+ }
440
+ const exact = safeWithin(clientDir, `.${decoded}`);
441
+ if (exact !== null && isFile(exact)) {
442
+ return exact;
443
+ }
444
+ const normalized = decoded.length > 1 ? decoded.replace(/\/+$/, "") : decoded;
445
+ const manifest = readPrerenderManifest(clientDir);
446
+ if (manifest.paths.has(normalized)) {
447
+ const target = normalized === "/" ? "index.html" : `${normalized.slice(1)}/index.html`;
448
+ return safeWithin(clientDir, `./${target}`);
449
+ }
450
+ return null;
451
+ }
452
+ function safeWithin(clientDir, relative) {
453
+ const candidate = resolve2(clientDir, relative);
454
+ if (candidate !== clientDir && !candidate.startsWith(clientDir + sep)) {
455
+ return null;
456
+ }
457
+ return candidate;
458
+ }
459
+ function isFile(path) {
460
+ return existsSync2(path) && statSync(path).isFile();
461
+ }
462
+ var prerenderManifestCache = null;
463
+ function readPrerenderManifest(clientDir) {
464
+ const file = join2(clientDir, "_moons_prerender.json");
465
+ const empty = { paths: new Set, revalidate: new Map };
466
+ try {
467
+ const mtimeMs = statSync(file).mtimeMs;
468
+ if (prerenderManifestCache !== null && prerenderManifestCache.file === file && prerenderManifestCache.mtimeMs === mtimeMs) {
469
+ return prerenderManifestCache.info;
470
+ }
471
+ const json = JSON.parse(readFileSync2(file, "utf8"));
472
+ const paths = new Set;
473
+ const revalidate = new Map;
474
+ if (Array.isArray(json.paths)) {
475
+ for (const path of json.paths) {
476
+ if (typeof path === "string") {
477
+ paths.add(path);
478
+ }
479
+ }
480
+ }
481
+ if (Array.isArray(json.entries)) {
482
+ for (const entry of json.entries) {
483
+ if (entry === null || typeof entry !== "object" || typeof entry["path"] !== "string") {
484
+ continue;
485
+ }
486
+ const path = entry["path"];
487
+ paths.add(path);
488
+ const seconds = entry["revalidate"];
489
+ if (typeof seconds === "number" && Number.isFinite(seconds) && seconds >= 0) {
490
+ revalidate.set(path, seconds);
491
+ }
492
+ }
493
+ }
494
+ const info = { paths, revalidate };
495
+ prerenderManifestCache = { file, mtimeMs, info };
496
+ return info;
497
+ } catch {
498
+ return empty;
499
+ }
500
+ }
501
+ function scheduleRevalidation(input) {
502
+ const normalized = input.pathname.length > 1 ? input.pathname.replace(/\/+$/, "") : input.pathname;
503
+ const seconds = readPrerenderManifest(input.clientDir).revalidate.get(normalized);
504
+ if (seconds === undefined || seconds < 0) {
505
+ return;
506
+ }
507
+ if (!shouldRevalidate({ mtimeMs: input.mtimeMs, revalidateSeconds: seconds })) {
508
+ return;
509
+ }
510
+ const regeneratedAt = performance.now();
511
+ const logger = input.logger ?? null;
512
+ revalidatePrerendered({
513
+ pathname: normalized,
514
+ ...input.file === undefined ? {} : { file: input.file },
515
+ ...input.storage === undefined ? {} : { storage: input.storage },
516
+ handler: input.handler,
517
+ ...input.options.canary === undefined ? {} : { canary: input.options.canary },
518
+ env: process.env
519
+ }).then(() => {
520
+ logger?.({
521
+ msg: "isr:regenerated",
522
+ path: normalized,
523
+ durationMs: Math.round(performance.now() - regeneratedAt)
524
+ });
525
+ }).catch((error) => {
526
+ const message = error instanceof Error ? error.message : String(error);
527
+ if (logger !== null) {
528
+ logger({ msg: "isr:revalidate-failed", level: "warn", path: normalized, error: message });
529
+ } else {
530
+ console.error(`[moons] isr regeneration failed (${normalized}): ${message}`);
531
+ }
532
+ });
533
+ }
534
+
535
+ // src/server/node.ts
536
+ import { Readable } from "node:stream";
537
+ import { pipeline } from "node:stream/promises";
538
+ import { CLIENT_IP_HEADER } from "@moonsjs/core";
116
539
  function resolveRequestUrl(req, options = {}) {
117
540
  const hostHeader = req.headers.host ?? "localhost";
118
541
  const trustProxy = options.trustProxy === true;
@@ -126,18 +549,7 @@ function resolveRequestUrl(req, options = {}) {
126
549
  }
127
550
  }
128
551
  function resolveClientIp(req, trustProxy) {
129
- if (trustProxy) {
130
- const forwarded = firstHeaderValue(req.headers["x-forwarded-for"]);
131
- if (forwarded !== null && isPlausibleIp(forwarded)) {
132
- return normalizeIp(forwarded);
133
- }
134
- }
135
- const remote = req.socket?.remoteAddress ?? null;
136
- return remote === null ? null : normalizeIp(remote);
137
- }
138
- function normalizeIp(value) {
139
- const withoutZone = stripZoneId(value);
140
- return withoutZone.startsWith("::ffff:") ? withoutZone.slice(7) : withoutZone;
552
+ return resolveClientIpValues(req.headers["x-forwarded-for"], req.socket?.remoteAddress ?? null, trustProxy);
141
553
  }
142
554
  async function toWebRequest2(req, options = {}) {
143
555
  const url = resolveRequestUrl(req, options);
@@ -199,10 +611,6 @@ function readBody(req, maxBytes) {
199
611
  req.on("error", (error) => fail(error));
200
612
  });
201
613
  }
202
- var DEFAULT_SECURITY_HEADERS = {
203
- "x-content-type-options": "nosniff",
204
- "referrer-policy": "strict-origin-when-cross-origin"
205
- };
206
614
  async function sendNodeResponse2(res, response) {
207
615
  res.statusCode = response.status;
208
616
  response.headers.forEach((value, key) => {
@@ -234,44 +642,6 @@ async function sendNodeResponse2(res, response) {
234
642
  }
235
643
  await pipeline(Readable.fromWeb(response.body), res);
236
644
  }
237
- function firstHeaderValue(value) {
238
- if (value === undefined) {
239
- return null;
240
- }
241
- const raw = Array.isArray(value) ? value[0] : value;
242
- if (raw === undefined) {
243
- return null;
244
- }
245
- const first = raw.split(",")[0]?.trim() ?? "";
246
- return first.length === 0 ? null : first;
247
- }
248
- function forwardedProtocol(value) {
249
- const first = firstHeaderValue(value)?.toLowerCase() ?? null;
250
- if (first === "https") {
251
- return "https";
252
- }
253
- if (first === "http") {
254
- return "http";
255
- }
256
- return null;
257
- }
258
- function forwardedHost(value) {
259
- const first = firstHeaderValue(value);
260
- if (first === null || first.length === 0 || first.length > 255) {
261
- return null;
262
- }
263
- if (!/^[A-Za-z0-9.\-[\]:]+$/.test(first)) {
264
- return null;
265
- }
266
- return first;
267
- }
268
- function isPlausibleIp(value) {
269
- return value.length <= 64 && /^[0-9a-fA-F:.]+$/.test(value);
270
- }
271
- function stripZoneId(value) {
272
- const index = value.indexOf("%");
273
- return index === -1 ? value : value.slice(0, index);
274
- }
275
645
 
276
646
  // src/virtual-modules.ts
277
647
  var VIRTUAL_MODULES = {
@@ -432,7 +802,19 @@ async function handleRequest(getApp, req, res, options) {
432
802
  trustProxy: options.trustProxy === true,
433
803
  ...isRpc ? { maxBodyBytes: options.bodyLimitBytes ?? DEFAULT_BODY_LIMIT_BYTES } : {}
434
804
  });
435
- const response = await app.handler(request);
805
+ let response;
806
+ try {
807
+ response = await runHandlerWithTimeout(app.handler, request, options.requestTimeoutMs);
808
+ } catch (error) {
809
+ if (error instanceof RequestTimeoutError) {
810
+ res.statusCode = 504;
811
+ res.setHeader("content-type", "text/plain; charset=utf-8");
812
+ applyStaticHeaders({ has: (name) => res.hasHeader(name), set: (name, value) => res.setHeader(name, value) }, "/", undefined);
813
+ res.end(requestTimeoutText(error.limit));
814
+ return;
815
+ }
816
+ throw error;
817
+ }
436
818
  await sendNodeResponse2(res, response);
437
819
  }
438
820
  function shouldHandle(req, apiPrefix) {
@@ -462,7 +844,7 @@ function shouldHandle(req, apiPrefix) {
462
844
 
463
845
  // src/manifest.ts
464
846
  import { findLayouts, routeKeyFromFile } from "@moonsjs/core";
465
- import { relative, sep } from "node:path";
847
+ import { relative, sep as sep2 } from "node:path";
466
848
  var NOT_FOUND_ROUTE_KEY = "__moons/404";
467
849
  var ERROR_ROUTE_KEY = "__moons/error";
468
850
  function buildClientManifest(routes, routesDir) {
@@ -534,10 +916,10 @@ function renderRoutesModule(routes, routesDir, projectRoot) {
534
916
  }
535
917
  function rootSpecifier(projectRoot, file) {
536
918
  let rel = relative(projectRoot, file);
537
- rel = sep === "/" ? rel : rel.split(sep).join("/");
919
+ rel = sep2 === "/" ? rel : rel.split(sep2).join("/");
538
920
  return rel.startsWith("/") ? rel : `/${rel}`;
539
921
  }
540
922
 
541
- export { NOT_FOUND_ROUTE_KEY, renderApiModule, renderRoutesModule, rootSpecifier, VIRTUAL_MODULES, fromNullPrefixed, ROOT_PLACEHOLDER2, DEFAULT_TEMPLATE2, injectShell2, createDevShell2, createFileShell2, InvalidRequestError, BodyLimitError, resolveRequestUrl, resolveClientIp, toWebRequest2, DEFAULT_SECURITY_HEADERS, sendNodeResponse2, installDevMiddleware2 };
923
+ export { NOT_FOUND_ROUTE_KEY, renderApiModule, renderRoutesModule, rootSpecifier, VIRTUAL_MODULES, fromNullPrefixed, ROOT_PLACEHOLDER2, DEFAULT_TEMPLATE2, injectShell2, createDevShell2, createFileShell2, scanPayloadForSecrets, MAX_TRANSPORT_BODY_BYTES, InvalidRequestError, BodyLimitError, DEFAULT_SECURITY_HEADERS, forwardedProtocol, forwardedHost, resolveClientIpValues, MIME_TYPES, COMPRESSIBLE_FILE, GZIP_MIN_BYTES, gzipCached, acceptsGzipHeader, rpcBodyTooLargeText, RequestTimeoutError, requestTimeoutText, runHandlerWithTimeout, isAbortLike, textResponseWithHeaders, applyStaticHeaders, readBodyWithLimit, resolveStaticFile2, staticFileTarget, scheduleRevalidation, resolveRequestUrl, resolveClientIp, toWebRequest2, sendNodeResponse2, installDevMiddleware2 };
542
924
 
543
- //# debugId=B02A629B2D6A252264756E2164756E21
925
+ //# debugId=A0E69BBAD13811FD64756E2164756E21