Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
1182 lines
45 KiB
Text
1182 lines
45 KiB
Text
// ../../node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/colors.mjs
|
|
var FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY = !0;
|
|
typeof process < "u" && ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {}, isTTY = process.stdout && process.stdout.isTTY);
|
|
var $ = {
|
|
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY)
|
|
};
|
|
function init(x, y) {
|
|
let rgx = new RegExp(`\\x1b\\[${y}m`, "g"), open = `\x1B[${x}m`, close = `\x1B[${y}m`;
|
|
return function(txt) {
|
|
return !$.enabled || txt == null ? txt : open + (~("" + txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;
|
|
};
|
|
}
|
|
var reset = init(0, 0), bold = init(1, 22), dim = init(2, 22), italic = init(3, 23), underline = init(4, 24), inverse = init(7, 27), hidden = init(8, 28), strikethrough = init(9, 29), black = init(30, 39), red = init(31, 39), green = init(32, 39), yellow = init(33, 39), blue = init(34, 39), magenta = init(35, 39), cyan = init(36, 39), white = init(37, 39), gray = init(90, 39), grey = init(90, 39), bgBlack = init(40, 49), bgRed = init(41, 49), bgGreen = init(42, 49), bgYellow = init(43, 49), bgBlue = init(44, 49), bgMagenta = init(45, 49), bgCyan = init(46, 49), bgWhite = init(47, 49);
|
|
|
|
// src/workers/core/entry.worker.ts
|
|
import { HttpError, LogLevel, SharedHeaders } from "miniflare:shared";
|
|
|
|
// src/shared/mime-types.ts
|
|
var compressedByCloudflareFL = /* @__PURE__ */ new Set([
|
|
// list copied from https://developers.cloudflare.com/speed/optimization/content/brotli/content-compression/#:~:text=If%20supported%20by%20visitors%E2%80%99%20web%20browsers%2C%20Cloudflare%20will%20return%20Gzip%20or%20Brotli%2Dencoded%20responses%20for%20the%20following%20content%20types%3A
|
|
"text/html",
|
|
"text/richtext",
|
|
"text/plain",
|
|
"text/css",
|
|
"text/x-script",
|
|
"text/x-component",
|
|
"text/x-java-source",
|
|
"text/x-markdown",
|
|
"application/javascript",
|
|
"application/x-javascript",
|
|
"text/javascript",
|
|
"text/js",
|
|
"image/x-icon",
|
|
"image/vnd.microsoft.icon",
|
|
"application/x-perl",
|
|
"application/x-httpd-cgi",
|
|
"text/xml",
|
|
"application/xml",
|
|
"application/rss+xml",
|
|
"application/vnd.api+json",
|
|
"application/x-protobuf",
|
|
"application/json",
|
|
"multipart/bag",
|
|
"multipart/mixed",
|
|
"application/xhtml+xml",
|
|
"font/ttf",
|
|
"font/otf",
|
|
"font/x-woff",
|
|
"image/svg+xml",
|
|
"application/vnd.ms-fontobject",
|
|
"application/ttf",
|
|
"application/x-ttf",
|
|
"application/otf",
|
|
"application/x-otf",
|
|
"application/truetype",
|
|
"application/opentype",
|
|
"application/x-opentype",
|
|
"application/font-woff",
|
|
"application/eot",
|
|
"application/font",
|
|
"application/font-sfnt",
|
|
"application/wasm",
|
|
"application/javascript-binast",
|
|
"application/manifest+json",
|
|
"application/ld+json",
|
|
"application/graphql+json",
|
|
"application/geo+json"
|
|
]);
|
|
function isCompressedByCloudflareFL(contentTypeHeader) {
|
|
if (!contentTypeHeader)
|
|
return !0;
|
|
let [contentType] = contentTypeHeader.split(";");
|
|
return compressedByCloudflareFL.has(contentType);
|
|
}
|
|
|
|
// src/workers/core/constants.ts
|
|
var CoreHeaders = {
|
|
CUSTOM_SERVICE: "MF-Custom-Service",
|
|
ORIGINAL_URL: "MF-Original-URL",
|
|
PROXY_SHARED_SECRET: "MF-Proxy-Shared-Secret",
|
|
DISABLE_PRETTY_ERROR: "MF-Disable-Pretty-Error",
|
|
ERROR_STACK: "MF-Experimental-Error-Stack",
|
|
ROUTE_OVERRIDE: "MF-Route-Override",
|
|
CF_BLOB: "MF-CF-Blob",
|
|
// API Proxy
|
|
OP_SECRET: "MF-Op-Secret",
|
|
OP: "MF-Op",
|
|
OP_TARGET: "MF-Op-Target",
|
|
OP_KEY: "MF-Op-Key",
|
|
OP_SYNC: "MF-Op-Sync",
|
|
OP_STRINGIFIED_SIZE: "MF-Op-Stringified-Size",
|
|
OP_RESULT_TYPE: "MF-Op-Result-Type"
|
|
}, CoreBindings = {
|
|
SERVICE_LOOPBACK: "MINIFLARE_LOOPBACK",
|
|
SERVICE_USER_ROUTE_PREFIX: "MINIFLARE_USER_ROUTE_",
|
|
SERVICE_USER_FALLBACK: "MINIFLARE_USER_FALLBACK",
|
|
TEXT_CUSTOM_SERVICE: "MINIFLARE_CUSTOM_SERVICE",
|
|
TEXT_UPSTREAM_URL: "MINIFLARE_UPSTREAM_URL",
|
|
JSON_CF_BLOB: "CF_BLOB",
|
|
JSON_ROUTES: "MINIFLARE_ROUTES",
|
|
JSON_LOG_LEVEL: "MINIFLARE_LOG_LEVEL",
|
|
DATA_LIVE_RELOAD_SCRIPT: "MINIFLARE_LIVE_RELOAD_SCRIPT",
|
|
DURABLE_OBJECT_NAMESPACE_PROXY: "MINIFLARE_PROXY",
|
|
DATA_PROXY_SECRET: "MINIFLARE_PROXY_SECRET",
|
|
DATA_PROXY_SHARED_SECRET: "MINIFLARE_PROXY_SHARED_SECRET"
|
|
}, ProxyOps = {
|
|
// Get the target or a property of the target
|
|
GET: "GET",
|
|
// Get the descriptor for a property of the target
|
|
GET_OWN_DESCRIPTOR: "GET_OWN_DESCRIPTOR",
|
|
// Get the target's own property names
|
|
GET_OWN_KEYS: "GET_OWN_KEYS",
|
|
// Call a method on the target
|
|
CALL: "CALL",
|
|
// Remove the strong reference to the target on the "heap", allowing it to be
|
|
// garbage collected
|
|
FREE: "FREE"
|
|
}, ProxyAddresses = {
|
|
GLOBAL: 0,
|
|
// globalThis
|
|
ENV: 1,
|
|
// env
|
|
USER_START: 2
|
|
};
|
|
function isFetcherFetch(targetName, key) {
|
|
return (targetName === "Fetcher" || targetName === "DurableObject" || targetName === "WorkerRpc") && key === "fetch";
|
|
}
|
|
function isR2ObjectWriteHttpMetadata(targetName, key) {
|
|
return (targetName === "HeadResult" || targetName === "GetResult") && key === "writeHttpMetadata";
|
|
}
|
|
|
|
// src/workers/core/http.ts
|
|
var STATUS_CODES = {
|
|
100: "Continue",
|
|
101: "Switching Protocols",
|
|
102: "Processing",
|
|
103: "Early Hints",
|
|
200: "OK",
|
|
201: "Created",
|
|
202: "Accepted",
|
|
203: "Non-Authoritative Information",
|
|
204: "No Content",
|
|
205: "Reset Content",
|
|
206: "Partial Content",
|
|
207: "Multi-Status",
|
|
208: "Already Reported",
|
|
226: "IM Used",
|
|
300: "Multiple Choices",
|
|
301: "Moved Permanently",
|
|
302: "Found",
|
|
303: "See Other",
|
|
304: "Not Modified",
|
|
305: "Use Proxy",
|
|
307: "Temporary Redirect",
|
|
308: "Permanent Redirect",
|
|
400: "Bad Request",
|
|
401: "Unauthorized",
|
|
402: "Payment Required",
|
|
403: "Forbidden",
|
|
404: "Not Found",
|
|
405: "Method Not Allowed",
|
|
406: "Not Acceptable",
|
|
407: "Proxy Authentication Required",
|
|
408: "Request Timeout",
|
|
409: "Conflict",
|
|
410: "Gone",
|
|
411: "Length Required",
|
|
412: "Precondition Failed",
|
|
413: "Payload Too Large",
|
|
414: "URI Too Long",
|
|
415: "Unsupported Media Type",
|
|
416: "Range Not Satisfiable",
|
|
417: "Expectation Failed",
|
|
418: "I'm a Teapot",
|
|
421: "Misdirected Request",
|
|
422: "Unprocessable Entity",
|
|
423: "Locked",
|
|
424: "Failed Dependency",
|
|
425: "Too Early",
|
|
426: "Upgrade Required",
|
|
428: "Precondition Required",
|
|
429: "Too Many Requests",
|
|
431: "Request Header Fields Too Large",
|
|
451: "Unavailable For Legal Reasons",
|
|
500: "Internal Server Error",
|
|
501: "Not Implemented",
|
|
502: "Bad Gateway",
|
|
503: "Service Unavailable",
|
|
504: "Gateway Timeout",
|
|
505: "HTTP Version Not Supported",
|
|
506: "Variant Also Negotiates",
|
|
507: "Insufficient Storage",
|
|
508: "Loop Detected",
|
|
509: "Bandwidth Limit Exceeded",
|
|
510: "Not Extended",
|
|
511: "Network Authentication Required"
|
|
};
|
|
|
|
// src/workers/core/routing.ts
|
|
function matchRoutes(routes, url) {
|
|
for (let route of routes) {
|
|
if (route.protocol && route.protocol !== url.protocol)
|
|
continue;
|
|
if (route.allowHostnamePrefix) {
|
|
if (!url.hostname.endsWith(route.hostname))
|
|
continue;
|
|
} else if (url.hostname !== route.hostname)
|
|
continue;
|
|
let path = url.pathname + url.search;
|
|
if (route.allowPathSuffix) {
|
|
if (!path.startsWith(route.path))
|
|
continue;
|
|
} else if (path !== route.path)
|
|
continue;
|
|
return route.target;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// src/workers/core/proxy.worker.ts
|
|
import assert2 from "node:assert";
|
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
|
|
// ../../node_modules/.pnpm/devalue@5.3.2/node_modules/devalue/src/utils.js
|
|
var DevalueError = class extends Error {
|
|
/**
|
|
* @param {string} message
|
|
* @param {string[]} keys
|
|
*/
|
|
constructor(message, keys) {
|
|
super(message), this.name = "DevalueError", this.path = keys.join("");
|
|
}
|
|
};
|
|
function is_primitive(thing) {
|
|
return Object(thing) !== thing;
|
|
}
|
|
var object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames(
|
|
Object.prototype
|
|
).sort().join("\0");
|
|
function is_plain_object(thing) {
|
|
let proto = Object.getPrototypeOf(thing);
|
|
return proto === Object.prototype || proto === null || Object.getPrototypeOf(proto) === null || Object.getOwnPropertyNames(proto).sort().join("\0") === object_proto_names;
|
|
}
|
|
function get_type(thing) {
|
|
return Object.prototype.toString.call(thing).slice(8, -1);
|
|
}
|
|
function get_escaped_char(char) {
|
|
switch (char) {
|
|
case '"':
|
|
return '\\"';
|
|
case "<":
|
|
return "\\u003C";
|
|
case "\\":
|
|
return "\\\\";
|
|
case `
|
|
`:
|
|
return "\\n";
|
|
case "\r":
|
|
return "\\r";
|
|
case " ":
|
|
return "\\t";
|
|
case "\b":
|
|
return "\\b";
|
|
case "\f":
|
|
return "\\f";
|
|
case "\u2028":
|
|
return "\\u2028";
|
|
case "\u2029":
|
|
return "\\u2029";
|
|
default:
|
|
return char < " " ? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}` : "";
|
|
}
|
|
}
|
|
function stringify_string(str) {
|
|
let result = "", last_pos = 0, len = str.length;
|
|
for (let i = 0; i < len; i += 1) {
|
|
let char = str[i], replacement = get_escaped_char(char);
|
|
replacement && (result += str.slice(last_pos, i) + replacement, last_pos = i + 1);
|
|
}
|
|
return `"${last_pos === 0 ? str : result + str.slice(last_pos)}"`;
|
|
}
|
|
function enumerable_symbols(object) {
|
|
return Object.getOwnPropertySymbols(object).filter(
|
|
(symbol) => Object.getOwnPropertyDescriptor(object, symbol).enumerable
|
|
);
|
|
}
|
|
var is_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
|
|
function stringify_key(key) {
|
|
return is_identifier.test(key) ? "." + key : "[" + JSON.stringify(key) + "]";
|
|
}
|
|
|
|
// ../../node_modules/.pnpm/devalue@5.3.2/node_modules/devalue/src/base64.js
|
|
function encode64(arraybuffer) {
|
|
let dv = new DataView(arraybuffer), binaryString = "";
|
|
for (let i = 0; i < arraybuffer.byteLength; i++)
|
|
binaryString += String.fromCharCode(dv.getUint8(i));
|
|
return binaryToAscii(binaryString);
|
|
}
|
|
function decode64(string) {
|
|
let binaryString = asciiToBinary(string), arraybuffer = new ArrayBuffer(binaryString.length), dv = new DataView(arraybuffer);
|
|
for (let i = 0; i < arraybuffer.byteLength; i++)
|
|
dv.setUint8(i, binaryString.charCodeAt(i));
|
|
return arraybuffer;
|
|
}
|
|
var KEY_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
function asciiToBinary(data) {
|
|
data.length % 4 === 0 && (data = data.replace(/==?$/, ""));
|
|
let output = "", buffer = 0, accumulatedBits = 0;
|
|
for (let i = 0; i < data.length; i++)
|
|
buffer <<= 6, buffer |= KEY_STRING.indexOf(data[i]), accumulatedBits += 6, accumulatedBits === 24 && (output += String.fromCharCode((buffer & 16711680) >> 16), output += String.fromCharCode((buffer & 65280) >> 8), output += String.fromCharCode(buffer & 255), buffer = accumulatedBits = 0);
|
|
return accumulatedBits === 12 ? (buffer >>= 4, output += String.fromCharCode(buffer)) : accumulatedBits === 18 && (buffer >>= 2, output += String.fromCharCode((buffer & 65280) >> 8), output += String.fromCharCode(buffer & 255)), output;
|
|
}
|
|
function binaryToAscii(str) {
|
|
let out = "";
|
|
for (let i = 0; i < str.length; i += 3) {
|
|
let groupsOfSix = [void 0, void 0, void 0, void 0];
|
|
groupsOfSix[0] = str.charCodeAt(i) >> 2, groupsOfSix[1] = (str.charCodeAt(i) & 3) << 4, str.length > i + 1 && (groupsOfSix[1] |= str.charCodeAt(i + 1) >> 4, groupsOfSix[2] = (str.charCodeAt(i + 1) & 15) << 2), str.length > i + 2 && (groupsOfSix[2] |= str.charCodeAt(i + 2) >> 6, groupsOfSix[3] = str.charCodeAt(i + 2) & 63);
|
|
for (let j = 0; j < groupsOfSix.length; j++)
|
|
typeof groupsOfSix[j] > "u" ? out += "=" : out += KEY_STRING[groupsOfSix[j]];
|
|
}
|
|
return out;
|
|
}
|
|
|
|
// ../../node_modules/.pnpm/devalue@5.3.2/node_modules/devalue/src/parse.js
|
|
function parse(serialized, revivers) {
|
|
return unflatten(JSON.parse(serialized), revivers);
|
|
}
|
|
function unflatten(parsed, revivers) {
|
|
if (typeof parsed == "number")
|
|
return hydrate(parsed, !0);
|
|
if (!Array.isArray(parsed) || parsed.length === 0)
|
|
throw new Error("Invalid input");
|
|
let values = (
|
|
/** @type {any[]} */
|
|
parsed
|
|
), hydrated = Array(values.length);
|
|
function hydrate(index, standalone = !1) {
|
|
if (index === -1)
|
|
return;
|
|
if (index === -3)
|
|
return NaN;
|
|
if (index === -4)
|
|
return 1 / 0;
|
|
if (index === -5)
|
|
return -1 / 0;
|
|
if (index === -6)
|
|
return -0;
|
|
if (standalone || typeof index != "number")
|
|
throw new Error("Invalid input");
|
|
if (index in hydrated)
|
|
return hydrated[index];
|
|
let value = values[index];
|
|
if (!value || typeof value != "object")
|
|
hydrated[index] = value;
|
|
else if (Array.isArray(value))
|
|
if (typeof value[0] == "string") {
|
|
let type = value[0], reviver = revivers?.[type];
|
|
if (reviver)
|
|
return hydrated[index] = reviver(hydrate(value[1]));
|
|
switch (type) {
|
|
case "Date":
|
|
hydrated[index] = new Date(value[1]);
|
|
break;
|
|
case "Set":
|
|
let set = /* @__PURE__ */ new Set();
|
|
hydrated[index] = set;
|
|
for (let i = 1; i < value.length; i += 1)
|
|
set.add(hydrate(value[i]));
|
|
break;
|
|
case "Map":
|
|
let map = /* @__PURE__ */ new Map();
|
|
hydrated[index] = map;
|
|
for (let i = 1; i < value.length; i += 2)
|
|
map.set(hydrate(value[i]), hydrate(value[i + 1]));
|
|
break;
|
|
case "RegExp":
|
|
hydrated[index] = new RegExp(value[1], value[2]);
|
|
break;
|
|
case "Object":
|
|
hydrated[index] = Object(value[1]);
|
|
break;
|
|
case "BigInt":
|
|
hydrated[index] = BigInt(value[1]);
|
|
break;
|
|
case "null":
|
|
let obj = /* @__PURE__ */ Object.create(null);
|
|
hydrated[index] = obj;
|
|
for (let i = 1; i < value.length; i += 2)
|
|
obj[value[i]] = hydrate(value[i + 1]);
|
|
break;
|
|
case "Int8Array":
|
|
case "Uint8Array":
|
|
case "Uint8ClampedArray":
|
|
case "Int16Array":
|
|
case "Uint16Array":
|
|
case "Int32Array":
|
|
case "Uint32Array":
|
|
case "Float32Array":
|
|
case "Float64Array":
|
|
case "BigInt64Array":
|
|
case "BigUint64Array": {
|
|
let TypedArrayConstructor = globalThis[type], typedArray = new TypedArrayConstructor(hydrate(value[1]));
|
|
hydrated[index] = value[2] !== void 0 ? typedArray.subarray(value[2], value[3]) : typedArray;
|
|
break;
|
|
}
|
|
case "ArrayBuffer": {
|
|
let base64 = value[1], arraybuffer = decode64(base64);
|
|
hydrated[index] = arraybuffer;
|
|
break;
|
|
}
|
|
case "Temporal.Duration":
|
|
case "Temporal.Instant":
|
|
case "Temporal.PlainDate":
|
|
case "Temporal.PlainTime":
|
|
case "Temporal.PlainDateTime":
|
|
case "Temporal.PlainMonthDay":
|
|
case "Temporal.PlainYearMonth":
|
|
case "Temporal.ZonedDateTime": {
|
|
let temporalName = type.slice(9);
|
|
hydrated[index] = Temporal[temporalName].from(value[1]);
|
|
break;
|
|
}
|
|
case "URL": {
|
|
let url = new URL(value[1]);
|
|
hydrated[index] = url;
|
|
break;
|
|
}
|
|
case "URLSearchParams": {
|
|
let url = new URLSearchParams(value[1]);
|
|
hydrated[index] = url;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(`Unknown type ${type}`);
|
|
}
|
|
} else {
|
|
let array = new Array(value.length);
|
|
hydrated[index] = array;
|
|
for (let i = 0; i < value.length; i += 1) {
|
|
let n = value[i];
|
|
n !== -2 && (array[i] = hydrate(n));
|
|
}
|
|
}
|
|
else {
|
|
let object = {};
|
|
hydrated[index] = object;
|
|
for (let key in value) {
|
|
if (key === "__proto__")
|
|
throw new Error("Cannot parse an object with a `__proto__` property");
|
|
let n = value[key];
|
|
object[key] = hydrate(n);
|
|
}
|
|
}
|
|
return hydrated[index];
|
|
}
|
|
return hydrate(0);
|
|
}
|
|
|
|
// ../../node_modules/.pnpm/devalue@5.3.2/node_modules/devalue/src/stringify.js
|
|
function stringify(value, reducers) {
|
|
let stringified = [], indexes = /* @__PURE__ */ new Map(), custom = [];
|
|
if (reducers)
|
|
for (let key of Object.getOwnPropertyNames(reducers))
|
|
custom.push({ key, fn: reducers[key] });
|
|
let keys = [], p = 0;
|
|
function flatten(thing) {
|
|
if (typeof thing == "function")
|
|
throw new DevalueError("Cannot stringify a function", keys);
|
|
if (thing === void 0)
|
|
return -1;
|
|
if (Number.isNaN(thing))
|
|
return -3;
|
|
if (thing === 1 / 0)
|
|
return -4;
|
|
if (thing === -1 / 0)
|
|
return -5;
|
|
if (thing === 0 && 1 / thing < 0)
|
|
return -6;
|
|
if (indexes.has(thing))
|
|
return indexes.get(thing);
|
|
let index2 = p++;
|
|
indexes.set(thing, index2);
|
|
for (let { key, fn } of custom) {
|
|
let value2 = fn(thing);
|
|
if (value2)
|
|
return stringified[index2] = `["${key}",${flatten(value2)}]`, index2;
|
|
}
|
|
let str = "";
|
|
if (is_primitive(thing))
|
|
str = stringify_primitive(thing);
|
|
else {
|
|
let type = get_type(thing);
|
|
switch (type) {
|
|
case "Number":
|
|
case "String":
|
|
case "Boolean":
|
|
str = `["Object",${stringify_primitive(thing)}]`;
|
|
break;
|
|
case "BigInt":
|
|
str = `["BigInt",${thing}]`;
|
|
break;
|
|
case "Date":
|
|
str = `["Date","${!isNaN(thing.getDate()) ? thing.toISOString() : ""}"]`;
|
|
break;
|
|
case "URL":
|
|
str = `["URL",${stringify_string(thing.toString())}]`;
|
|
break;
|
|
case "URLSearchParams":
|
|
str = `["URLSearchParams",${stringify_string(thing.toString())}]`;
|
|
break;
|
|
case "RegExp":
|
|
let { source, flags } = thing;
|
|
str = flags ? `["RegExp",${stringify_string(source)},"${flags}"]` : `["RegExp",${stringify_string(source)}]`;
|
|
break;
|
|
case "Array":
|
|
str = "[";
|
|
for (let i = 0; i < thing.length; i += 1)
|
|
i > 0 && (str += ","), i in thing ? (keys.push(`[${i}]`), str += flatten(thing[i]), keys.pop()) : str += -2;
|
|
str += "]";
|
|
break;
|
|
case "Set":
|
|
str = '["Set"';
|
|
for (let value2 of thing)
|
|
str += `,${flatten(value2)}`;
|
|
str += "]";
|
|
break;
|
|
case "Map":
|
|
str = '["Map"';
|
|
for (let [key, value2] of thing)
|
|
keys.push(
|
|
`.get(${is_primitive(key) ? stringify_primitive(key) : "..."})`
|
|
), str += `,${flatten(key)},${flatten(value2)}`, keys.pop();
|
|
str += "]";
|
|
break;
|
|
case "Int8Array":
|
|
case "Uint8Array":
|
|
case "Uint8ClampedArray":
|
|
case "Int16Array":
|
|
case "Uint16Array":
|
|
case "Int32Array":
|
|
case "Uint32Array":
|
|
case "Float32Array":
|
|
case "Float64Array":
|
|
case "BigInt64Array":
|
|
case "BigUint64Array": {
|
|
let typedArray = thing;
|
|
str = '["' + type + '",' + flatten(typedArray.buffer);
|
|
let a = thing.byteOffset, b = a + thing.byteLength;
|
|
if (a > 0 || b !== typedArray.buffer.byteLength) {
|
|
let m = +/(\d+)/.exec(type)[1] / 8;
|
|
str += `,${a / m},${b / m}`;
|
|
}
|
|
str += "]";
|
|
break;
|
|
}
|
|
case "ArrayBuffer": {
|
|
str = `["ArrayBuffer","${encode64(thing)}"]`;
|
|
break;
|
|
}
|
|
case "Temporal.Duration":
|
|
case "Temporal.Instant":
|
|
case "Temporal.PlainDate":
|
|
case "Temporal.PlainTime":
|
|
case "Temporal.PlainDateTime":
|
|
case "Temporal.PlainMonthDay":
|
|
case "Temporal.PlainYearMonth":
|
|
case "Temporal.ZonedDateTime":
|
|
str = `["${type}",${stringify_string(thing.toString())}]`;
|
|
break;
|
|
default:
|
|
if (!is_plain_object(thing))
|
|
throw new DevalueError(
|
|
"Cannot stringify arbitrary non-POJOs",
|
|
keys
|
|
);
|
|
if (enumerable_symbols(thing).length > 0)
|
|
throw new DevalueError(
|
|
"Cannot stringify POJOs with symbolic keys",
|
|
keys
|
|
);
|
|
if (Object.getPrototypeOf(thing) === null) {
|
|
str = '["null"';
|
|
for (let key in thing)
|
|
keys.push(stringify_key(key)), str += `,${stringify_string(key)},${flatten(thing[key])}`, keys.pop();
|
|
str += "]";
|
|
} else {
|
|
str = "{";
|
|
let started = !1;
|
|
for (let key in thing)
|
|
started && (str += ","), started = !0, keys.push(stringify_key(key)), str += `${stringify_string(key)}:${flatten(thing[key])}`, keys.pop();
|
|
str += "}";
|
|
}
|
|
}
|
|
}
|
|
return stringified[index2] = str, index2;
|
|
}
|
|
let index = flatten(value);
|
|
return index < 0 ? `${index}` : `[${stringified.join(",")}]`;
|
|
}
|
|
function stringify_primitive(thing) {
|
|
let type = typeof thing;
|
|
return type === "string" ? stringify_string(thing) : thing instanceof String ? stringify_string(thing.toString()) : thing === void 0 ? (-1).toString() : thing === 0 && 1 / thing < 0 ? (-6).toString() : type === "bigint" ? `["BigInt","${thing}"]` : String(thing);
|
|
}
|
|
|
|
// src/workers/core/proxy.worker.ts
|
|
import { readPrefix, reduceError } from "miniflare:shared";
|
|
|
|
// src/workers/core/devalue.ts
|
|
import assert from "node:assert";
|
|
import { Buffer } from "node:buffer";
|
|
var ALLOWED_ARRAY_BUFFER_VIEW_CONSTRUCTORS = [
|
|
DataView,
|
|
Int8Array,
|
|
Uint8Array,
|
|
Uint8ClampedArray,
|
|
Int16Array,
|
|
Uint16Array,
|
|
Int32Array,
|
|
Uint32Array,
|
|
Float32Array,
|
|
Float64Array,
|
|
BigInt64Array,
|
|
BigUint64Array
|
|
], ALLOWED_ERROR_CONSTRUCTORS = [
|
|
EvalError,
|
|
RangeError,
|
|
ReferenceError,
|
|
SyntaxError,
|
|
TypeError,
|
|
URIError,
|
|
Error
|
|
// `Error` last so more specific error subclasses preferred
|
|
], structuredSerializableReducers = {
|
|
ArrayBuffer(value) {
|
|
if (value instanceof ArrayBuffer)
|
|
return [Buffer.from(value).toString("base64")];
|
|
},
|
|
ArrayBufferView(value) {
|
|
if (ArrayBuffer.isView(value))
|
|
return [
|
|
value.constructor.name,
|
|
value.buffer,
|
|
value.byteOffset,
|
|
value.byteLength
|
|
];
|
|
},
|
|
RegExp(value) {
|
|
if (value instanceof RegExp) {
|
|
let { source, flags } = value, encoded = Buffer.from(source).toString("base64");
|
|
return flags ? ["RegExp", encoded, flags] : ["RegExp", encoded];
|
|
}
|
|
},
|
|
Error(value) {
|
|
for (let ctor of ALLOWED_ERROR_CONSTRUCTORS)
|
|
if (value instanceof ctor && value.name === ctor.name)
|
|
return [value.name, value.message, value.stack, value.cause];
|
|
if (value instanceof Error)
|
|
return ["Error", value.message, value.stack, value.cause];
|
|
}
|
|
}, structuredSerializableRevivers = {
|
|
ArrayBuffer(value) {
|
|
assert(Array.isArray(value));
|
|
let [encoded] = value;
|
|
assert(typeof encoded == "string");
|
|
let view = Buffer.from(encoded, "base64");
|
|
return view.buffer.slice(
|
|
view.byteOffset,
|
|
view.byteOffset + view.byteLength
|
|
);
|
|
},
|
|
ArrayBufferView(value) {
|
|
assert(Array.isArray(value));
|
|
let [name, buffer, byteOffset, byteLength] = value;
|
|
assert(typeof name == "string"), assert(buffer instanceof ArrayBuffer), assert(typeof byteOffset == "number"), assert(typeof byteLength == "number");
|
|
let ctor = globalThis[name];
|
|
assert(ALLOWED_ARRAY_BUFFER_VIEW_CONSTRUCTORS.includes(ctor));
|
|
let length = byteLength;
|
|
return "BYTES_PER_ELEMENT" in ctor && (length /= ctor.BYTES_PER_ELEMENT), new ctor(buffer, byteOffset, length);
|
|
},
|
|
RegExp(value) {
|
|
assert(Array.isArray(value));
|
|
let [name, encoded, flags] = value;
|
|
assert(typeof name == "string"), assert(typeof encoded == "string");
|
|
let source = Buffer.from(encoded, "base64").toString("utf-8");
|
|
return new RegExp(source, flags);
|
|
},
|
|
Error(value) {
|
|
assert(Array.isArray(value));
|
|
let [name, message, stack, cause] = value;
|
|
assert(typeof name == "string"), assert(typeof message == "string"), assert(stack === void 0 || typeof stack == "string");
|
|
let ctor = globalThis[name];
|
|
assert(ALLOWED_ERROR_CONSTRUCTORS.includes(ctor));
|
|
let error = new ctor(message, { cause });
|
|
return error.stack = stack, error;
|
|
}
|
|
};
|
|
function createHTTPReducers(impl) {
|
|
return {
|
|
Headers(val) {
|
|
if (val instanceof impl.Headers)
|
|
return [...val.entries()];
|
|
},
|
|
Request(val) {
|
|
if (val instanceof impl.Request)
|
|
return [val.method, val.url, val.headers, val.cf, val.body];
|
|
},
|
|
Response(val) {
|
|
if (val instanceof impl.Response)
|
|
return [val.status, val.statusText, val.headers, val.cf, val.body];
|
|
}
|
|
};
|
|
}
|
|
function createHTTPRevivers(impl) {
|
|
return {
|
|
Headers(value) {
|
|
return assert(typeof value == "object" && value !== null), new impl.Headers(value);
|
|
},
|
|
Request(value) {
|
|
assert(Array.isArray(value));
|
|
let [method, url, headers, cf, body] = value;
|
|
return assert(typeof method == "string"), assert(typeof url == "string"), assert(headers instanceof impl.Headers), assert(body === null || impl.isReadableStream(body)), new impl.Request(url, {
|
|
method,
|
|
headers,
|
|
cf,
|
|
// @ts-expect-error `duplex` is not required by `workerd` yet
|
|
duplex: body === null ? void 0 : "half",
|
|
body
|
|
});
|
|
},
|
|
Response(value) {
|
|
assert(Array.isArray(value));
|
|
let [status, statusText, headers, cf, body] = value;
|
|
return assert(typeof status == "number"), assert(typeof statusText == "string"), assert(headers instanceof impl.Headers), assert(body === null || impl.isReadableStream(body)), new impl.Response(body, {
|
|
status,
|
|
statusText,
|
|
headers,
|
|
cf
|
|
});
|
|
}
|
|
};
|
|
}
|
|
function stringifyWithStreams(impl, value, reducers, allowUnbufferedStream) {
|
|
let unbufferedStream, bufferPromises = [], streamReducers = {
|
|
ReadableStream(value2) {
|
|
if (impl.isReadableStream(value2))
|
|
return allowUnbufferedStream && unbufferedStream === void 0 ? unbufferedStream = value2 : bufferPromises.push(impl.bufferReadableStream(value2)), !0;
|
|
},
|
|
Blob(value2) {
|
|
if (value2 instanceof impl.Blob)
|
|
return bufferPromises.push(value2.arrayBuffer()), !0;
|
|
},
|
|
...reducers
|
|
};
|
|
typeof value == "function" && (value = new __MiniflareFunctionWrapper(
|
|
value
|
|
));
|
|
let stringifiedValue = stringify(value, streamReducers);
|
|
return bufferPromises.length === 0 ? { value: stringifiedValue, unbufferedStream } : Promise.all(bufferPromises).then((streamBuffers) => (streamReducers.ReadableStream = function(value2) {
|
|
if (impl.isReadableStream(value2))
|
|
return value2 === unbufferedStream ? !0 : streamBuffers.shift();
|
|
}, streamReducers.Blob = function(value2) {
|
|
if (value2 instanceof impl.Blob) {
|
|
let array = [streamBuffers.shift(), value2.type];
|
|
return value2 instanceof impl.File && array.push(value2.name, value2.lastModified), array;
|
|
}
|
|
}, { value: stringify(value, streamReducers), unbufferedStream }));
|
|
}
|
|
var __MiniflareFunctionWrapper = class {
|
|
constructor(fnWithProps) {
|
|
return new Proxy(this, {
|
|
get: (_, key) => key === "__miniflareWrappedFunction" ? fnWithProps : fnWithProps[key]
|
|
});
|
|
}
|
|
};
|
|
function parseWithReadableStreams(impl, stringified, revivers) {
|
|
let streamRevivers = {
|
|
ReadableStream(value) {
|
|
return value === !0 ? (assert(stringified.unbufferedStream !== void 0), stringified.unbufferedStream) : (assert(value instanceof ArrayBuffer), impl.unbufferReadableStream(value));
|
|
},
|
|
Blob(value) {
|
|
if (assert(Array.isArray(value)), value.length === 2) {
|
|
let [buffer, type] = value;
|
|
assert(buffer instanceof ArrayBuffer), assert(typeof type == "string");
|
|
let opts = {};
|
|
return type !== "" && (opts.type = type), new impl.Blob([buffer], opts);
|
|
} else {
|
|
assert(value.length === 4);
|
|
let [buffer, type, name, lastModified] = value;
|
|
assert(buffer instanceof ArrayBuffer), assert(typeof type == "string"), assert(typeof name == "string"), assert(typeof lastModified == "number");
|
|
let opts = { lastModified };
|
|
return type !== "" && (opts.type = type), new impl.File([buffer], name, opts);
|
|
}
|
|
},
|
|
...revivers
|
|
};
|
|
return parse(stringified.value, streamRevivers);
|
|
}
|
|
|
|
// src/workers/core/proxy.worker.ts
|
|
var ENCODER = new TextEncoder(), DECODER = new TextDecoder(), ALLOWED_HOSTNAMES = ["127.0.0.1", "[::1]", "localhost"], WORKERS_PLATFORM_IMPL = {
|
|
Blob,
|
|
File,
|
|
Headers,
|
|
Request,
|
|
Response,
|
|
isReadableStream(value) {
|
|
return value instanceof ReadableStream;
|
|
},
|
|
bufferReadableStream(stream) {
|
|
return new Response(stream).arrayBuffer();
|
|
},
|
|
unbufferReadableStream(buffer) {
|
|
let body = new Response(buffer).body;
|
|
return assert2(body !== null), body;
|
|
}
|
|
}, objectProtoNames = Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
|
|
function isPlainObject(value) {
|
|
let proto = Object.getPrototypeOf(value);
|
|
return value?.constructor?.name === "RpcStub" || isObject(value) && objectContainsFunctions(value) ? !1 : proto === Object.prototype || proto === null || Object.getOwnPropertyNames(proto).sort().join("\0") === objectProtoNames;
|
|
}
|
|
function objectContainsFunctions(obj) {
|
|
let propertyNames = Object.getOwnPropertyNames(obj), propertySymbols = Object.getOwnPropertySymbols(obj), properties = [...propertyNames, ...propertySymbols];
|
|
for (let property of properties) {
|
|
let entry = obj[property];
|
|
if (typeof entry == "function" || isObject(entry) && objectContainsFunctions(entry))
|
|
return !0;
|
|
}
|
|
return !1;
|
|
}
|
|
function isObject(value) {
|
|
return !!value && typeof value == "object";
|
|
}
|
|
function getType(value) {
|
|
return Object.prototype.toString.call(value).slice(8, -1);
|
|
}
|
|
function isInternal(value) {
|
|
return isObject(value) && value[Symbol.for("cloudflare:internal-class")];
|
|
}
|
|
var ProxyServer = class {
|
|
constructor(_state, env) {
|
|
this.env = env;
|
|
this.heap.set(ProxyAddresses.GLOBAL, globalThis), this.heap.set(ProxyAddresses.ENV, env);
|
|
}
|
|
nextHeapAddress = ProxyAddresses.USER_START;
|
|
heap = /* @__PURE__ */ new Map();
|
|
reducers = {
|
|
...structuredSerializableReducers,
|
|
...createHTTPReducers(WORKERS_PLATFORM_IMPL),
|
|
// Corresponding revivers in `ProxyClient`
|
|
// `Native` reducer *MUST* be applied last
|
|
Native: (value) => {
|
|
let type = getType(value);
|
|
if ((type === "Object" || isInternal(value)) && !isPlainObject(value) || type === "Promise") {
|
|
let address = this.nextHeapAddress++;
|
|
this.heap.set(address, value), assert2(value !== null);
|
|
let name = value?.constructor.name, isFunction = value instanceof __MiniflareFunctionWrapper;
|
|
return [address, name, isFunction];
|
|
}
|
|
}
|
|
};
|
|
revivers = {
|
|
...structuredSerializableRevivers,
|
|
...createHTTPRevivers(WORKERS_PLATFORM_IMPL),
|
|
// Corresponding reducers in `ProxyClient`
|
|
Native: (value) => {
|
|
assert2(Array.isArray(value));
|
|
let [address] = value;
|
|
assert2(typeof address == "number");
|
|
let heapValue = this.heap.get(address);
|
|
return assert2(heapValue !== void 0), heapValue instanceof Promise && this.heap.delete(address), heapValue;
|
|
}
|
|
};
|
|
nativeReviver = { Native: this.revivers.Native };
|
|
async fetch(request) {
|
|
try {
|
|
return await this.#fetch(request);
|
|
} catch (e) {
|
|
let error = reduceError(e);
|
|
return Response.json(error, {
|
|
status: 500,
|
|
headers: { [CoreHeaders.ERROR_STACK]: "true" }
|
|
});
|
|
}
|
|
}
|
|
async #fetch(request) {
|
|
let hostHeader = request.headers.get("Host");
|
|
if (hostHeader == null)
|
|
return new Response(null, { status: 400 });
|
|
try {
|
|
let host = new URL(`http://${hostHeader}`);
|
|
if (!ALLOWED_HOSTNAMES.includes(host.hostname))
|
|
return new Response(null, { status: 401 });
|
|
} catch {
|
|
return new Response(null, { status: 400 });
|
|
}
|
|
let secretHex = request.headers.get(CoreHeaders.OP_SECRET);
|
|
if (secretHex == null)
|
|
return new Response(null, { status: 401 });
|
|
let expectedSecret = this.env[CoreBindings.DATA_PROXY_SECRET], secretBuffer = Buffer2.from(secretHex, "hex");
|
|
if (secretBuffer.byteLength !== expectedSecret.byteLength || !crypto.subtle.timingSafeEqual(secretBuffer, expectedSecret))
|
|
return new Response(null, { status: 401 });
|
|
let opHeader = request.headers.get(CoreHeaders.OP), targetHeader = request.headers.get(CoreHeaders.OP_TARGET), keyHeader = request.headers.get(CoreHeaders.OP_KEY), allowAsync = request.headers.get(CoreHeaders.OP_SYNC) === null, argsSizeHeader = request.headers.get(CoreHeaders.OP_STRINGIFIED_SIZE), contentLengthHeader = request.headers.get("Content-Length");
|
|
if (targetHeader === null)
|
|
return new Response(null, { status: 400 });
|
|
if (opHeader === ProxyOps.FREE) {
|
|
for (let targetValue of targetHeader.split(",")) {
|
|
let targetAddress = parseInt(targetValue);
|
|
assert2(!Number.isNaN(targetAddress)), this.heap.delete(targetAddress);
|
|
}
|
|
return new Response(null, { status: 204 });
|
|
}
|
|
let target = parse(
|
|
targetHeader,
|
|
this.nativeReviver
|
|
), targetName = target.constructor.name, status = 200, result, unbufferedRest, rpcAwaited = !1;
|
|
if (opHeader === ProxyOps.GET) {
|
|
if (result = keyHeader === null ? target : target[keyHeader], result?.constructor.name === "RpcProperty" && (result = await result), typeof result == "function")
|
|
return new Response(null, {
|
|
status: 204,
|
|
headers: { [CoreHeaders.OP_RESULT_TYPE]: "Function" }
|
|
});
|
|
} else if (opHeader === ProxyOps.GET_OWN_DESCRIPTOR) {
|
|
if (keyHeader === null)
|
|
return new Response(null, { status: 400 });
|
|
let descriptor = Object.getOwnPropertyDescriptor(target, keyHeader);
|
|
descriptor !== void 0 && (result = {
|
|
configurable: descriptor.configurable,
|
|
enumerable: descriptor.enumerable,
|
|
writable: descriptor.writable
|
|
});
|
|
} else if (opHeader === ProxyOps.GET_OWN_KEYS)
|
|
result = Object.getOwnPropertyNames(target);
|
|
else if (opHeader === ProxyOps.CALL) {
|
|
assert2(keyHeader !== null);
|
|
let func = target[keyHeader];
|
|
if (assert2(typeof func == "function"), isFetcherFetch(targetName, keyHeader)) {
|
|
let originalUrl = request.headers.get(CoreHeaders.ORIGINAL_URL), url = new URL(originalUrl ?? request.url);
|
|
return request = new Request(url, request), request.headers.delete(CoreHeaders.OP_SECRET), request.headers.delete(CoreHeaders.OP), request.headers.delete(CoreHeaders.OP_TARGET), request.headers.delete(CoreHeaders.OP_KEY), request.headers.delete(CoreHeaders.ORIGINAL_URL), request.headers.delete(CoreHeaders.DISABLE_PRETTY_ERROR), func.call(target, request);
|
|
}
|
|
let args;
|
|
if (argsSizeHeader === null || argsSizeHeader === contentLengthHeader)
|
|
args = parseWithReadableStreams(
|
|
WORKERS_PLATFORM_IMPL,
|
|
{ value: await request.text() },
|
|
this.revivers
|
|
);
|
|
else {
|
|
let argsSize = parseInt(argsSizeHeader);
|
|
assert2(!Number.isNaN(argsSize)), assert2(request.body !== null);
|
|
let [encodedArgs, rest] = await readPrefix(request.body, argsSize);
|
|
unbufferedRest = rest;
|
|
let stringifiedArgs = DECODER.decode(encodedArgs);
|
|
args = parseWithReadableStreams(
|
|
WORKERS_PLATFORM_IMPL,
|
|
{ value: stringifiedArgs, unbufferedStream: rest },
|
|
this.revivers
|
|
);
|
|
}
|
|
assert2(Array.isArray(args));
|
|
try {
|
|
["RpcProperty", "RpcStub"].includes(func.constructor.name) ? (result = await func(...args), rpcAwaited = !0) : result = func.apply(target, args), isR2ObjectWriteHttpMetadata(targetName, keyHeader) && (result = args[0]);
|
|
} catch (e) {
|
|
status = 500, result = e;
|
|
}
|
|
} else
|
|
return new Response(null, { status: 404 });
|
|
let headers = new Headers();
|
|
if (allowAsync && (result instanceof Promise || rpcAwaited)) {
|
|
try {
|
|
result = await result;
|
|
} catch (e) {
|
|
status = 500, result = e;
|
|
}
|
|
headers.append(CoreHeaders.OP_RESULT_TYPE, "Promise");
|
|
}
|
|
if (unbufferedRest !== void 0 && !unbufferedRest.locked)
|
|
try {
|
|
await unbufferedRest.pipeTo(new WritableStream());
|
|
} catch {
|
|
}
|
|
if (result instanceof ReadableStream)
|
|
return headers.append(CoreHeaders.OP_RESULT_TYPE, "ReadableStream"), new Response(result, { status, headers });
|
|
{
|
|
let stringified = await stringifyWithStreams(
|
|
WORKERS_PLATFORM_IMPL,
|
|
result,
|
|
this.reducers,
|
|
/* allowUnbufferedStream */
|
|
allowAsync
|
|
);
|
|
if (stringified.unbufferedStream === void 0)
|
|
return new Response(stringified.value, { status, headers });
|
|
{
|
|
let body = new IdentityTransformStream(), encodedValue = ENCODER.encode(stringified.value), encodedSize = encodedValue.byteLength.toString();
|
|
return headers.set(CoreHeaders.OP_STRINGIFIED_SIZE, encodedSize), this.#writeWithUnbufferedStream(
|
|
body.writable,
|
|
encodedValue,
|
|
stringified.unbufferedStream
|
|
), new Response(body.readable, { status, headers });
|
|
}
|
|
}
|
|
}
|
|
async #writeWithUnbufferedStream(writable, encodedValue, unbufferedStream) {
|
|
let writer = writable.getWriter();
|
|
await writer.write(encodedValue), writer.releaseLock(), await unbufferedStream.pipeTo(writable);
|
|
}
|
|
};
|
|
|
|
// src/workers/core/entry.worker.ts
|
|
var encoder = new TextEncoder();
|
|
function getUserRequest(request, env, clientIp) {
|
|
let originalUrl = request.headers.get(CoreHeaders.ORIGINAL_URL), url = new URL(originalUrl ?? request.url), rewriteHeadersFromOriginalUrl = !1, proxySharedSecret = request.headers.get(
|
|
CoreHeaders.PROXY_SHARED_SECRET
|
|
);
|
|
if (proxySharedSecret) {
|
|
let secretFromHeader = encoder.encode(proxySharedSecret), configuredSecret = env[CoreBindings.DATA_PROXY_SHARED_SECRET];
|
|
if (secretFromHeader.byteLength === configuredSecret?.byteLength && crypto.subtle.timingSafeEqual(secretFromHeader, configuredSecret))
|
|
rewriteHeadersFromOriginalUrl = !0;
|
|
else
|
|
throw new HttpError(
|
|
400,
|
|
`Disallowed header in request: ${CoreHeaders.PROXY_SHARED_SECRET}=${proxySharedSecret}`
|
|
);
|
|
}
|
|
let upstreamUrl = env[CoreBindings.TEXT_UPSTREAM_URL];
|
|
if (upstreamUrl !== void 0) {
|
|
let path = url.pathname + url.search;
|
|
path.startsWith("/") && (path = `./${path.substring(1)}`), url = new URL(path, upstreamUrl), rewriteHeadersFromOriginalUrl = !0;
|
|
}
|
|
if (request = new Request(url, request), request.headers.set("Accept-Encoding", "br, gzip"), rewriteHeadersFromOriginalUrl && request.headers.set("Host", url.host), clientIp && !request.headers.get("CF-Connecting-IP")) {
|
|
let ipv4Regex = /(?<ip>.*?):\d+/, ipv6Regex = /\[(?<ip>.*?)\]:\d+/, ip = clientIp.match(ipv6Regex)?.groups?.ip ?? clientIp.match(ipv4Regex)?.groups?.ip;
|
|
ip && request.headers.set("CF-Connecting-IP", ip);
|
|
}
|
|
return request.headers.delete(CoreHeaders.PROXY_SHARED_SECRET), request.headers.delete(CoreHeaders.ORIGINAL_URL), request.headers.delete(CoreHeaders.DISABLE_PRETTY_ERROR), request;
|
|
}
|
|
function getTargetService(request, url, env) {
|
|
let service = env[CoreBindings.SERVICE_USER_FALLBACK], override = request.headers.get(CoreHeaders.ROUTE_OVERRIDE);
|
|
request.headers.delete(CoreHeaders.ROUTE_OVERRIDE);
|
|
let route = override ?? matchRoutes(env[CoreBindings.JSON_ROUTES], url);
|
|
return route !== null && (service = env[`${CoreBindings.SERVICE_USER_ROUTE_PREFIX}${route}`]), service;
|
|
}
|
|
function maybePrettifyError(request, response, env) {
|
|
return response.status !== 500 || response.headers.get(CoreHeaders.ERROR_STACK) === null ? response : env[CoreBindings.SERVICE_LOOPBACK].fetch(
|
|
"http://localhost/core/error",
|
|
{
|
|
method: "POST",
|
|
headers: request.headers,
|
|
body: response.body,
|
|
cf: { prettyErrorOriginalUrl: request.url }
|
|
}
|
|
);
|
|
}
|
|
function maybeInjectLiveReload(response, env, ctx) {
|
|
let liveReloadScript = env[CoreBindings.DATA_LIVE_RELOAD_SCRIPT];
|
|
if (liveReloadScript === void 0 || !response.headers.get("Content-Type")?.toLowerCase().includes("text/html"))
|
|
return response;
|
|
let headers = new Headers(response.headers), contentLength = parseInt(headers.get("content-length"));
|
|
isNaN(contentLength) || headers.set(
|
|
"content-length",
|
|
String(contentLength + liveReloadScript.byteLength)
|
|
);
|
|
let { readable, writable } = new IdentityTransformStream();
|
|
return ctx.waitUntil(
|
|
(async () => {
|
|
await response.body?.pipeTo(writable, { preventClose: !0 });
|
|
let writer = writable.getWriter();
|
|
await writer.write(liveReloadScript), await writer.close();
|
|
})()
|
|
), new Response(readable, {
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
headers
|
|
});
|
|
}
|
|
var acceptEncodingElement = /^(?<coding>[a-z]+|\*)(?:\s*;\s*q=(?<weight>\d+(?:.\d+)?))?$/;
|
|
function maybeParseAcceptEncodingElement(element) {
|
|
let match = acceptEncodingElement.exec(element);
|
|
if (match?.groups != null)
|
|
return {
|
|
coding: match.groups.coding,
|
|
weight: match.groups.weight === void 0 ? 1 : parseFloat(match.groups.weight)
|
|
};
|
|
}
|
|
function parseAcceptEncoding(header) {
|
|
let encodings = [];
|
|
for (let element of header.split(",")) {
|
|
let maybeEncoding = maybeParseAcceptEncodingElement(element.trim());
|
|
maybeEncoding !== void 0 && encodings.push(maybeEncoding);
|
|
}
|
|
return encodings.sort((a, b) => b.weight - a.weight);
|
|
}
|
|
function ensureAcceptableEncoding(clientAcceptEncoding, response) {
|
|
if (clientAcceptEncoding === null)
|
|
return response;
|
|
let encodings = parseAcceptEncoding(clientAcceptEncoding);
|
|
if (encodings.length === 0)
|
|
return response;
|
|
let contentEncoding = response.headers.get("Content-Encoding"), contentType = response.headers.get("Content-Type");
|
|
if (!isCompressedByCloudflareFL(contentType) || contentEncoding !== null && contentEncoding !== "gzip" && contentEncoding !== "br")
|
|
return response;
|
|
let desiredEncoding, identityDisallowed = !1;
|
|
for (let encoding of encodings)
|
|
if (encoding.weight === 0)
|
|
(encoding.coding === "identity" || encoding.coding === "*") && (identityDisallowed = !0);
|
|
else if (encoding.coding === "gzip" || encoding.coding === "br") {
|
|
desiredEncoding = encoding.coding;
|
|
break;
|
|
} else if (encoding.coding === "identity")
|
|
break;
|
|
return desiredEncoding === void 0 ? identityDisallowed ? new Response("Unsupported Media Type", {
|
|
status: 415,
|
|
headers: { "Accept-Encoding": "br, gzip" }
|
|
}) : (contentEncoding === null || (response = new Response(response.body, response), response.headers.delete("Content-Encoding")), response) : (contentEncoding === desiredEncoding || (response = new Response(response.body, response), response.headers.set("Content-Encoding", desiredEncoding)), response);
|
|
}
|
|
function colourFromHTTPStatus(status) {
|
|
return 200 <= status && status < 300 ? green : 400 <= status && status < 500 ? yellow : 500 <= status ? red : blue;
|
|
}
|
|
function maybeLogRequest(req, res, env, ctx, startTime) {
|
|
if (env[CoreBindings.JSON_LOG_LEVEL] < LogLevel.INFO)
|
|
return;
|
|
let url = new URL(req.url), statusText = (res.statusText.trim() || STATUS_CODES[res.status]) ?? "", lines = [
|
|
`${bold(req.method)} ${url.pathname} `,
|
|
colourFromHTTPStatus(res.status)(`${bold(res.status)} ${statusText} `),
|
|
grey(`(${Date.now() - startTime}ms)`)
|
|
], message = reset(lines.join(""));
|
|
ctx.waitUntil(
|
|
env[CoreBindings.SERVICE_LOOPBACK].fetch("http://localhost/core/log", {
|
|
method: "POST",
|
|
headers: { [SharedHeaders.LOG_LEVEL]: LogLevel.INFO.toString() },
|
|
body: message
|
|
})
|
|
);
|
|
}
|
|
function handleProxy(request, env) {
|
|
let ns = env[CoreBindings.DURABLE_OBJECT_NAMESPACE_PROXY], id = ns.idFromName("");
|
|
return ns.get(id).fetch(request);
|
|
}
|
|
async function handleScheduled(params, service) {
|
|
let time = params.get("time"), scheduledTime = time ? new Date(parseInt(time)) : void 0, cron = params.get("cron") ?? void 0, result = await service.scheduled({
|
|
scheduledTime,
|
|
cron
|
|
});
|
|
return new Response(result.outcome, {
|
|
status: result.outcome === "ok" ? 200 : 500
|
|
});
|
|
}
|
|
var entry_worker_default = {
|
|
async fetch(request, env, ctx) {
|
|
let startTime = Date.now(), clientIp = request.cf?.clientIp, clientCfBlobHeader = request.headers.get(CoreHeaders.CF_BLOB), cf = clientCfBlobHeader ? JSON.parse(clientCfBlobHeader) : {
|
|
...env[CoreBindings.JSON_CF_BLOB],
|
|
// Defaulting to empty string to preserve undefined `Accept-Encoding`
|
|
// through Wrangler's proxy worker.
|
|
clientAcceptEncoding: request.headers.get("Accept-Encoding") ?? ""
|
|
};
|
|
if (request = new Request(request, { cf }), request.headers.get(CoreHeaders.OP) !== null)
|
|
return handleProxy(request, env);
|
|
let disablePrettyErrorPage = request.headers.get(CoreHeaders.DISABLE_PRETTY_ERROR) !== null, clientAcceptEncoding = request.headers.get("Accept-Encoding");
|
|
try {
|
|
request = getUserRequest(request, env, clientIp);
|
|
} catch (e) {
|
|
if (e instanceof HttpError)
|
|
return e.toResponse();
|
|
throw e;
|
|
}
|
|
let url = new URL(request.url), service = getTargetService(request, url, env);
|
|
if (service === void 0)
|
|
return new Response("No entrypoint worker found", { status: 404 });
|
|
try {
|
|
if (url.pathname === "/cdn-cgi/mf/scheduled")
|
|
return await handleScheduled(url.searchParams, service);
|
|
let response = await service.fetch(request);
|
|
return disablePrettyErrorPage || (response = await maybePrettifyError(request, response, env)), response = maybeInjectLiveReload(response, env, ctx), response = ensureAcceptableEncoding(clientAcceptEncoding, response), maybeLogRequest(request, response, env, ctx, startTime), response;
|
|
} catch (e) {
|
|
return new Response(e?.stack ?? String(e), { status: 500 });
|
|
}
|
|
}
|
|
};
|
|
export {
|
|
ProxyServer,
|
|
entry_worker_default as default
|
|
};
|
|
//# sourceMappingURL=entry.worker.js.map
|