UNPKG

blade

Version:
499 lines (494 loc) • 16.1 kB
import { n as resolveCallback, t as HtmlEscapedCallbackPhase } from "./html-BHm7adlz.js"; //#region ../../node_modules/hono/dist/utils/body.js var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => { const { all = false, dot = false } = options; const contentType = (request instanceof HonoRequest ? request.raw.headers : request.headers).get("Content-Type"); if (contentType?.startsWith("multipart/form-data") || contentType?.startsWith("application/x-www-form-urlencoded")) return parseFormData(request, { all, dot }); return {}; }; async function parseFormData(request, options) { const formData = await request.formData(); if (formData) return convertFormDataToBodyData(formData, options); return {}; } function convertFormDataToBodyData(formData, options) { const form = /* @__PURE__ */ Object.create(null); formData.forEach((value, key) => { if (!(options.all || key.endsWith("[]"))) form[key] = value; else handleParsingAllValues(form, key, value); }); if (options.dot) Object.entries(form).forEach(([key, value]) => { if (key.includes(".")) { handleParsingNestedValues(form, key, value); delete form[key]; } }); return form; } var handleParsingAllValues = (form, key, value) => { if (form[key] !== void 0) if (Array.isArray(form[key])) form[key].push(value); else form[key] = [form[key], value]; else form[key] = value; }; var handleParsingNestedValues = (form, key, value) => { let nestedForm = form; const keys = key.split("."); keys.forEach((key2, index) => { if (index === keys.length - 1) nestedForm[key2] = value; else { if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) nestedForm[key2] = /* @__PURE__ */ Object.create(null); nestedForm = nestedForm[key2]; } }); }; //#endregion //#region ../../node_modules/hono/dist/utils/url.js var splitPath = (path) => { const paths = path.split("/"); if (paths[0] === "") paths.shift(); return paths; }; var splitRoutingPath = (routePath) => { const { groups, path } = extractGroupsFromPath(routePath); return replaceGroupMarks(splitPath(path), groups); }; var extractGroupsFromPath = (path) => { const groups = []; path = path.replace(/\{[^}]+\}/g, (match, index) => { const mark = `@${index}`; groups.push([mark, match]); return mark; }); return { groups, path }; }; var replaceGroupMarks = (paths, groups) => { for (let i = groups.length - 1; i >= 0; i--) { const [mark] = groups[i]; for (let j = paths.length - 1; j >= 0; j--) if (paths[j].includes(mark)) { paths[j] = paths[j].replace(mark, groups[i][1]); break; } } return paths; }; var patternCache = {}; var getPattern = (label, next) => { if (label === "*") return "*"; const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/); if (match) { const cacheKey = `${label}#${next}`; if (!patternCache[cacheKey]) if (match[2]) patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [ cacheKey, match[1], /* @__PURE__ */ new RegExp(`^${match[2]}(?=/${next})`) ] : [ label, match[1], /* @__PURE__ */ new RegExp(`^${match[2]}$`) ]; else patternCache[cacheKey] = [ label, match[1], true ]; return patternCache[cacheKey]; } return null; }; var tryDecode = (str, decoder) => { try { return decoder(str); } catch { return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => { try { return decoder(match); } catch { return match; } }); } }; var tryDecodeURI = (str) => tryDecode(str, decodeURI); var getPath = (request) => { const url = request.url; const start = url.indexOf("/", 8); let i = start; for (; i < url.length; i++) { const charCode = url.charCodeAt(i); if (charCode === 37) { const queryIndex = url.indexOf("?", i); const path = url.slice(start, queryIndex === -1 ? void 0 : queryIndex); return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path); } else if (charCode === 63) break; } return url.slice(start, i); }; var getPathNoStrict = (request) => { const result = getPath(request); return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result; }; var mergePath = (base, sub, ...rest) => { if (rest.length) sub = mergePath(sub, ...rest); return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`; }; var checkOptionalParameter = (path) => { if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) return null; const segments = path.split("/"); const results = []; let basePath = ""; segments.forEach((segment) => { if (segment !== "" && !/\:/.test(segment)) basePath += "/" + segment; else if (/\:/.test(segment)) if (/\?/.test(segment)) { if (results.length === 0 && basePath === "") results.push("/"); else results.push(basePath); const optionalSegment = segment.replace("?", ""); basePath += "/" + optionalSegment; results.push(basePath); } else basePath += "/" + segment; }); return results.filter((v, i, a) => a.indexOf(v) === i); }; var _decodeURI = (value) => { if (!/[%+]/.test(value)) return value; if (value.indexOf("+") !== -1) value = value.replace(/\+/g, " "); return value.indexOf("%") !== -1 ? decodeURIComponent_(value) : value; }; var _getQueryParam = (url, key, multiple) => { let encoded; if (!multiple && key && !/[%+]/.test(key)) { let keyIndex2 = url.indexOf(`?${key}`, 8); if (keyIndex2 === -1) keyIndex2 = url.indexOf(`&${key}`, 8); while (keyIndex2 !== -1) { const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1); if (trailingKeyCode === 61) { const valueIndex = keyIndex2 + key.length + 2; const endIndex = url.indexOf("&", valueIndex); return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex)); } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) return ""; keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1); } encoded = /[%+]/.test(url); if (!encoded) return; } const results = {}; encoded ??= /[%+]/.test(url); let keyIndex = url.indexOf("?", 8); while (keyIndex !== -1) { const nextKeyIndex = url.indexOf("&", keyIndex + 1); let valueIndex = url.indexOf("=", keyIndex); if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) valueIndex = -1; let name = url.slice(keyIndex + 1, valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex); if (encoded) name = _decodeURI(name); keyIndex = nextKeyIndex; if (name === "") continue; let value; if (valueIndex === -1) value = ""; else { value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex); if (encoded) value = _decodeURI(value); } if (multiple) { if (!(results[name] && Array.isArray(results[name]))) results[name] = []; results[name].push(value); } else results[name] ??= value; } return key ? results[key] : results; }; var getQueryParam = _getQueryParam; var getQueryParams = (url, key) => { return _getQueryParam(url, key, true); }; var decodeURIComponent_ = decodeURIComponent; //#endregion //#region ../../node_modules/hono/dist/request.js var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_); var HonoRequest = class { raw; #validatedData; #matchResult; routeIndex = 0; path; bodyCache = {}; constructor(request, path = "/", matchResult = [[]]) { this.raw = request; this.path = path; this.#matchResult = matchResult; this.#validatedData = {}; } param(key) { return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams(); } #getDecodedParam(key) { const paramKey = this.#matchResult[0][this.routeIndex][1][key]; const param = this.#getParamValue(paramKey); return param ? /\%/.test(param) ? tryDecodeURIComponent(param) : param : void 0; } #getAllDecodedParams() { const decoded = {}; const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]); for (const key of keys) { const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]); if (value && typeof value === "string") decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value; } return decoded; } #getParamValue(paramKey) { return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey; } query(key) { return getQueryParam(this.url, key); } queries(key) { return getQueryParams(this.url, key); } header(name) { if (name) return this.raw.headers.get(name) ?? void 0; const headerData = {}; this.raw.headers.forEach((value, key) => { headerData[key] = value; }); return headerData; } async parseBody(options) { return this.bodyCache.parsedBody ??= await parseBody(this, options); } #cachedBody = (key) => { const { bodyCache, raw } = this; const cachedBody = bodyCache[key]; if (cachedBody) return cachedBody; const anyCachedKey = Object.keys(bodyCache)[0]; if (anyCachedKey) return bodyCache[anyCachedKey].then((body) => { if (anyCachedKey === "json") body = JSON.stringify(body); return new Response(body)[key](); }); return bodyCache[key] = raw[key](); }; json() { return this.#cachedBody("json"); } text() { return this.#cachedBody("text"); } arrayBuffer() { return this.#cachedBody("arrayBuffer"); } blob() { return this.#cachedBody("blob"); } formData() { return this.#cachedBody("formData"); } addValidatedData(target, data) { this.#validatedData[target] = data; } valid(target) { return this.#validatedData[target]; } get url() { return this.raw.url; } get method() { return this.raw.method; } get matchedRoutes() { return this.#matchResult[0].map(([[, route]]) => route); } get routePath() { return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path; } }; //#endregion //#region ../../node_modules/hono/dist/context.js var TEXT_PLAIN = "text/plain; charset=UTF-8"; var setHeaders = (headers, map = {}) => { for (const key of Object.keys(map)) headers.set(key, map[key]); return headers; }; var Context = class { #rawRequest; #req; env = {}; #var; finalized = false; error; #status = 200; #executionCtx; #headers; #preparedHeaders; #res; #isFresh = true; #layout; #renderer; #notFoundHandler; #matchResult; #path; constructor(req, options) { this.#rawRequest = req; if (options) { this.#executionCtx = options.executionCtx; this.env = options.env; this.#notFoundHandler = options.notFoundHandler; this.#path = options.path; this.#matchResult = options.matchResult; } } get req() { this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult); return this.#req; } get event() { if (this.#executionCtx && "respondWith" in this.#executionCtx) return this.#executionCtx; else throw Error("This context has no FetchEvent"); } get executionCtx() { if (this.#executionCtx) return this.#executionCtx; else throw Error("This context has no ExecutionContext"); } get res() { this.#isFresh = false; return this.#res ||= new Response("404 Not Found", { status: 404 }); } set res(_res) { this.#isFresh = false; if (this.#res && _res) { _res = new Response(_res.body, _res); for (const [k, v] of this.#res.headers.entries()) { if (k === "content-type") continue; if (k === "set-cookie") { const cookies = this.#res.headers.getSetCookie(); _res.headers.delete("set-cookie"); for (const cookie of cookies) _res.headers.append("set-cookie", cookie); } else _res.headers.set(k, v); } } this.#res = _res; this.finalized = true; } render = (...args) => { this.#renderer ??= (content) => this.html(content); return this.#renderer(...args); }; setLayout = (layout) => this.#layout = layout; getLayout = () => this.#layout; setRenderer = (renderer) => { this.#renderer = renderer; }; header = (name, value, options) => { if (this.finalized) this.#res = new Response(this.#res.body, this.#res); if (value === void 0) { if (this.#headers) this.#headers.delete(name); else if (this.#preparedHeaders) delete this.#preparedHeaders[name.toLocaleLowerCase()]; if (this.finalized) this.res.headers.delete(name); return; } if (options?.append) { if (!this.#headers) { this.#isFresh = false; this.#headers = new Headers(this.#preparedHeaders); this.#preparedHeaders = {}; } this.#headers.append(name, value); } else if (this.#headers) this.#headers.set(name, value); else { this.#preparedHeaders ??= {}; this.#preparedHeaders[name.toLowerCase()] = value; } if (this.finalized) if (options?.append) this.res.headers.append(name, value); else this.res.headers.set(name, value); }; status = (status) => { this.#isFresh = false; this.#status = status; }; set = (key, value) => { this.#var ??= /* @__PURE__ */ new Map(); this.#var.set(key, value); }; get = (key) => { return this.#var ? this.#var.get(key) : void 0; }; get var() { if (!this.#var) return {}; return Object.fromEntries(this.#var); } #newResponse(data, arg, headers) { if (this.#isFresh && !headers && !arg && this.#status === 200) return new Response(data, { headers: this.#preparedHeaders }); if (arg && typeof arg !== "number") { const header = new Headers(arg.headers); if (this.#headers) this.#headers.forEach((v, k) => { if (k === "set-cookie") header.append(k, v); else header.set(k, v); }); const headers2 = setHeaders(header, this.#preparedHeaders); return new Response(data, { headers: headers2, status: arg.status ?? this.#status }); } const status = typeof arg === "number" ? arg : this.#status; this.#preparedHeaders ??= {}; this.#headers ??= new Headers(); setHeaders(this.#headers, this.#preparedHeaders); if (this.#res) { this.#res.headers.forEach((v, k) => { if (k === "set-cookie") this.#headers?.append(k, v); else this.#headers?.set(k, v); }); setHeaders(this.#headers, this.#preparedHeaders); } headers ??= {}; for (const [k, v] of Object.entries(headers)) if (typeof v === "string") this.#headers.set(k, v); else { this.#headers.delete(k); for (const v2 of v) this.#headers.append(k, v2); } return new Response(data, { status, headers: this.#headers }); } newResponse = (...args) => this.#newResponse(...args); body = (data, arg, headers) => { return typeof arg === "number" ? this.#newResponse(data, arg, headers) : this.#newResponse(data, arg); }; text = (text, arg, headers) => { if (!this.#preparedHeaders) { if (this.#isFresh && !headers && !arg) return new Response(text); this.#preparedHeaders = {}; } this.#preparedHeaders["content-type"] = TEXT_PLAIN; if (typeof arg === "number") return this.#newResponse(text, arg, headers); return this.#newResponse(text, arg); }; json = (object, arg, headers) => { const body = JSON.stringify(object); this.#preparedHeaders ??= {}; this.#preparedHeaders["content-type"] = "application/json"; return typeof arg === "number" ? this.#newResponse(body, arg, headers) : this.#newResponse(body, arg); }; html = (html, arg, headers) => { this.#preparedHeaders ??= {}; this.#preparedHeaders["content-type"] = "text/html; charset=UTF-8"; if (typeof html === "object") return resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then((html2) => { return typeof arg === "number" ? this.#newResponse(html2, arg, headers) : this.#newResponse(html2, arg); }); return typeof arg === "number" ? this.#newResponse(html, arg, headers) : this.#newResponse(html, arg); }; redirect = (location, status) => { this.#headers ??= new Headers(); this.#headers.set("Location", String(location)); return this.newResponse(null, status ?? 302); }; notFound = () => { this.#notFoundHandler ??= () => new Response(); return this.#notFoundHandler(this); }; }; //#endregion export { getPathNoStrict as a, splitPath as c, getPath as i, splitRoutingPath as l, checkOptionalParameter as n, getPattern as o, decodeURIComponent_ as r, mergePath as s, Context as t };