Aktueller Stand
This commit is contained in:
60
backend/node_modules/hono/dist/middleware/basic-auth/index.js
generated
vendored
Normal file
60
backend/node_modules/hono/dist/middleware/basic-auth/index.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// src/middleware/basic-auth/index.ts
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
import { auth } from "../../utils/basic-auth.js";
|
||||
import { timingSafeEqual } from "../../utils/buffer.js";
|
||||
var basicAuth = (options, ...users) => {
|
||||
const usernamePasswordInOptions = "username" in options && "password" in options;
|
||||
const verifyUserInOptions = "verifyUser" in options;
|
||||
if (!(usernamePasswordInOptions || verifyUserInOptions)) {
|
||||
throw new Error(
|
||||
'basic auth middleware requires options for "username and password" or "verifyUser"'
|
||||
);
|
||||
}
|
||||
if (!options.realm) {
|
||||
options.realm = "Secure Area";
|
||||
}
|
||||
if (!options.invalidUserMessage) {
|
||||
options.invalidUserMessage = "Unauthorized";
|
||||
}
|
||||
if (usernamePasswordInOptions) {
|
||||
users.unshift({ username: options.username, password: options.password });
|
||||
}
|
||||
return async function basicAuth2(ctx, next) {
|
||||
const requestUser = auth(ctx.req.raw);
|
||||
if (requestUser) {
|
||||
if (verifyUserInOptions) {
|
||||
if (await options.verifyUser(requestUser.username, requestUser.password, ctx)) {
|
||||
await next();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
for (const user of users) {
|
||||
const [usernameEqual, passwordEqual] = await Promise.all([
|
||||
timingSafeEqual(user.username, requestUser.username, options.hashFunction),
|
||||
timingSafeEqual(user.password, requestUser.password, options.hashFunction)
|
||||
]);
|
||||
if (usernameEqual && passwordEqual) {
|
||||
await next();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const status = 401;
|
||||
const headers = {
|
||||
"WWW-Authenticate": 'Basic realm="' + options.realm?.replace(/"/g, '\\"') + '"'
|
||||
};
|
||||
const responseMessage = typeof options.invalidUserMessage === "function" ? await options.invalidUserMessage(ctx) : options.invalidUserMessage;
|
||||
const res = typeof responseMessage === "string" ? new Response(responseMessage, { status, headers }) : new Response(JSON.stringify(responseMessage), {
|
||||
status,
|
||||
headers: {
|
||||
...headers,
|
||||
"content-type": "application/json"
|
||||
}
|
||||
});
|
||||
throw new HTTPException(status, { res });
|
||||
};
|
||||
};
|
||||
export {
|
||||
basicAuth
|
||||
};
|
||||
83
backend/node_modules/hono/dist/middleware/bearer-auth/index.js
generated
vendored
Normal file
83
backend/node_modules/hono/dist/middleware/bearer-auth/index.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// src/middleware/bearer-auth/index.ts
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
import { timingSafeEqual } from "../../utils/buffer.js";
|
||||
var TOKEN_STRINGS = "[A-Za-z0-9._~+/-]+=*";
|
||||
var PREFIX = "Bearer";
|
||||
var HEADER = "Authorization";
|
||||
var bearerAuth = (options) => {
|
||||
if (!("token" in options || "verifyToken" in options)) {
|
||||
throw new Error('bearer auth middleware requires options for "token"');
|
||||
}
|
||||
if (!options.realm) {
|
||||
options.realm = "";
|
||||
}
|
||||
if (options.prefix === void 0) {
|
||||
options.prefix = PREFIX;
|
||||
}
|
||||
const realm = options.realm?.replace(/"/g, '\\"');
|
||||
const prefixRegexStr = options.prefix === "" ? "" : `${options.prefix} +`;
|
||||
const regexp = new RegExp(`^${prefixRegexStr}(${TOKEN_STRINGS}) *$`);
|
||||
const wwwAuthenticatePrefix = options.prefix === "" ? "" : `${options.prefix} `;
|
||||
const throwHTTPException = async (c, status, wwwAuthenticateHeader, messageOption) => {
|
||||
const wwwAuthenticateHeaderValue = typeof wwwAuthenticateHeader === "function" ? await wwwAuthenticateHeader(c) : wwwAuthenticateHeader;
|
||||
const headers = {
|
||||
"WWW-Authenticate": typeof wwwAuthenticateHeaderValue === "string" ? wwwAuthenticateHeaderValue : `${wwwAuthenticatePrefix}${Object.entries(wwwAuthenticateHeaderValue).map(([key, value]) => `${key}="${value}"`).join(",")}`
|
||||
};
|
||||
const responseMessage = typeof messageOption === "function" ? await messageOption(c) : messageOption;
|
||||
const res = typeof responseMessage === "string" ? new Response(responseMessage, { status, headers }) : new Response(JSON.stringify(responseMessage), {
|
||||
status,
|
||||
headers: {
|
||||
...headers,
|
||||
"content-type": "application/json"
|
||||
}
|
||||
});
|
||||
throw new HTTPException(status, { res });
|
||||
};
|
||||
return async function bearerAuth2(c, next) {
|
||||
const headerToken = c.req.header(options.headerName || HEADER);
|
||||
if (!headerToken) {
|
||||
await throwHTTPException(
|
||||
c,
|
||||
401,
|
||||
options.noAuthenticationHeader?.wwwAuthenticateHeader || `${wwwAuthenticatePrefix}realm="${realm}"`,
|
||||
options.noAuthenticationHeader?.message || options.noAuthenticationHeaderMessage || "Unauthorized"
|
||||
);
|
||||
} else {
|
||||
const match = regexp.exec(headerToken);
|
||||
if (!match) {
|
||||
await throwHTTPException(
|
||||
c,
|
||||
400,
|
||||
options.invalidAuthenticationHeader?.wwwAuthenticateHeader || `${wwwAuthenticatePrefix}error="invalid_request"`,
|
||||
options.invalidAuthenticationHeader?.message || options.invalidAuthenticationHeaderMessage || "Bad Request"
|
||||
);
|
||||
} else {
|
||||
let equal = false;
|
||||
if ("verifyToken" in options) {
|
||||
equal = await options.verifyToken(match[1], c);
|
||||
} else if (typeof options.token === "string") {
|
||||
equal = await timingSafeEqual(options.token, match[1], options.hashFunction);
|
||||
} else if (Array.isArray(options.token) && options.token.length > 0) {
|
||||
for (const token of options.token) {
|
||||
if (await timingSafeEqual(token, match[1], options.hashFunction)) {
|
||||
equal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!equal) {
|
||||
await throwHTTPException(
|
||||
c,
|
||||
401,
|
||||
options.invalidToken?.wwwAuthenticateHeader || `${wwwAuthenticatePrefix}error="invalid_token"`,
|
||||
options.invalidToken?.message || options.invalidTokenMessage || "Unauthorized"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
await next();
|
||||
};
|
||||
};
|
||||
export {
|
||||
bearerAuth
|
||||
};
|
||||
62
backend/node_modules/hono/dist/middleware/body-limit/index.js
generated
vendored
Normal file
62
backend/node_modules/hono/dist/middleware/body-limit/index.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// src/middleware/body-limit/index.ts
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
var ERROR_MESSAGE = "Payload Too Large";
|
||||
var BodyLimitError = class extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "BodyLimitError";
|
||||
}
|
||||
};
|
||||
var bodyLimit = (options) => {
|
||||
const onError = options.onError || (() => {
|
||||
const res = new Response(ERROR_MESSAGE, {
|
||||
status: 413
|
||||
});
|
||||
throw new HTTPException(413, { res });
|
||||
});
|
||||
const maxSize = options.maxSize;
|
||||
return async function bodyLimit2(c, next) {
|
||||
if (!c.req.raw.body) {
|
||||
return next();
|
||||
}
|
||||
const hasTransferEncoding = c.req.raw.headers.has("transfer-encoding");
|
||||
const hasContentLength = c.req.raw.headers.has("content-length");
|
||||
if (hasTransferEncoding && hasContentLength) {
|
||||
}
|
||||
if (hasContentLength && !hasTransferEncoding) {
|
||||
const contentLength = parseInt(c.req.raw.headers.get("content-length") || "0", 10);
|
||||
return contentLength > maxSize ? onError(c) : next();
|
||||
}
|
||||
let size = 0;
|
||||
const rawReader = c.req.raw.body.getReader();
|
||||
const reader = new ReadableStream({
|
||||
async start(controller) {
|
||||
try {
|
||||
for (; ; ) {
|
||||
const { done, value } = await rawReader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
size += value.length;
|
||||
if (size > maxSize) {
|
||||
controller.error(new BodyLimitError(ERROR_MESSAGE));
|
||||
break;
|
||||
}
|
||||
controller.enqueue(value);
|
||||
}
|
||||
} finally {
|
||||
controller.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
const requestInit = { body: reader, duplex: "half" };
|
||||
c.req.raw = new Request(c.req.raw, requestInit);
|
||||
await next();
|
||||
if (c.error instanceof BodyLimitError) {
|
||||
c.res = await onError(c);
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
bodyLimit
|
||||
};
|
||||
79
backend/node_modules/hono/dist/middleware/cache/index.js
generated
vendored
Normal file
79
backend/node_modules/hono/dist/middleware/cache/index.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// src/middleware/cache/index.ts
|
||||
var defaultCacheableStatusCodes = [200];
|
||||
var shouldSkipCache = (res) => {
|
||||
const vary = res.headers.get("Vary");
|
||||
return vary && vary.includes("*");
|
||||
};
|
||||
var cache = (options) => {
|
||||
if (!globalThis.caches) {
|
||||
console.log("Cache Middleware is not enabled because caches is not defined.");
|
||||
return async (_c, next) => await next();
|
||||
}
|
||||
if (options.wait === void 0) {
|
||||
options.wait = false;
|
||||
}
|
||||
const cacheControlDirectives = options.cacheControl?.split(",").map((directive) => directive.toLowerCase());
|
||||
const varyDirectives = Array.isArray(options.vary) ? options.vary : options.vary?.split(",").map((directive) => directive.trim());
|
||||
if (options.vary?.includes("*")) {
|
||||
throw new Error(
|
||||
'Middleware vary configuration cannot include "*", as it disallows effective caching.'
|
||||
);
|
||||
}
|
||||
const cacheableStatusCodes = new Set(
|
||||
options.cacheableStatusCodes ?? defaultCacheableStatusCodes
|
||||
);
|
||||
const addHeader = (c) => {
|
||||
if (cacheControlDirectives) {
|
||||
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0]) ?? [];
|
||||
for (const directive of cacheControlDirectives) {
|
||||
let [name, value] = directive.trim().split("=", 2);
|
||||
name = name.toLowerCase();
|
||||
if (!existingDirectives.includes(name)) {
|
||||
c.header("Cache-Control", `${name}${value ? `=${value}` : ""}`, { append: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (varyDirectives) {
|
||||
const existingDirectives = c.res.headers.get("Vary")?.split(",").map((d) => d.trim()) ?? [];
|
||||
const vary = Array.from(
|
||||
new Set(
|
||||
[...existingDirectives, ...varyDirectives].map((directive) => directive.toLowerCase())
|
||||
)
|
||||
).sort();
|
||||
if (vary.includes("*")) {
|
||||
c.header("Vary", "*");
|
||||
} else {
|
||||
c.header("Vary", vary.join(", "));
|
||||
}
|
||||
}
|
||||
};
|
||||
return async function cache2(c, next) {
|
||||
let key = c.req.url;
|
||||
if (options.keyGenerator) {
|
||||
key = await options.keyGenerator(c);
|
||||
}
|
||||
const cacheName = typeof options.cacheName === "function" ? await options.cacheName(c) : options.cacheName;
|
||||
const cache3 = await caches.open(cacheName);
|
||||
const response = await cache3.match(key);
|
||||
if (response) {
|
||||
return new Response(response.body, response);
|
||||
}
|
||||
await next();
|
||||
if (!cacheableStatusCodes.has(c.res.status)) {
|
||||
return;
|
||||
}
|
||||
addHeader(c);
|
||||
if (shouldSkipCache(c.res)) {
|
||||
return;
|
||||
}
|
||||
const res = c.res.clone();
|
||||
if (options.wait) {
|
||||
await cache3.put(key, res);
|
||||
} else {
|
||||
c.executionCtx.waitUntil(cache3.put(key, res));
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
cache
|
||||
};
|
||||
77
backend/node_modules/hono/dist/middleware/combine/index.js
generated
vendored
Normal file
77
backend/node_modules/hono/dist/middleware/combine/index.js
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// src/middleware/combine/index.ts
|
||||
import { compose } from "../../compose.js";
|
||||
import { METHOD_NAME_ALL } from "../../router.js";
|
||||
import { TrieRouter } from "../../router/trie-router/index.js";
|
||||
var some = (...middleware) => {
|
||||
return async function some2(c, next) {
|
||||
let isNextCalled = false;
|
||||
const wrappedNext = () => {
|
||||
isNextCalled = true;
|
||||
return next();
|
||||
};
|
||||
let lastError;
|
||||
for (const handler of middleware) {
|
||||
try {
|
||||
const result = await handler(c, wrappedNext);
|
||||
if (result === true && !c.finalized) {
|
||||
await wrappedNext();
|
||||
} else if (result === false) {
|
||||
lastError = new Error("No successful middleware found");
|
||||
continue;
|
||||
}
|
||||
lastError = void 0;
|
||||
break;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
if (isNextCalled) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastError) {
|
||||
throw lastError;
|
||||
}
|
||||
};
|
||||
};
|
||||
var every = (...middleware) => {
|
||||
return async function every2(c, next) {
|
||||
const currentRouteIndex = c.req.routeIndex;
|
||||
await compose(
|
||||
middleware.map((m) => [
|
||||
[
|
||||
async (c2, next2) => {
|
||||
c2.req.routeIndex = currentRouteIndex;
|
||||
const res = await m(c2, next2);
|
||||
if (res === false) {
|
||||
throw new Error("Unmet condition");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
]
|
||||
])
|
||||
)(c, next);
|
||||
};
|
||||
};
|
||||
var except = (condition, ...middleware) => {
|
||||
let router = void 0;
|
||||
const conditions = (Array.isArray(condition) ? condition : [condition]).map((condition2) => {
|
||||
if (typeof condition2 === "string") {
|
||||
router ||= new TrieRouter();
|
||||
router.add(METHOD_NAME_ALL, condition2, true);
|
||||
} else {
|
||||
return condition2;
|
||||
}
|
||||
}).filter(Boolean);
|
||||
if (router) {
|
||||
conditions.unshift((c) => !!router?.match(METHOD_NAME_ALL, c.req.path)?.[0]?.[0]?.[0]);
|
||||
}
|
||||
const handler = some((c) => conditions.some((cond) => cond(c)), every(...middleware));
|
||||
return async function except2(c, next) {
|
||||
await handler(c, next);
|
||||
};
|
||||
};
|
||||
export {
|
||||
every,
|
||||
except,
|
||||
some
|
||||
};
|
||||
39
backend/node_modules/hono/dist/middleware/compress/index.js
generated
vendored
Normal file
39
backend/node_modules/hono/dist/middleware/compress/index.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// src/middleware/compress/index.ts
|
||||
import { COMPRESSIBLE_CONTENT_TYPE_REGEX } from "../../utils/compress.js";
|
||||
var ENCODING_TYPES = ["gzip", "deflate"];
|
||||
var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/i;
|
||||
var compress = (options) => {
|
||||
const threshold = options?.threshold ?? 1024;
|
||||
return async function compress2(ctx, next) {
|
||||
await next();
|
||||
const contentLength = ctx.res.headers.get("Content-Length");
|
||||
if (ctx.res.headers.has("Content-Encoding") || // already encoded
|
||||
ctx.res.headers.has("Transfer-Encoding") || // already encoded or chunked
|
||||
ctx.req.method === "HEAD" || // HEAD request
|
||||
contentLength && Number(contentLength) < threshold || // content-length below threshold
|
||||
!shouldCompress(ctx.res) || // not compressible type
|
||||
!shouldTransform(ctx.res)) {
|
||||
return;
|
||||
}
|
||||
const accepted = ctx.req.header("Accept-Encoding");
|
||||
const encoding = options?.encoding ?? ENCODING_TYPES.find((encoding2) => accepted?.includes(encoding2));
|
||||
if (!encoding || !ctx.res.body) {
|
||||
return;
|
||||
}
|
||||
const stream = new CompressionStream(encoding);
|
||||
ctx.res = new Response(ctx.res.body.pipeThrough(stream), ctx.res);
|
||||
ctx.res.headers.delete("Content-Length");
|
||||
ctx.res.headers.set("Content-Encoding", encoding);
|
||||
};
|
||||
};
|
||||
var shouldCompress = (res) => {
|
||||
const type = res.headers.get("Content-Type");
|
||||
return type && COMPRESSIBLE_CONTENT_TYPE_REGEX.test(type);
|
||||
};
|
||||
var shouldTransform = (res) => {
|
||||
const cacheControl = res.headers.get("Cache-Control");
|
||||
return !cacheControl || !cacheControlNoTransformRegExp.test(cacheControl);
|
||||
};
|
||||
export {
|
||||
compress
|
||||
};
|
||||
23
backend/node_modules/hono/dist/middleware/context-storage/index.js
generated
vendored
Normal file
23
backend/node_modules/hono/dist/middleware/context-storage/index.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// src/middleware/context-storage/index.ts
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
var asyncLocalStorage = new AsyncLocalStorage();
|
||||
var contextStorage = () => {
|
||||
return async function contextStorage2(c, next) {
|
||||
await asyncLocalStorage.run(c, next);
|
||||
};
|
||||
};
|
||||
var tryGetContext = () => {
|
||||
return asyncLocalStorage.getStore();
|
||||
};
|
||||
var getContext = () => {
|
||||
const context = tryGetContext();
|
||||
if (!context) {
|
||||
throw new Error("Context is not available");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
export {
|
||||
contextStorage,
|
||||
getContext,
|
||||
tryGetContext
|
||||
};
|
||||
87
backend/node_modules/hono/dist/middleware/cors/index.js
generated
vendored
Normal file
87
backend/node_modules/hono/dist/middleware/cors/index.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
// src/middleware/cors/index.ts
|
||||
var cors = (options) => {
|
||||
const defaults = {
|
||||
origin: "*",
|
||||
allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
|
||||
allowHeaders: [],
|
||||
exposeHeaders: []
|
||||
};
|
||||
const opts = {
|
||||
...defaults,
|
||||
...options
|
||||
};
|
||||
const findAllowOrigin = ((optsOrigin) => {
|
||||
if (typeof optsOrigin === "string") {
|
||||
if (optsOrigin === "*") {
|
||||
return () => optsOrigin;
|
||||
} else {
|
||||
return (origin) => optsOrigin === origin ? origin : null;
|
||||
}
|
||||
} else if (typeof optsOrigin === "function") {
|
||||
return optsOrigin;
|
||||
} else {
|
||||
return (origin) => optsOrigin.includes(origin) ? origin : null;
|
||||
}
|
||||
})(opts.origin);
|
||||
const findAllowMethods = ((optsAllowMethods) => {
|
||||
if (typeof optsAllowMethods === "function") {
|
||||
return optsAllowMethods;
|
||||
} else if (Array.isArray(optsAllowMethods)) {
|
||||
return () => optsAllowMethods;
|
||||
} else {
|
||||
return () => [];
|
||||
}
|
||||
})(opts.allowMethods);
|
||||
return async function cors2(c, next) {
|
||||
function set(key, value) {
|
||||
c.res.headers.set(key, value);
|
||||
}
|
||||
const allowOrigin = await findAllowOrigin(c.req.header("origin") || "", c);
|
||||
if (allowOrigin) {
|
||||
set("Access-Control-Allow-Origin", allowOrigin);
|
||||
}
|
||||
if (opts.credentials) {
|
||||
set("Access-Control-Allow-Credentials", "true");
|
||||
}
|
||||
if (opts.exposeHeaders?.length) {
|
||||
set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
|
||||
}
|
||||
if (c.req.method === "OPTIONS") {
|
||||
if (opts.origin !== "*") {
|
||||
set("Vary", "Origin");
|
||||
}
|
||||
if (opts.maxAge != null) {
|
||||
set("Access-Control-Max-Age", opts.maxAge.toString());
|
||||
}
|
||||
const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
|
||||
if (allowMethods.length) {
|
||||
set("Access-Control-Allow-Methods", allowMethods.join(","));
|
||||
}
|
||||
let headers = opts.allowHeaders;
|
||||
if (!headers?.length) {
|
||||
const requestHeaders = c.req.header("Access-Control-Request-Headers");
|
||||
if (requestHeaders) {
|
||||
headers = requestHeaders.split(/\s*,\s*/);
|
||||
}
|
||||
}
|
||||
if (headers?.length) {
|
||||
set("Access-Control-Allow-Headers", headers.join(","));
|
||||
c.res.headers.append("Vary", "Access-Control-Request-Headers");
|
||||
}
|
||||
c.res.headers.delete("Content-Length");
|
||||
c.res.headers.delete("Content-Type");
|
||||
return new Response(null, {
|
||||
headers: c.res.headers,
|
||||
status: 204,
|
||||
statusText: "No Content"
|
||||
});
|
||||
}
|
||||
await next();
|
||||
if (opts.origin !== "*") {
|
||||
c.header("Vary", "Origin", { append: true });
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
cors
|
||||
};
|
||||
55
backend/node_modules/hono/dist/middleware/csrf/index.js
generated
vendored
Normal file
55
backend/node_modules/hono/dist/middleware/csrf/index.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// src/middleware/csrf/index.ts
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
var secFetchSiteValues = ["same-origin", "same-site", "none", "cross-site"];
|
||||
var isSecFetchSite = (value) => secFetchSiteValues.includes(value);
|
||||
var isSafeMethodRe = /^(GET|HEAD)$/;
|
||||
var isRequestedByFormElementRe = /^\b(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)\b/i;
|
||||
var csrf = (options) => {
|
||||
const originHandler = ((optsOrigin) => {
|
||||
if (!optsOrigin) {
|
||||
return (origin, c) => origin === new URL(c.req.url).origin;
|
||||
} else if (typeof optsOrigin === "string") {
|
||||
return (origin) => origin === optsOrigin;
|
||||
} else if (typeof optsOrigin === "function") {
|
||||
return optsOrigin;
|
||||
} else {
|
||||
return (origin) => optsOrigin.includes(origin);
|
||||
}
|
||||
})(options?.origin);
|
||||
const isAllowedOrigin = async (origin, c) => {
|
||||
if (origin === void 0) {
|
||||
return false;
|
||||
}
|
||||
return await originHandler(origin, c);
|
||||
};
|
||||
const secFetchSiteHandler = ((optsSecFetchSite) => {
|
||||
if (!optsSecFetchSite) {
|
||||
return (secFetchSite) => secFetchSite === "same-origin";
|
||||
} else if (typeof optsSecFetchSite === "string") {
|
||||
return (secFetchSite) => secFetchSite === optsSecFetchSite;
|
||||
} else if (typeof optsSecFetchSite === "function") {
|
||||
return optsSecFetchSite;
|
||||
} else {
|
||||
return (secFetchSite) => optsSecFetchSite.includes(secFetchSite);
|
||||
}
|
||||
})(options?.secFetchSite);
|
||||
const isAllowedSecFetchSite = async (secFetchSite, c) => {
|
||||
if (secFetchSite === void 0) {
|
||||
return false;
|
||||
}
|
||||
if (!isSecFetchSite(secFetchSite)) {
|
||||
return false;
|
||||
}
|
||||
return await secFetchSiteHandler(secFetchSite, c);
|
||||
};
|
||||
return async function csrf2(c, next) {
|
||||
if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "text/plain") && !await isAllowedSecFetchSite(c.req.header("sec-fetch-site"), c) && !await isAllowedOrigin(c.req.header("origin"), c)) {
|
||||
const res = new Response("Forbidden", { status: 403 });
|
||||
throw new HTTPException(403, { res });
|
||||
}
|
||||
await next();
|
||||
};
|
||||
};
|
||||
export {
|
||||
csrf
|
||||
};
|
||||
33
backend/node_modules/hono/dist/middleware/etag/digest.js
generated
vendored
Normal file
33
backend/node_modules/hono/dist/middleware/etag/digest.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// src/middleware/etag/digest.ts
|
||||
var mergeBuffers = (buffer1, buffer2) => {
|
||||
if (!buffer1) {
|
||||
return buffer2;
|
||||
}
|
||||
const merged = new Uint8Array(
|
||||
new ArrayBuffer(buffer1.byteLength + buffer2.byteLength)
|
||||
);
|
||||
merged.set(new Uint8Array(buffer1), 0);
|
||||
merged.set(buffer2, buffer1.byteLength);
|
||||
return merged;
|
||||
};
|
||||
var generateDigest = async (stream, generator) => {
|
||||
if (!stream) {
|
||||
return null;
|
||||
}
|
||||
let result = void 0;
|
||||
const reader = stream.getReader();
|
||||
for (; ; ) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
result = await generator(mergeBuffers(result, value));
|
||||
}
|
||||
if (!result) {
|
||||
return null;
|
||||
}
|
||||
return Array.prototype.map.call(new Uint8Array(result), (x) => x.toString(16).padStart(2, "0")).join("");
|
||||
};
|
||||
export {
|
||||
generateDigest
|
||||
};
|
||||
72
backend/node_modules/hono/dist/middleware/etag/index.js
generated
vendored
Normal file
72
backend/node_modules/hono/dist/middleware/etag/index.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// src/middleware/etag/index.ts
|
||||
import { generateDigest } from "./digest.js";
|
||||
var RETAINED_304_HEADERS = [
|
||||
"cache-control",
|
||||
"content-location",
|
||||
"date",
|
||||
"etag",
|
||||
"expires",
|
||||
"vary"
|
||||
];
|
||||
var stripWeak = (tag) => tag.replace(/^W\//, "");
|
||||
function etagMatches(etag2, ifNoneMatch) {
|
||||
return ifNoneMatch != null && ifNoneMatch.split(/,\s*/).some((t) => stripWeak(t) === stripWeak(etag2));
|
||||
}
|
||||
function initializeGenerator(generator) {
|
||||
if (!generator) {
|
||||
if (crypto && crypto.subtle) {
|
||||
generator = (body) => crypto.subtle.digest(
|
||||
{
|
||||
name: "SHA-1"
|
||||
},
|
||||
body
|
||||
);
|
||||
}
|
||||
}
|
||||
return generator;
|
||||
}
|
||||
var etag = (options) => {
|
||||
const retainedHeaders = options?.retainedHeaders ?? RETAINED_304_HEADERS;
|
||||
const weak = options?.weak ?? false;
|
||||
const generator = initializeGenerator(options?.generateDigest);
|
||||
return async function etag2(c, next) {
|
||||
const ifNoneMatch = c.req.header("If-None-Match") ?? null;
|
||||
await next();
|
||||
const res = c.res;
|
||||
let etag3 = res.headers.get("ETag");
|
||||
if (!etag3) {
|
||||
if (!generator) {
|
||||
return;
|
||||
}
|
||||
const hash = await generateDigest(
|
||||
// This type casing avoids the type error for `deno publish`
|
||||
res.clone().body,
|
||||
generator
|
||||
);
|
||||
if (hash === null) {
|
||||
return;
|
||||
}
|
||||
etag3 = weak ? `W/"${hash}"` : `"${hash}"`;
|
||||
}
|
||||
if (etagMatches(etag3, ifNoneMatch)) {
|
||||
c.res = new Response(null, {
|
||||
status: 304,
|
||||
statusText: "Not Modified",
|
||||
headers: {
|
||||
ETag: etag3
|
||||
}
|
||||
});
|
||||
c.res.headers.forEach((_, key) => {
|
||||
if (retainedHeaders.indexOf(key.toLowerCase()) === -1) {
|
||||
c.res.headers.delete(key);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
c.res.headers.set("ETag", etag3);
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
RETAINED_304_HEADERS,
|
||||
etag
|
||||
};
|
||||
107
backend/node_modules/hono/dist/middleware/ip-restriction/index.js
generated
vendored
Normal file
107
backend/node_modules/hono/dist/middleware/ip-restriction/index.js
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// src/middleware/ip-restriction/index.ts
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
import {
|
||||
convertIPv4ToBinary,
|
||||
convertIPv6BinaryToString,
|
||||
convertIPv6ToBinary,
|
||||
distinctRemoteAddr
|
||||
} from "../../utils/ipaddr.js";
|
||||
var IS_CIDR_NOTATION_REGEX = /\/[0-9]{0,3}$/;
|
||||
var buildMatcher = (rules) => {
|
||||
const functionRules = [];
|
||||
const staticRules = /* @__PURE__ */ new Set();
|
||||
const cidrRules = [];
|
||||
for (let rule of rules) {
|
||||
if (rule === "*") {
|
||||
return () => true;
|
||||
} else if (typeof rule === "function") {
|
||||
functionRules.push(rule);
|
||||
} else {
|
||||
if (IS_CIDR_NOTATION_REGEX.test(rule)) {
|
||||
const separatedRule = rule.split("/");
|
||||
const addrStr = separatedRule[0];
|
||||
const type2 = distinctRemoteAddr(addrStr);
|
||||
if (type2 === void 0) {
|
||||
throw new TypeError(`Invalid rule: ${rule}`);
|
||||
}
|
||||
const isIPv4 = type2 === "IPv4";
|
||||
const prefix = parseInt(separatedRule[1]);
|
||||
if (isIPv4 ? prefix === 32 : prefix === 128) {
|
||||
rule = addrStr;
|
||||
} else {
|
||||
const addr = (isIPv4 ? convertIPv4ToBinary : convertIPv6ToBinary)(addrStr);
|
||||
const mask = (1n << BigInt(prefix)) - 1n << BigInt((isIPv4 ? 32 : 128) - prefix);
|
||||
cidrRules.push([isIPv4, addr & mask, mask]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const type = distinctRemoteAddr(rule);
|
||||
if (type === void 0) {
|
||||
throw new TypeError(`Invalid rule: ${rule}`);
|
||||
}
|
||||
staticRules.add(
|
||||
type === "IPv4" ? rule : convertIPv6BinaryToString(convertIPv6ToBinary(rule))
|
||||
// normalize IPv6 address (e.g. 0000:0000:0000:0000:0000:0000:0000:0001 => ::1)
|
||||
);
|
||||
}
|
||||
}
|
||||
return (remote) => {
|
||||
if (staticRules.has(remote.addr)) {
|
||||
return true;
|
||||
}
|
||||
for (const [isIPv4, addr, mask] of cidrRules) {
|
||||
if (isIPv4 !== remote.isIPv4) {
|
||||
continue;
|
||||
}
|
||||
const remoteAddr = remote.binaryAddr ||= (isIPv4 ? convertIPv4ToBinary : convertIPv6ToBinary)(remote.addr);
|
||||
if ((remoteAddr & mask) === addr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (const rule of functionRules) {
|
||||
if (rule({ addr: remote.addr, type: remote.type })) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
};
|
||||
var ipRestriction = (getIP, { denyList = [], allowList = [] }, onError) => {
|
||||
const allowLength = allowList.length;
|
||||
const denyMatcher = buildMatcher(denyList);
|
||||
const allowMatcher = buildMatcher(allowList);
|
||||
const blockError = (c) => new HTTPException(403, {
|
||||
res: c.text("Forbidden", {
|
||||
status: 403
|
||||
})
|
||||
});
|
||||
return async function ipRestriction2(c, next) {
|
||||
const connInfo = getIP(c);
|
||||
const addr = typeof connInfo === "string" ? connInfo : connInfo.remote.address;
|
||||
if (!addr) {
|
||||
throw blockError(c);
|
||||
}
|
||||
const type = typeof connInfo !== "string" && connInfo.remote.addressType || distinctRemoteAddr(addr);
|
||||
const remoteData = { addr, type, isIPv4: type === "IPv4" };
|
||||
if (denyMatcher(remoteData)) {
|
||||
if (onError) {
|
||||
return onError({ addr, type }, c);
|
||||
}
|
||||
throw blockError(c);
|
||||
}
|
||||
if (allowMatcher(remoteData)) {
|
||||
return await next();
|
||||
}
|
||||
if (allowLength === 0) {
|
||||
return await next();
|
||||
} else {
|
||||
if (onError) {
|
||||
return await onError({ addr, type }, c);
|
||||
}
|
||||
throw blockError(c);
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
ipRestriction
|
||||
};
|
||||
57
backend/node_modules/hono/dist/middleware/jsx-renderer/index.js
generated
vendored
Normal file
57
backend/node_modules/hono/dist/middleware/jsx-renderer/index.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
// src/middleware/jsx-renderer/index.ts
|
||||
import { html, raw } from "../../helper/html/index.js";
|
||||
import { Fragment, createContext, jsx, useContext } from "../../jsx/index.js";
|
||||
import { renderToReadableStream } from "../../jsx/streaming.js";
|
||||
var RequestContext = createContext(null);
|
||||
var createRenderer = (c, Layout, component, options) => (children, props) => {
|
||||
const docType = typeof options?.docType === "string" ? options.docType : options?.docType === false ? "" : "<!DOCTYPE html>";
|
||||
const currentLayout = component ? jsx(
|
||||
(props2) => component(props2, c),
|
||||
{
|
||||
Layout,
|
||||
...props
|
||||
},
|
||||
children
|
||||
) : children;
|
||||
const body = html`${raw(docType)}${jsx(
|
||||
RequestContext.Provider,
|
||||
{ value: c },
|
||||
currentLayout
|
||||
)}`;
|
||||
if (options?.stream) {
|
||||
if (options.stream === true) {
|
||||
c.header("Transfer-Encoding", "chunked");
|
||||
c.header("Content-Type", "text/html; charset=UTF-8");
|
||||
c.header("Content-Encoding", "Identity");
|
||||
} else {
|
||||
for (const [key, value] of Object.entries(options.stream)) {
|
||||
c.header(key, value);
|
||||
}
|
||||
}
|
||||
return c.body(renderToReadableStream(body));
|
||||
} else {
|
||||
return c.html(body);
|
||||
}
|
||||
};
|
||||
var jsxRenderer = (component, options) => function jsxRenderer2(c, next) {
|
||||
const Layout = c.getLayout() ?? Fragment;
|
||||
if (component) {
|
||||
c.setLayout((props) => {
|
||||
return component({ ...props, Layout }, c);
|
||||
});
|
||||
}
|
||||
c.setRenderer(createRenderer(c, Layout, component, options));
|
||||
return next();
|
||||
};
|
||||
var useRequestContext = () => {
|
||||
const c = useContext(RequestContext);
|
||||
if (!c) {
|
||||
throw new Error("RequestContext is not provided.");
|
||||
}
|
||||
return c;
|
||||
};
|
||||
export {
|
||||
RequestContext,
|
||||
jsxRenderer,
|
||||
useRequestContext
|
||||
};
|
||||
5
backend/node_modules/hono/dist/middleware/jwk/index.js
generated
vendored
Normal file
5
backend/node_modules/hono/dist/middleware/jwk/index.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// src/middleware/jwk/index.ts
|
||||
import { jwk } from "./jwk.js";
|
||||
export {
|
||||
jwk
|
||||
};
|
||||
112
backend/node_modules/hono/dist/middleware/jwk/jwk.js
generated
vendored
Normal file
112
backend/node_modules/hono/dist/middleware/jwk/jwk.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
// src/middleware/jwk/jwk.ts
|
||||
import { getCookie, getSignedCookie } from "../../helper/cookie/index.js";
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
import { Jwt } from "../../utils/jwt/index.js";
|
||||
import "../../context.js";
|
||||
var jwk = (options, init) => {
|
||||
const verifyOpts = options.verification || {};
|
||||
if (!options || !(options.keys || options.jwks_uri)) {
|
||||
throw new Error('JWK auth middleware requires options for either "keys" or "jwks_uri" or both');
|
||||
}
|
||||
if (!crypto.subtle || !crypto.subtle.importKey) {
|
||||
throw new Error("`crypto.subtle.importKey` is undefined. JWK auth middleware requires it.");
|
||||
}
|
||||
return async function jwk2(ctx, next) {
|
||||
const headerName = options.headerName || "Authorization";
|
||||
const credentials = ctx.req.raw.headers.get(headerName);
|
||||
let token;
|
||||
if (credentials) {
|
||||
const parts = credentials.split(/\s+/);
|
||||
if (parts.length !== 2) {
|
||||
const errDescription = "invalid credentials structure";
|
||||
throw new HTTPException(401, {
|
||||
message: errDescription,
|
||||
res: unauthorizedResponse({
|
||||
ctx,
|
||||
error: "invalid_request",
|
||||
errDescription
|
||||
})
|
||||
});
|
||||
} else {
|
||||
token = parts[1];
|
||||
}
|
||||
} else if (options.cookie) {
|
||||
if (typeof options.cookie == "string") {
|
||||
token = getCookie(ctx, options.cookie);
|
||||
} else if (options.cookie.secret) {
|
||||
if (options.cookie.prefixOptions) {
|
||||
token = await getSignedCookie(
|
||||
ctx,
|
||||
options.cookie.secret,
|
||||
options.cookie.key,
|
||||
options.cookie.prefixOptions
|
||||
);
|
||||
} else {
|
||||
token = await getSignedCookie(ctx, options.cookie.secret, options.cookie.key);
|
||||
}
|
||||
} else {
|
||||
if (options.cookie.prefixOptions) {
|
||||
token = getCookie(ctx, options.cookie.key, options.cookie.prefixOptions);
|
||||
} else {
|
||||
token = getCookie(ctx, options.cookie.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!token) {
|
||||
if (options.allow_anon) {
|
||||
return next();
|
||||
}
|
||||
const errDescription = "no authorization included in request";
|
||||
throw new HTTPException(401, {
|
||||
message: errDescription,
|
||||
res: unauthorizedResponse({
|
||||
ctx,
|
||||
error: "invalid_request",
|
||||
errDescription
|
||||
})
|
||||
});
|
||||
}
|
||||
let payload;
|
||||
let cause;
|
||||
try {
|
||||
const keys = typeof options.keys === "function" ? await options.keys(ctx) : options.keys;
|
||||
const jwks_uri = typeof options.jwks_uri === "function" ? await options.jwks_uri(ctx) : options.jwks_uri;
|
||||
payload = await Jwt.verifyWithJwks(
|
||||
token,
|
||||
{ keys, jwks_uri, verification: verifyOpts, allowedAlgorithms: options.alg },
|
||||
init
|
||||
);
|
||||
} catch (e) {
|
||||
cause = e;
|
||||
}
|
||||
if (!payload) {
|
||||
if (cause instanceof Error && cause.constructor === Error) {
|
||||
throw cause;
|
||||
}
|
||||
throw new HTTPException(401, {
|
||||
message: "Unauthorized",
|
||||
res: unauthorizedResponse({
|
||||
ctx,
|
||||
error: "invalid_token",
|
||||
statusText: "Unauthorized",
|
||||
errDescription: "token verification failure"
|
||||
}),
|
||||
cause
|
||||
});
|
||||
}
|
||||
ctx.set("jwtPayload", payload);
|
||||
await next();
|
||||
};
|
||||
};
|
||||
function unauthorizedResponse(opts) {
|
||||
return new Response("Unauthorized", {
|
||||
status: 401,
|
||||
statusText: opts.statusText,
|
||||
headers: {
|
||||
"WWW-Authenticate": `Bearer realm="${opts.ctx.req.url}",error="${opts.error}",error_description="${opts.errDescription}"`
|
||||
}
|
||||
});
|
||||
}
|
||||
export {
|
||||
jwk
|
||||
};
|
||||
9
backend/node_modules/hono/dist/middleware/jwt/index.js
generated
vendored
Normal file
9
backend/node_modules/hono/dist/middleware/jwt/index.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// src/middleware/jwt/index.ts
|
||||
import { jwt, verifyWithJwks, verify, decode, sign } from "./jwt.js";
|
||||
export {
|
||||
decode,
|
||||
jwt,
|
||||
sign,
|
||||
verify,
|
||||
verifyWithJwks
|
||||
};
|
||||
114
backend/node_modules/hono/dist/middleware/jwt/jwt.js
generated
vendored
Normal file
114
backend/node_modules/hono/dist/middleware/jwt/jwt.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// src/middleware/jwt/jwt.ts
|
||||
import { getCookie, getSignedCookie } from "../../helper/cookie/index.js";
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
import { Jwt } from "../../utils/jwt/index.js";
|
||||
import "../../context.js";
|
||||
var jwt = (options) => {
|
||||
const verifyOpts = options.verification || {};
|
||||
if (!options || !options.secret) {
|
||||
throw new Error('JWT auth middleware requires options for "secret"');
|
||||
}
|
||||
if (!options.alg) {
|
||||
throw new Error('JWT auth middleware requires options for "alg"');
|
||||
}
|
||||
if (!crypto.subtle || !crypto.subtle.importKey) {
|
||||
throw new Error("`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.");
|
||||
}
|
||||
return async function jwt2(ctx, next) {
|
||||
const headerName = options.headerName || "Authorization";
|
||||
const credentials = ctx.req.raw.headers.get(headerName);
|
||||
let token;
|
||||
if (credentials) {
|
||||
const parts = credentials.split(/\s+/);
|
||||
if (parts.length !== 2) {
|
||||
const errDescription = "invalid credentials structure";
|
||||
throw new HTTPException(401, {
|
||||
message: errDescription,
|
||||
res: unauthorizedResponse({
|
||||
ctx,
|
||||
error: "invalid_request",
|
||||
errDescription
|
||||
})
|
||||
});
|
||||
} else {
|
||||
token = parts[1];
|
||||
}
|
||||
} else if (options.cookie) {
|
||||
if (typeof options.cookie == "string") {
|
||||
token = getCookie(ctx, options.cookie);
|
||||
} else if (options.cookie.secret) {
|
||||
if (options.cookie.prefixOptions) {
|
||||
token = await getSignedCookie(
|
||||
ctx,
|
||||
options.cookie.secret,
|
||||
options.cookie.key,
|
||||
options.cookie.prefixOptions
|
||||
);
|
||||
} else {
|
||||
token = await getSignedCookie(ctx, options.cookie.secret, options.cookie.key);
|
||||
}
|
||||
} else {
|
||||
if (options.cookie.prefixOptions) {
|
||||
token = getCookie(ctx, options.cookie.key, options.cookie.prefixOptions);
|
||||
} else {
|
||||
token = getCookie(ctx, options.cookie.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!token) {
|
||||
const errDescription = "no authorization included in request";
|
||||
throw new HTTPException(401, {
|
||||
message: errDescription,
|
||||
res: unauthorizedResponse({
|
||||
ctx,
|
||||
error: "invalid_request",
|
||||
errDescription
|
||||
})
|
||||
});
|
||||
}
|
||||
let payload;
|
||||
let cause;
|
||||
try {
|
||||
payload = await Jwt.verify(token, options.secret, {
|
||||
alg: options.alg,
|
||||
...verifyOpts
|
||||
});
|
||||
} catch (e) {
|
||||
cause = e;
|
||||
}
|
||||
if (!payload) {
|
||||
throw new HTTPException(401, {
|
||||
message: "Unauthorized",
|
||||
res: unauthorizedResponse({
|
||||
ctx,
|
||||
error: "invalid_token",
|
||||
statusText: "Unauthorized",
|
||||
errDescription: "token verification failure"
|
||||
}),
|
||||
cause
|
||||
});
|
||||
}
|
||||
ctx.set("jwtPayload", payload);
|
||||
await next();
|
||||
};
|
||||
};
|
||||
function unauthorizedResponse(opts) {
|
||||
return new Response("Unauthorized", {
|
||||
status: 401,
|
||||
statusText: opts.statusText,
|
||||
headers: {
|
||||
"WWW-Authenticate": `Bearer realm="${opts.ctx.req.url}",error="${opts.error}",error_description="${opts.errDescription}"`
|
||||
}
|
||||
});
|
||||
}
|
||||
var verifyWithJwks = Jwt.verifyWithJwks;
|
||||
var verify = Jwt.verify;
|
||||
var decode = Jwt.decode;
|
||||
var sign = Jwt.sign;
|
||||
export {
|
||||
decode,
|
||||
jwt,
|
||||
sign,
|
||||
verify,
|
||||
verifyWithJwks
|
||||
};
|
||||
15
backend/node_modules/hono/dist/middleware/language/index.js
generated
vendored
Normal file
15
backend/node_modules/hono/dist/middleware/language/index.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// src/middleware/language/index.ts
|
||||
import {
|
||||
languageDetector,
|
||||
detectFromCookie,
|
||||
detectFromHeader,
|
||||
detectFromPath,
|
||||
detectFromQuery
|
||||
} from "./language.js";
|
||||
export {
|
||||
detectFromCookie,
|
||||
detectFromHeader,
|
||||
detectFromPath,
|
||||
detectFromQuery,
|
||||
languageDetector
|
||||
};
|
||||
179
backend/node_modules/hono/dist/middleware/language/language.js
generated
vendored
Normal file
179
backend/node_modules/hono/dist/middleware/language/language.js
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
// src/middleware/language/language.ts
|
||||
import { setCookie, getCookie } from "../../helper/cookie/index.js";
|
||||
import { parseAccept } from "../../utils/accept.js";
|
||||
var DEFAULT_OPTIONS = {
|
||||
order: ["querystring", "cookie", "header"],
|
||||
lookupQueryString: "lang",
|
||||
lookupCookie: "language",
|
||||
lookupFromHeaderKey: "accept-language",
|
||||
lookupFromPathIndex: 0,
|
||||
caches: ["cookie"],
|
||||
ignoreCase: true,
|
||||
fallbackLanguage: "en",
|
||||
supportedLanguages: ["en"],
|
||||
cookieOptions: {
|
||||
sameSite: "Strict",
|
||||
secure: true,
|
||||
maxAge: 365 * 24 * 60 * 60,
|
||||
httpOnly: true
|
||||
},
|
||||
debug: false
|
||||
};
|
||||
function parseAcceptLanguage(header) {
|
||||
return parseAccept(header).map(({ type, q }) => ({ lang: type, q }));
|
||||
}
|
||||
var normalizeLanguage = (lang, options) => {
|
||||
if (!lang) {
|
||||
return void 0;
|
||||
}
|
||||
try {
|
||||
let normalizedLang = lang.trim();
|
||||
if (options.convertDetectedLanguage) {
|
||||
normalizedLang = options.convertDetectedLanguage(normalizedLang);
|
||||
}
|
||||
const compLang = options.ignoreCase ? normalizedLang.toLowerCase() : normalizedLang;
|
||||
const compSupported = options.supportedLanguages.map(
|
||||
(l) => options.ignoreCase ? l.toLowerCase() : l
|
||||
);
|
||||
const matchedLang = compSupported.find((l) => l === compLang);
|
||||
return matchedLang ? options.supportedLanguages[compSupported.indexOf(matchedLang)] : void 0;
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
};
|
||||
var detectFromQuery = (c, options) => {
|
||||
try {
|
||||
const query = c.req.query(options.lookupQueryString);
|
||||
return normalizeLanguage(query, options);
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
};
|
||||
var detectFromCookie = (c, options) => {
|
||||
try {
|
||||
const cookie = getCookie(c, options.lookupCookie);
|
||||
return normalizeLanguage(cookie, options);
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
};
|
||||
function detectFromHeader(c, options) {
|
||||
try {
|
||||
const acceptLanguage = c.req.header(options.lookupFromHeaderKey);
|
||||
if (!acceptLanguage) {
|
||||
return void 0;
|
||||
}
|
||||
const languages = parseAcceptLanguage(acceptLanguage);
|
||||
for (const { lang } of languages) {
|
||||
const normalizedLang = normalizeLanguage(lang, options);
|
||||
if (normalizedLang) {
|
||||
return normalizedLang;
|
||||
}
|
||||
}
|
||||
return void 0;
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
function detectFromPath(c, options) {
|
||||
try {
|
||||
const url = new URL(c.req.url);
|
||||
const pathSegments = url.pathname.split("/").filter(Boolean);
|
||||
const langSegment = pathSegments[options.lookupFromPathIndex];
|
||||
return normalizeLanguage(langSegment, options);
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
var detectors = {
|
||||
querystring: detectFromQuery,
|
||||
cookie: detectFromCookie,
|
||||
header: detectFromHeader,
|
||||
path: detectFromPath
|
||||
};
|
||||
function validateOptions(options) {
|
||||
if (!options.supportedLanguages.includes(options.fallbackLanguage)) {
|
||||
throw new Error("Fallback language must be included in supported languages");
|
||||
}
|
||||
if (options.lookupFromPathIndex < 0) {
|
||||
throw new Error("Path index must be non-negative");
|
||||
}
|
||||
if (!options.order.every((detector) => Object.keys(detectors).includes(detector))) {
|
||||
throw new Error("Invalid detector type in order array");
|
||||
}
|
||||
}
|
||||
function cacheLanguage(c, language, options) {
|
||||
if (!Array.isArray(options.caches) || !options.caches.includes("cookie")) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setCookie(c, options.lookupCookie, language, options.cookieOptions);
|
||||
} catch (error) {
|
||||
if (options.debug) {
|
||||
console.error("Failed to cache language:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
var detectLanguage = (c, options) => {
|
||||
let detectedLang;
|
||||
for (const detectorName of options.order) {
|
||||
const detector = detectors[detectorName];
|
||||
if (!detector) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
detectedLang = detector(c, options);
|
||||
if (detectedLang) {
|
||||
if (options.debug) {
|
||||
console.log(`Language detected from ${detectorName}: ${detectedLang}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
if (options.debug) {
|
||||
console.error(`Error in ${detectorName} detector:`, error);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const finalLang = detectedLang || options.fallbackLanguage;
|
||||
if (detectedLang && options.caches) {
|
||||
cacheLanguage(c, finalLang, options);
|
||||
}
|
||||
return finalLang;
|
||||
};
|
||||
var languageDetector = (userOptions) => {
|
||||
const options = {
|
||||
...DEFAULT_OPTIONS,
|
||||
...userOptions,
|
||||
cookieOptions: {
|
||||
...DEFAULT_OPTIONS.cookieOptions,
|
||||
...userOptions.cookieOptions
|
||||
}
|
||||
};
|
||||
validateOptions(options);
|
||||
return async function languageDetector2(ctx, next) {
|
||||
try {
|
||||
const lang = detectLanguage(ctx, options);
|
||||
ctx.set("language", lang);
|
||||
} catch (error) {
|
||||
if (options.debug) {
|
||||
console.error("Language detection failed:", error);
|
||||
}
|
||||
ctx.set("language", options.fallbackLanguage);
|
||||
}
|
||||
await next();
|
||||
};
|
||||
};
|
||||
export {
|
||||
DEFAULT_OPTIONS,
|
||||
detectFromCookie,
|
||||
detectFromHeader,
|
||||
detectFromPath,
|
||||
detectFromQuery,
|
||||
detectors,
|
||||
languageDetector,
|
||||
normalizeLanguage,
|
||||
parseAcceptLanguage,
|
||||
validateOptions
|
||||
};
|
||||
44
backend/node_modules/hono/dist/middleware/logger/index.js
generated
vendored
Normal file
44
backend/node_modules/hono/dist/middleware/logger/index.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// src/middleware/logger/index.ts
|
||||
import { getColorEnabledAsync } from "../../utils/color.js";
|
||||
var humanize = (times) => {
|
||||
const [delimiter, separator] = [",", "."];
|
||||
const orderTimes = times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + delimiter));
|
||||
return orderTimes.join(separator);
|
||||
};
|
||||
var time = (start) => {
|
||||
const delta = Date.now() - start;
|
||||
return humanize([delta < 1e3 ? delta + "ms" : Math.round(delta / 1e3) + "s"]);
|
||||
};
|
||||
var colorStatus = async (status) => {
|
||||
const colorEnabled = await getColorEnabledAsync();
|
||||
if (colorEnabled) {
|
||||
switch (status / 100 | 0) {
|
||||
case 5:
|
||||
return `\x1B[31m${status}\x1B[0m`;
|
||||
case 4:
|
||||
return `\x1B[33m${status}\x1B[0m`;
|
||||
case 3:
|
||||
return `\x1B[36m${status}\x1B[0m`;
|
||||
case 2:
|
||||
return `\x1B[32m${status}\x1B[0m`;
|
||||
}
|
||||
}
|
||||
return `${status}`;
|
||||
};
|
||||
async function log(fn, prefix, method, path, status = 0, elapsed) {
|
||||
const out = prefix === "<--" /* Incoming */ ? `${prefix} ${method} ${path}` : `${prefix} ${method} ${path} ${await colorStatus(status)} ${elapsed}`;
|
||||
fn(out);
|
||||
}
|
||||
var logger = (fn = console.log) => {
|
||||
return async function logger2(c, next) {
|
||||
const { method, url } = c.req;
|
||||
const path = url.slice(url.indexOf("/", 8));
|
||||
await log(fn, "<--" /* Incoming */, method, path);
|
||||
const start = Date.now();
|
||||
await next();
|
||||
await log(fn, "-->" /* Outgoing */, method, path, c.res.status, time(start));
|
||||
};
|
||||
};
|
||||
export {
|
||||
logger
|
||||
};
|
||||
82
backend/node_modules/hono/dist/middleware/method-override/index.js
generated
vendored
Normal file
82
backend/node_modules/hono/dist/middleware/method-override/index.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// src/middleware/method-override/index.ts
|
||||
import { parseBody } from "../../utils/body.js";
|
||||
var DEFAULT_METHOD_FORM_NAME = "_method";
|
||||
var methodOverride = (options) => async function methodOverride2(c, next) {
|
||||
if (c.req.method === "GET") {
|
||||
return await next();
|
||||
}
|
||||
const app = options.app;
|
||||
if (!(options.header || options.query)) {
|
||||
const contentType = c.req.header("content-type");
|
||||
const methodFormName = options.form || DEFAULT_METHOD_FORM_NAME;
|
||||
const clonedRequest = c.req.raw.clone();
|
||||
const newRequest = clonedRequest.clone();
|
||||
if (contentType?.startsWith("multipart/form-data")) {
|
||||
const form = await clonedRequest.formData();
|
||||
const method = form.get(methodFormName);
|
||||
if (method) {
|
||||
const newForm = await newRequest.formData();
|
||||
newForm.delete(methodFormName);
|
||||
const newHeaders = new Headers(clonedRequest.headers);
|
||||
newHeaders.delete("content-type");
|
||||
newHeaders.delete("content-length");
|
||||
const request = new Request(c.req.url, {
|
||||
body: newForm,
|
||||
headers: newHeaders,
|
||||
method
|
||||
});
|
||||
return app.fetch(request, c.env, getExecutionCtx(c));
|
||||
}
|
||||
}
|
||||
if (contentType === "application/x-www-form-urlencoded") {
|
||||
const params = await parseBody(clonedRequest);
|
||||
const method = params[methodFormName];
|
||||
if (method) {
|
||||
delete params[methodFormName];
|
||||
const newParams = new URLSearchParams(params);
|
||||
const request = new Request(newRequest, {
|
||||
body: newParams,
|
||||
method
|
||||
});
|
||||
return app.fetch(request, c.env, getExecutionCtx(c));
|
||||
}
|
||||
}
|
||||
} else if (options.header) {
|
||||
const headerName = options.header;
|
||||
const method = c.req.header(headerName);
|
||||
if (method) {
|
||||
const newHeaders = new Headers(c.req.raw.headers);
|
||||
newHeaders.delete(headerName);
|
||||
const request = new Request(c.req.raw, {
|
||||
headers: newHeaders,
|
||||
method
|
||||
});
|
||||
return app.fetch(request, c.env, getExecutionCtx(c));
|
||||
}
|
||||
} else if (options.query) {
|
||||
const queryName = options.query;
|
||||
const method = c.req.query(queryName);
|
||||
if (method) {
|
||||
const url = new URL(c.req.url);
|
||||
url.searchParams.delete(queryName);
|
||||
const request = new Request(url.toString(), {
|
||||
body: c.req.raw.body,
|
||||
headers: c.req.raw.headers,
|
||||
method
|
||||
});
|
||||
return app.fetch(request, c.env, getExecutionCtx(c));
|
||||
}
|
||||
}
|
||||
await next();
|
||||
};
|
||||
var getExecutionCtx = (c) => {
|
||||
let executionCtx;
|
||||
try {
|
||||
executionCtx = c.executionCtx;
|
||||
} catch {
|
||||
}
|
||||
return executionCtx;
|
||||
};
|
||||
export {
|
||||
methodOverride
|
||||
};
|
||||
10
backend/node_modules/hono/dist/middleware/powered-by/index.js
generated
vendored
Normal file
10
backend/node_modules/hono/dist/middleware/powered-by/index.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// src/middleware/powered-by/index.ts
|
||||
var poweredBy = (options) => {
|
||||
return async function poweredBy2(c, next) {
|
||||
await next();
|
||||
c.res.headers.set("X-Powered-By", options?.serverName ?? "Hono");
|
||||
};
|
||||
};
|
||||
export {
|
||||
poweredBy
|
||||
};
|
||||
15
backend/node_modules/hono/dist/middleware/pretty-json/index.js
generated
vendored
Normal file
15
backend/node_modules/hono/dist/middleware/pretty-json/index.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// src/middleware/pretty-json/index.ts
|
||||
var prettyJSON = (options) => {
|
||||
const targetQuery = options?.query ?? "pretty";
|
||||
return async function prettyJSON2(c, next) {
|
||||
const pretty = options?.force || c.req.query(targetQuery) || c.req.query(targetQuery) === "";
|
||||
await next();
|
||||
if (pretty && c.res.headers.get("Content-Type")?.startsWith("application/json")) {
|
||||
const obj = await c.res.json();
|
||||
c.res = new Response(JSON.stringify(obj, null, options?.space ?? 2), c.res);
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
prettyJSON
|
||||
};
|
||||
5
backend/node_modules/hono/dist/middleware/request-id/index.js
generated
vendored
Normal file
5
backend/node_modules/hono/dist/middleware/request-id/index.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// src/middleware/request-id/index.ts
|
||||
import { requestId } from "./request-id.js";
|
||||
export {
|
||||
requestId
|
||||
};
|
||||
21
backend/node_modules/hono/dist/middleware/request-id/request-id.js
generated
vendored
Normal file
21
backend/node_modules/hono/dist/middleware/request-id/request-id.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// src/middleware/request-id/request-id.ts
|
||||
var requestId = ({
|
||||
limitLength = 255,
|
||||
headerName = "X-Request-Id",
|
||||
generator = () => crypto.randomUUID()
|
||||
} = {}) => {
|
||||
return async function requestId2(c, next) {
|
||||
let reqId = headerName ? c.req.header(headerName) : void 0;
|
||||
if (!reqId || reqId.length > limitLength || /[^\w\-=]/.test(reqId)) {
|
||||
reqId = generator(c);
|
||||
}
|
||||
c.set("requestId", reqId);
|
||||
if (headerName) {
|
||||
c.header(headerName, reqId);
|
||||
}
|
||||
await next();
|
||||
};
|
||||
};
|
||||
export {
|
||||
requestId
|
||||
};
|
||||
6
backend/node_modules/hono/dist/middleware/secure-headers/index.js
generated
vendored
Normal file
6
backend/node_modules/hono/dist/middleware/secure-headers/index.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// src/middleware/secure-headers/index.ts
|
||||
import { NONCE, secureHeaders } from "./secure-headers.js";
|
||||
export {
|
||||
NONCE,
|
||||
secureHeaders
|
||||
};
|
||||
0
backend/node_modules/hono/dist/middleware/secure-headers/permissions-policy.js
generated
vendored
Normal file
0
backend/node_modules/hono/dist/middleware/secure-headers/permissions-policy.js
generated
vendored
Normal file
166
backend/node_modules/hono/dist/middleware/secure-headers/secure-headers.js
generated
vendored
Normal file
166
backend/node_modules/hono/dist/middleware/secure-headers/secure-headers.js
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
// src/middleware/secure-headers/secure-headers.ts
|
||||
import { encodeBase64 } from "../../utils/encode.js";
|
||||
var HEADERS_MAP = {
|
||||
crossOriginEmbedderPolicy: ["Cross-Origin-Embedder-Policy", "require-corp"],
|
||||
crossOriginResourcePolicy: ["Cross-Origin-Resource-Policy", "same-origin"],
|
||||
crossOriginOpenerPolicy: ["Cross-Origin-Opener-Policy", "same-origin"],
|
||||
originAgentCluster: ["Origin-Agent-Cluster", "?1"],
|
||||
referrerPolicy: ["Referrer-Policy", "no-referrer"],
|
||||
strictTransportSecurity: ["Strict-Transport-Security", "max-age=15552000; includeSubDomains"],
|
||||
xContentTypeOptions: ["X-Content-Type-Options", "nosniff"],
|
||||
xDnsPrefetchControl: ["X-DNS-Prefetch-Control", "off"],
|
||||
xDownloadOptions: ["X-Download-Options", "noopen"],
|
||||
xFrameOptions: ["X-Frame-Options", "SAMEORIGIN"],
|
||||
xPermittedCrossDomainPolicies: ["X-Permitted-Cross-Domain-Policies", "none"],
|
||||
xXssProtection: ["X-XSS-Protection", "0"]
|
||||
};
|
||||
var DEFAULT_OPTIONS = {
|
||||
crossOriginEmbedderPolicy: false,
|
||||
crossOriginResourcePolicy: true,
|
||||
crossOriginOpenerPolicy: true,
|
||||
originAgentCluster: true,
|
||||
referrerPolicy: true,
|
||||
strictTransportSecurity: true,
|
||||
xContentTypeOptions: true,
|
||||
xDnsPrefetchControl: true,
|
||||
xDownloadOptions: true,
|
||||
xFrameOptions: true,
|
||||
xPermittedCrossDomainPolicies: true,
|
||||
xXssProtection: true,
|
||||
removePoweredBy: true,
|
||||
permissionsPolicy: {}
|
||||
};
|
||||
var generateNonce = () => {
|
||||
const arrayBuffer = new Uint8Array(16);
|
||||
crypto.getRandomValues(arrayBuffer);
|
||||
return encodeBase64(arrayBuffer.buffer);
|
||||
};
|
||||
var NONCE = (ctx) => {
|
||||
const key = "secureHeadersNonce";
|
||||
const init = ctx.get(key);
|
||||
const nonce = init || generateNonce();
|
||||
if (init == null) {
|
||||
ctx.set(key, nonce);
|
||||
}
|
||||
return `'nonce-${nonce}'`;
|
||||
};
|
||||
var secureHeaders = (customOptions) => {
|
||||
const options = { ...DEFAULT_OPTIONS, ...customOptions };
|
||||
const headersToSet = getFilteredHeaders(options);
|
||||
const callbacks = [];
|
||||
if (options.contentSecurityPolicy) {
|
||||
const [callback, value] = getCSPDirectives(options.contentSecurityPolicy);
|
||||
if (callback) {
|
||||
callbacks.push(callback);
|
||||
}
|
||||
headersToSet.push(["Content-Security-Policy", value]);
|
||||
}
|
||||
if (options.contentSecurityPolicyReportOnly) {
|
||||
const [callback, value] = getCSPDirectives(options.contentSecurityPolicyReportOnly);
|
||||
if (callback) {
|
||||
callbacks.push(callback);
|
||||
}
|
||||
headersToSet.push(["Content-Security-Policy-Report-Only", value]);
|
||||
}
|
||||
if (options.permissionsPolicy && Object.keys(options.permissionsPolicy).length > 0) {
|
||||
headersToSet.push([
|
||||
"Permissions-Policy",
|
||||
getPermissionsPolicyDirectives(options.permissionsPolicy)
|
||||
]);
|
||||
}
|
||||
if (options.reportingEndpoints) {
|
||||
headersToSet.push(["Reporting-Endpoints", getReportingEndpoints(options.reportingEndpoints)]);
|
||||
}
|
||||
if (options.reportTo) {
|
||||
headersToSet.push(["Report-To", getReportToOptions(options.reportTo)]);
|
||||
}
|
||||
return async function secureHeaders2(ctx, next) {
|
||||
const headersToSetForReq = callbacks.length === 0 ? headersToSet : callbacks.reduce((acc, cb) => cb(ctx, acc), headersToSet);
|
||||
await next();
|
||||
setHeaders(ctx, headersToSetForReq);
|
||||
if (options?.removePoweredBy) {
|
||||
ctx.res.headers.delete("X-Powered-By");
|
||||
}
|
||||
};
|
||||
};
|
||||
function getFilteredHeaders(options) {
|
||||
return Object.entries(HEADERS_MAP).filter(([key]) => options[key]).map(([key, defaultValue]) => {
|
||||
const overrideValue = options[key];
|
||||
return typeof overrideValue === "string" ? [defaultValue[0], overrideValue] : defaultValue;
|
||||
});
|
||||
}
|
||||
function getCSPDirectives(contentSecurityPolicy) {
|
||||
const callbacks = [];
|
||||
const resultValues = [];
|
||||
for (const [directive, value] of Object.entries(contentSecurityPolicy)) {
|
||||
const valueArray = Array.isArray(value) ? value : [value];
|
||||
valueArray.forEach((value2, i) => {
|
||||
if (typeof value2 === "function") {
|
||||
const index = i * 2 + 2 + resultValues.length;
|
||||
callbacks.push((ctx, values) => {
|
||||
values[index] = value2(ctx, directive);
|
||||
});
|
||||
}
|
||||
});
|
||||
resultValues.push(
|
||||
directive.replace(
|
||||
/[A-Z]+(?![a-z])|[A-Z]/g,
|
||||
(match, offset) => offset ? "-" + match.toLowerCase() : match.toLowerCase()
|
||||
),
|
||||
...valueArray.flatMap((value2) => [" ", value2]),
|
||||
"; "
|
||||
);
|
||||
}
|
||||
resultValues.pop();
|
||||
return callbacks.length === 0 ? [void 0, resultValues.join("")] : [
|
||||
(ctx, headersToSet) => headersToSet.map((values) => {
|
||||
if (values[0] === "Content-Security-Policy" || values[0] === "Content-Security-Policy-Report-Only") {
|
||||
const clone = values[1].slice();
|
||||
callbacks.forEach((cb) => {
|
||||
cb(ctx, clone);
|
||||
});
|
||||
return [values[0], clone.join("")];
|
||||
} else {
|
||||
return values;
|
||||
}
|
||||
}),
|
||||
resultValues
|
||||
];
|
||||
}
|
||||
function getPermissionsPolicyDirectives(policy) {
|
||||
return Object.entries(policy).map(([directive, value]) => {
|
||||
const kebabDirective = camelToKebab(directive);
|
||||
if (typeof value === "boolean") {
|
||||
return `${kebabDirective}=${value ? "*" : "none"}`;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length === 0) {
|
||||
return `${kebabDirective}=()`;
|
||||
}
|
||||
if (value.length === 1 && (value[0] === "*" || value[0] === "none")) {
|
||||
return `${kebabDirective}=${value[0]}`;
|
||||
}
|
||||
const allowlist = value.map((item) => ["self", "src"].includes(item) ? item : `"${item}"`);
|
||||
return `${kebabDirective}=(${allowlist.join(" ")})`;
|
||||
}
|
||||
return "";
|
||||
}).filter(Boolean).join(", ");
|
||||
}
|
||||
function camelToKebab(str) {
|
||||
return str.replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
|
||||
}
|
||||
function getReportingEndpoints(reportingEndpoints = []) {
|
||||
return reportingEndpoints.map((endpoint) => `${endpoint.name}="${endpoint.url}"`).join(", ");
|
||||
}
|
||||
function getReportToOptions(reportTo = []) {
|
||||
return reportTo.map((option) => JSON.stringify(option)).join(", ");
|
||||
}
|
||||
function setHeaders(ctx, headersToSet) {
|
||||
headersToSet.forEach(([header, value]) => {
|
||||
ctx.res.headers.set(header, value);
|
||||
});
|
||||
}
|
||||
export {
|
||||
NONCE,
|
||||
secureHeaders
|
||||
};
|
||||
76
backend/node_modules/hono/dist/middleware/serve-static/index.js
generated
vendored
Normal file
76
backend/node_modules/hono/dist/middleware/serve-static/index.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// src/middleware/serve-static/index.ts
|
||||
import { COMPRESSIBLE_CONTENT_TYPE_REGEX } from "../../utils/compress.js";
|
||||
import { getMimeType } from "../../utils/mime.js";
|
||||
import { defaultJoin } from "./path.js";
|
||||
var ENCODINGS = {
|
||||
br: ".br",
|
||||
zstd: ".zst",
|
||||
gzip: ".gz"
|
||||
};
|
||||
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
||||
var DEFAULT_DOCUMENT = "index.html";
|
||||
var serveStatic = (options) => {
|
||||
const root = options.root ?? "./";
|
||||
const optionPath = options.path;
|
||||
const join = options.join ?? defaultJoin;
|
||||
return async (c, next) => {
|
||||
if (c.finalized) {
|
||||
return next();
|
||||
}
|
||||
let filename;
|
||||
if (options.path) {
|
||||
filename = options.path;
|
||||
} else {
|
||||
try {
|
||||
filename = decodeURIComponent(c.req.path);
|
||||
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
||||
throw new Error();
|
||||
}
|
||||
} catch {
|
||||
await options.onNotFound?.(c.req.path, c);
|
||||
return next();
|
||||
}
|
||||
}
|
||||
let path = join(
|
||||
root,
|
||||
!optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename
|
||||
);
|
||||
if (options.isDir && await options.isDir(path)) {
|
||||
path = join(path, DEFAULT_DOCUMENT);
|
||||
}
|
||||
const getContent = options.getContent;
|
||||
let content = await getContent(path, c);
|
||||
if (content instanceof Response) {
|
||||
return c.newResponse(content.body, content);
|
||||
}
|
||||
if (content) {
|
||||
const mimeType = options.mimes && getMimeType(path, options.mimes) || getMimeType(path);
|
||||
c.header("Content-Type", mimeType || "application/octet-stream");
|
||||
if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
|
||||
const acceptEncodingSet = new Set(
|
||||
c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim())
|
||||
);
|
||||
for (const encoding of ENCODINGS_ORDERED_KEYS) {
|
||||
if (!acceptEncodingSet.has(encoding)) {
|
||||
continue;
|
||||
}
|
||||
const compressedContent = await getContent(path + ENCODINGS[encoding], c);
|
||||
if (compressedContent) {
|
||||
content = compressedContent;
|
||||
c.header("Content-Encoding", encoding);
|
||||
c.header("Vary", "Accept-Encoding", { append: true });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
await options.onFound?.(path, c);
|
||||
return c.body(content);
|
||||
}
|
||||
await options.onNotFound?.(path, c);
|
||||
await next();
|
||||
return;
|
||||
};
|
||||
};
|
||||
export {
|
||||
serveStatic
|
||||
};
|
||||
18
backend/node_modules/hono/dist/middleware/serve-static/path.js
generated
vendored
Normal file
18
backend/node_modules/hono/dist/middleware/serve-static/path.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// src/middleware/serve-static/path.ts
|
||||
var defaultJoin = (...paths) => {
|
||||
let result = paths.filter((p) => p !== "").join("/");
|
||||
result = result.replace(/(?<=\/)\/+/g, "");
|
||||
const segments = result.split("/");
|
||||
const resolved = [];
|
||||
for (const segment of segments) {
|
||||
if (segment === ".." && resolved.length > 0 && resolved.at(-1) !== "..") {
|
||||
resolved.pop();
|
||||
} else if (segment !== ".") {
|
||||
resolved.push(segment);
|
||||
}
|
||||
}
|
||||
return resolved.join("/") || ".";
|
||||
};
|
||||
export {
|
||||
defaultJoin
|
||||
};
|
||||
25
backend/node_modules/hono/dist/middleware/timeout/index.js
generated
vendored
Normal file
25
backend/node_modules/hono/dist/middleware/timeout/index.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// src/middleware/timeout/index.ts
|
||||
import { HTTPException } from "../../http-exception.js";
|
||||
var defaultTimeoutException = new HTTPException(504, {
|
||||
message: "Gateway Timeout"
|
||||
});
|
||||
var timeout = (duration, exception = defaultTimeoutException) => {
|
||||
return async function timeout2(context, next) {
|
||||
let timer;
|
||||
const timeoutPromise = new Promise((_, reject) => {
|
||||
timer = setTimeout(() => {
|
||||
reject(typeof exception === "function" ? exception(context) : exception);
|
||||
}, duration);
|
||||
});
|
||||
try {
|
||||
await Promise.race([next(), timeoutPromise]);
|
||||
} finally {
|
||||
if (timer !== void 0) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
timeout
|
||||
};
|
||||
9
backend/node_modules/hono/dist/middleware/timing/index.js
generated
vendored
Normal file
9
backend/node_modules/hono/dist/middleware/timing/index.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// src/middleware/timing/index.ts
|
||||
import { timing, setMetric, startTime, endTime, wrapTime } from "./timing.js";
|
||||
export {
|
||||
endTime,
|
||||
setMetric,
|
||||
startTime,
|
||||
timing,
|
||||
wrapTime
|
||||
};
|
||||
102
backend/node_modules/hono/dist/middleware/timing/timing.js
generated
vendored
Normal file
102
backend/node_modules/hono/dist/middleware/timing/timing.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// src/middleware/timing/timing.ts
|
||||
import "../../context.js";
|
||||
var getTime = () => {
|
||||
try {
|
||||
return performance.now();
|
||||
} catch {
|
||||
}
|
||||
return Date.now();
|
||||
};
|
||||
var timing = (config) => {
|
||||
const options = {
|
||||
total: true,
|
||||
enabled: true,
|
||||
totalDescription: "Total Response Time",
|
||||
autoEnd: true,
|
||||
crossOrigin: false,
|
||||
...config
|
||||
};
|
||||
return async function timing2(c, next) {
|
||||
const headers = [];
|
||||
const timers = /* @__PURE__ */ new Map();
|
||||
if (c.get("metric")) {
|
||||
return await next();
|
||||
}
|
||||
c.set("metric", { headers, timers });
|
||||
if (options.total) {
|
||||
startTime(c, "total", options.totalDescription);
|
||||
}
|
||||
await next();
|
||||
if (options.total) {
|
||||
endTime(c, "total");
|
||||
}
|
||||
if (options.autoEnd) {
|
||||
timers.forEach((_, key) => endTime(c, key));
|
||||
}
|
||||
const enabled = typeof options.enabled === "function" ? options.enabled(c) : options.enabled;
|
||||
if (enabled) {
|
||||
c.res.headers.append("Server-Timing", headers.join(","));
|
||||
const crossOrigin = typeof options.crossOrigin === "function" ? options.crossOrigin(c) : options.crossOrigin;
|
||||
if (crossOrigin) {
|
||||
c.res.headers.append(
|
||||
"Timing-Allow-Origin",
|
||||
typeof crossOrigin === "string" ? crossOrigin : "*"
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
var setMetric = (c, name, valueDescription, description, precision) => {
|
||||
const metrics = c.get("metric");
|
||||
if (!metrics) {
|
||||
console.warn("Metrics not initialized! Please add the `timing()` middleware to this route!");
|
||||
return;
|
||||
}
|
||||
if (typeof valueDescription === "number") {
|
||||
const dur = valueDescription.toFixed(precision || 1);
|
||||
const metric = description ? `${name};dur=${dur};desc="${description}"` : `${name};dur=${dur}`;
|
||||
metrics.headers.push(metric);
|
||||
} else {
|
||||
const metric = valueDescription ? `${name};desc="${valueDescription}"` : `${name}`;
|
||||
metrics.headers.push(metric);
|
||||
}
|
||||
};
|
||||
var startTime = (c, name, description) => {
|
||||
const metrics = c.get("metric");
|
||||
if (!metrics) {
|
||||
console.warn("Metrics not initialized! Please add the `timing()` middleware to this route!");
|
||||
return;
|
||||
}
|
||||
metrics.timers.set(name, { description, start: getTime() });
|
||||
};
|
||||
var endTime = (c, name, precision) => {
|
||||
const metrics = c.get("metric");
|
||||
if (!metrics) {
|
||||
console.warn("Metrics not initialized! Please add the `timing()` middleware to this route!");
|
||||
return;
|
||||
}
|
||||
const timer = metrics.timers.get(name);
|
||||
if (!timer) {
|
||||
console.warn(`Timer "${name}" does not exist!`);
|
||||
return;
|
||||
}
|
||||
const { description, start } = timer;
|
||||
const duration = getTime() - start;
|
||||
setMetric(c, name, duration, description, precision);
|
||||
metrics.timers.delete(name);
|
||||
};
|
||||
async function wrapTime(c, name, callable, description, precision) {
|
||||
startTime(c, name, description);
|
||||
try {
|
||||
return await callable;
|
||||
} finally {
|
||||
endTime(c, name, precision);
|
||||
}
|
||||
}
|
||||
export {
|
||||
endTime,
|
||||
setMetric,
|
||||
startTime,
|
||||
timing,
|
||||
wrapTime
|
||||
};
|
||||
25
backend/node_modules/hono/dist/middleware/trailing-slash/index.js
generated
vendored
Normal file
25
backend/node_modules/hono/dist/middleware/trailing-slash/index.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// src/middleware/trailing-slash/index.ts
|
||||
var trimTrailingSlash = () => {
|
||||
return async function trimTrailingSlash2(c, next) {
|
||||
await next();
|
||||
if (c.res.status === 404 && (c.req.method === "GET" || c.req.method === "HEAD") && c.req.path !== "/" && c.req.path.at(-1) === "/") {
|
||||
const url = new URL(c.req.url);
|
||||
url.pathname = url.pathname.substring(0, url.pathname.length - 1);
|
||||
c.res = c.redirect(url.toString(), 301);
|
||||
}
|
||||
};
|
||||
};
|
||||
var appendTrailingSlash = () => {
|
||||
return async function appendTrailingSlash2(c, next) {
|
||||
await next();
|
||||
if (c.res.status === 404 && (c.req.method === "GET" || c.req.method === "HEAD") && c.req.path.at(-1) !== "/") {
|
||||
const url = new URL(c.req.url);
|
||||
url.pathname += "/";
|
||||
c.res = c.redirect(url.toString(), 301);
|
||||
}
|
||||
};
|
||||
};
|
||||
export {
|
||||
appendTrailingSlash,
|
||||
trimTrailingSlash
|
||||
};
|
||||
Reference in New Issue
Block a user