hono
Version:
Web framework built on Web Standards
264 lines (263 loc) • 8.01 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var context_exports = {};
__export(context_exports, {
Context: () => Context,
TEXT_PLAIN: () => TEXT_PLAIN
});
module.exports = __toCommonJS(context_exports);
var import_request = require("./request");
var import_html = require("./utils/html");
const TEXT_PLAIN = "text/plain; charset=UTF-8";
const setHeaders = (headers, map = {}) => {
Object.entries(map).forEach(([key, value]) => headers.set(key, value));
return headers;
};
class Context {
#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 import_request.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) {
this.#res.headers.delete("content-type");
for (const [k, v] of this.#res.headers.entries()) {
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 (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
});
};
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;
return typeof arg === "number" ? this.newResponse(text, arg, headers) : this.newResponse(text, arg);
};
json = (object, arg, headers) => {
const body = JSON.stringify(object);
this.#preparedHeaders ??= {};
this.#preparedHeaders["content-type"] = "application/json; charset=UTF-8";
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") {
if (!(html instanceof Promise)) {
html = html.toString();
}
if (html instanceof Promise) {
return html.then((html2) => (0, import_html.resolveCallback)(html2, import_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", location);
return this.newResponse(null, status ?? 302);
};
notFound = () => {
this.#notFoundHandler ??= () => new Response();
return this.#notFoundHandler(this);
};
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Context,
TEXT_PLAIN
});