Buckets:
ktongue/docker_container / .cache /opencode /node_modules /hono /dist /middleware /language /language.js
| // 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 | |
| }; | |
Xet Storage Details
- Size:
- 4.96 kB
- Xet hash:
- 5c3fcdefb47e0813f3e41d61601b1816c65441f549d7c8e6a3af173b0e096146
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.