diff --git a/.open-next 2/middleware/handler.mjs b/.open-next 2/middleware/handler.mjs deleted file mode 100644 index 637352a..0000000 --- a/.open-next 2/middleware/handler.mjs +++ /dev/null @@ -1,2660 +0,0 @@ - -import {Buffer} from "node:buffer"; -globalThis.Buffer = Buffer; - -import {AsyncLocalStorage} from "node:async_hooks"; -globalThis.AsyncLocalStorage = AsyncLocalStorage; - - -const defaultDefineProperty = Object.defineProperty; -Object.defineProperty = function(o, p, a) { - if(p=== '__import_unsupported' && Boolean(globalThis.__import_unsupported)) { - return; - } - return defaultDefineProperty(o, p, a); -}; - - - - globalThis.openNextDebug = false;globalThis.openNextVersion = "3.9.12"; -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __esm = (fn, res) => function __init() { - return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; -}; -var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; -}; -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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); - -// node_modules/@opennextjs/aws/dist/utils/error.js -function isOpenNextError(e) { - try { - return "__openNextInternal" in e; - } catch { - return false; - } -} -var init_error = __esm({ - "node_modules/@opennextjs/aws/dist/utils/error.js"() { - } -}); - -// node_modules/@opennextjs/aws/dist/adapters/logger.js -function debug(...args) { - if (globalThis.openNextDebug) { - console.log(...args); - } -} -function warn(...args) { - console.warn(...args); -} -function error(...args) { - if (args.some((arg) => isDownplayedErrorLog(arg))) { - return debug(...args); - } - if (args.some((arg) => isOpenNextError(arg))) { - const error2 = args.find((arg) => isOpenNextError(arg)); - if (error2.logLevel < getOpenNextErrorLogLevel()) { - return; - } - if (error2.logLevel === 0) { - return console.log(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg)); - } - if (error2.logLevel === 1) { - return warn(...args.map((arg) => isOpenNextError(arg) ? `${arg.name}: ${arg.message}` : arg)); - } - return console.error(...args); - } - console.error(...args); -} -function getOpenNextErrorLogLevel() { - const strLevel = process.env.OPEN_NEXT_ERROR_LOG_LEVEL ?? "1"; - switch (strLevel.toLowerCase()) { - case "debug": - case "0": - return 0; - case "error": - case "2": - return 2; - default: - return 1; - } -} -var DOWNPLAYED_ERROR_LOGS, isDownplayedErrorLog; -var init_logger = __esm({ - "node_modules/@opennextjs/aws/dist/adapters/logger.js"() { - init_error(); - DOWNPLAYED_ERROR_LOGS = [ - { - clientName: "S3Client", - commandName: "GetObjectCommand", - errorName: "NoSuchKey" - } - ]; - isDownplayedErrorLog = (errorLog) => DOWNPLAYED_ERROR_LOGS.some((downplayedInput) => downplayedInput.clientName === errorLog?.clientName && downplayedInput.commandName === errorLog?.commandName && (downplayedInput.errorName === errorLog?.error?.name || downplayedInput.errorName === errorLog?.error?.Code)); - } -}); - -// node_modules/cookie/dist/index.js -var require_dist = __commonJS({ - "node_modules/cookie/dist/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.parseCookie = parseCookie; - exports.parse = parseCookie; - exports.stringifyCookie = stringifyCookie; - exports.stringifySetCookie = stringifySetCookie; - exports.serialize = stringifySetCookie; - exports.parseSetCookie = parseSetCookie; - exports.stringifySetCookie = stringifySetCookie; - exports.serialize = stringifySetCookie; - var cookieNameRegExp = /^[\u0021-\u003A\u003C\u003E-\u007E]+$/; - var cookieValueRegExp = /^[\u0021-\u003A\u003C-\u007E]*$/; - var domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i; - var pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/; - var maxAgeRegExp = /^-?\d+$/; - var __toString = Object.prototype.toString; - var NullObject = /* @__PURE__ */ (() => { - const C = function() { - }; - C.prototype = /* @__PURE__ */ Object.create(null); - return C; - })(); - function parseCookie(str, options) { - const obj = new NullObject(); - const len = str.length; - if (len < 2) - return obj; - const dec = options?.decode || decode; - let index = 0; - do { - const eqIdx = eqIndex(str, index, len); - if (eqIdx === -1) - break; - const endIdx = endIndex(str, index, len); - if (eqIdx > endIdx) { - index = str.lastIndexOf(";", eqIdx - 1) + 1; - continue; - } - const key = valueSlice(str, index, eqIdx); - if (obj[key] === void 0) { - obj[key] = dec(valueSlice(str, eqIdx + 1, endIdx)); - } - index = endIdx + 1; - } while (index < len); - return obj; - } - function stringifyCookie(cookie, options) { - const enc = options?.encode || encodeURIComponent; - const cookieStrings = []; - for (const name of Object.keys(cookie)) { - const val = cookie[name]; - if (val === void 0) - continue; - if (!cookieNameRegExp.test(name)) { - throw new TypeError(`cookie name is invalid: ${name}`); - } - const value = enc(val); - if (!cookieValueRegExp.test(value)) { - throw new TypeError(`cookie val is invalid: ${val}`); - } - cookieStrings.push(`${name}=${value}`); - } - return cookieStrings.join("; "); - } - function stringifySetCookie(_name, _val, _opts) { - const cookie = typeof _name === "object" ? _name : { ..._opts, name: _name, value: String(_val) }; - const options = typeof _val === "object" ? _val : _opts; - const enc = options?.encode || encodeURIComponent; - if (!cookieNameRegExp.test(cookie.name)) { - throw new TypeError(`argument name is invalid: ${cookie.name}`); - } - const value = cookie.value ? enc(cookie.value) : ""; - if (!cookieValueRegExp.test(value)) { - throw new TypeError(`argument val is invalid: ${cookie.value}`); - } - let str = cookie.name + "=" + value; - if (cookie.maxAge !== void 0) { - if (!Number.isInteger(cookie.maxAge)) { - throw new TypeError(`option maxAge is invalid: ${cookie.maxAge}`); - } - str += "; Max-Age=" + cookie.maxAge; - } - if (cookie.domain) { - if (!domainValueRegExp.test(cookie.domain)) { - throw new TypeError(`option domain is invalid: ${cookie.domain}`); - } - str += "; Domain=" + cookie.domain; - } - if (cookie.path) { - if (!pathValueRegExp.test(cookie.path)) { - throw new TypeError(`option path is invalid: ${cookie.path}`); - } - str += "; Path=" + cookie.path; - } - if (cookie.expires) { - if (!isDate(cookie.expires) || !Number.isFinite(cookie.expires.valueOf())) { - throw new TypeError(`option expires is invalid: ${cookie.expires}`); - } - str += "; Expires=" + cookie.expires.toUTCString(); - } - if (cookie.httpOnly) { - str += "; HttpOnly"; - } - if (cookie.secure) { - str += "; Secure"; - } - if (cookie.partitioned) { - str += "; Partitioned"; - } - if (cookie.priority) { - const priority = typeof cookie.priority === "string" ? cookie.priority.toLowerCase() : void 0; - switch (priority) { - case "low": - str += "; Priority=Low"; - break; - case "medium": - str += "; Priority=Medium"; - break; - case "high": - str += "; Priority=High"; - break; - default: - throw new TypeError(`option priority is invalid: ${cookie.priority}`); - } - } - if (cookie.sameSite) { - const sameSite = typeof cookie.sameSite === "string" ? cookie.sameSite.toLowerCase() : cookie.sameSite; - switch (sameSite) { - case true: - case "strict": - str += "; SameSite=Strict"; - break; - case "lax": - str += "; SameSite=Lax"; - break; - case "none": - str += "; SameSite=None"; - break; - default: - throw new TypeError(`option sameSite is invalid: ${cookie.sameSite}`); - } - } - return str; - } - function parseSetCookie(str, options) { - const dec = options?.decode || decode; - const len = str.length; - const endIdx = endIndex(str, 0, len); - const eqIdx = eqIndex(str, 0, endIdx); - const setCookie = eqIdx === -1 ? { name: "", value: dec(valueSlice(str, 0, endIdx)) } : { - name: valueSlice(str, 0, eqIdx), - value: dec(valueSlice(str, eqIdx + 1, endIdx)) - }; - let index = endIdx + 1; - while (index < len) { - const endIdx2 = endIndex(str, index, len); - const eqIdx2 = eqIndex(str, index, endIdx2); - const attr = eqIdx2 === -1 ? valueSlice(str, index, endIdx2) : valueSlice(str, index, eqIdx2); - const val = eqIdx2 === -1 ? void 0 : valueSlice(str, eqIdx2 + 1, endIdx2); - switch (attr.toLowerCase()) { - case "httponly": - setCookie.httpOnly = true; - break; - case "secure": - setCookie.secure = true; - break; - case "partitioned": - setCookie.partitioned = true; - break; - case "domain": - setCookie.domain = val; - break; - case "path": - setCookie.path = val; - break; - case "max-age": - if (val && maxAgeRegExp.test(val)) - setCookie.maxAge = Number(val); - break; - case "expires": - if (!val) - break; - const date = new Date(val); - if (Number.isFinite(date.valueOf())) - setCookie.expires = date; - break; - case "priority": - if (!val) - break; - const priority = val.toLowerCase(); - if (priority === "low" || priority === "medium" || priority === "high") { - setCookie.priority = priority; - } - break; - case "samesite": - if (!val) - break; - const sameSite = val.toLowerCase(); - if (sameSite === "lax" || sameSite === "strict" || sameSite === "none") { - setCookie.sameSite = sameSite; - } - break; - } - index = endIdx2 + 1; - } - return setCookie; - } - function endIndex(str, min, len) { - const index = str.indexOf(";", min); - return index === -1 ? len : index; - } - function eqIndex(str, min, max) { - const index = str.indexOf("=", min); - return index < max ? index : -1; - } - function valueSlice(str, min, max) { - let start = min; - let end = max; - do { - const code = str.charCodeAt(start); - if (code !== 32 && code !== 9) - break; - } while (++start < end); - while (end > start) { - const code = str.charCodeAt(end - 1); - if (code !== 32 && code !== 9) - break; - end--; - } - return str.slice(start, end); - } - function decode(str) { - if (str.indexOf("%") === -1) - return str; - try { - return decodeURIComponent(str); - } catch (e) { - return str; - } - } - function isDate(val) { - return __toString.call(val) === "[object Date]"; - } - } -}); - -// node_modules/@opennextjs/aws/dist/http/util.js -function parseSetCookieHeader(cookies) { - if (!cookies) { - return []; - } - if (typeof cookies === "string") { - return cookies.split(/(? c.trim()); - } - return cookies; -} -function getQueryFromIterator(it) { - const query = {}; - for (const [key, value] of it) { - if (key in query) { - if (Array.isArray(query[key])) { - query[key].push(value); - } else { - query[key] = [query[key], value]; - } - } else { - query[key] = value; - } - } - return query; -} -var init_util = __esm({ - "node_modules/@opennextjs/aws/dist/http/util.js"() { - init_logger(); - } -}); - -// node_modules/@opennextjs/aws/dist/overrides/converters/utils.js -function getQueryFromSearchParams(searchParams) { - return getQueryFromIterator(searchParams.entries()); -} -var init_utils = __esm({ - "node_modules/@opennextjs/aws/dist/overrides/converters/utils.js"() { - init_util(); - } -}); - -// node_modules/@opennextjs/aws/dist/overrides/converters/edge.js -var edge_exports = {}; -__export(edge_exports, { - default: () => edge_default -}); -import { Buffer as Buffer2 } from "node:buffer"; -var import_cookie, NULL_BODY_STATUSES, converter, edge_default; -var init_edge = __esm({ - "node_modules/@opennextjs/aws/dist/overrides/converters/edge.js"() { - import_cookie = __toESM(require_dist(), 1); - init_util(); - init_utils(); - NULL_BODY_STATUSES = /* @__PURE__ */ new Set([101, 103, 204, 205, 304]); - converter = { - convertFrom: async (event) => { - const url = new URL(event.url); - const searchParams = url.searchParams; - const query = getQueryFromSearchParams(searchParams); - const headers = {}; - event.headers.forEach((value, key) => { - headers[key] = value; - }); - const rawPath = url.pathname; - const method = event.method; - const shouldHaveBody = method !== "GET" && method !== "HEAD"; - const body = shouldHaveBody ? Buffer2.from(await event.arrayBuffer()) : void 0; - const cookieHeader = event.headers.get("cookie"); - const cookies = cookieHeader ? import_cookie.default.parse(cookieHeader) : {}; - return { - type: "core", - method, - rawPath, - url: event.url, - body, - headers, - remoteAddress: event.headers.get("x-forwarded-for") ?? "::1", - query, - cookies - }; - }, - convertTo: async (result) => { - if ("internalEvent" in result) { - const request = new Request(result.internalEvent.url, { - body: result.internalEvent.body, - method: result.internalEvent.method, - headers: { - ...result.internalEvent.headers, - "x-forwarded-host": result.internalEvent.headers.host - } - }); - if (globalThis.__dangerous_ON_edge_converter_returns_request === true) { - return request; - } - const cfCache = (result.isISR || result.internalEvent.rawPath.startsWith("/_next/image")) && process.env.DISABLE_CACHE !== "true" ? { cacheEverything: true } : {}; - return fetch(request, { - // This is a hack to make sure that the response is cached by Cloudflare - // See https://developers.cloudflare.com/workers/examples/cache-using-fetch/#caching-html-resources - // @ts-expect-error - This is a Cloudflare specific option - cf: cfCache - }); - } - const headers = new Headers(); - for (const [key, value] of Object.entries(result.headers)) { - if (key === "set-cookie" && typeof value === "string") { - const cookies = parseSetCookieHeader(value); - for (const cookie of cookies) { - headers.append(key, cookie); - } - continue; - } - if (Array.isArray(value)) { - for (const v of value) { - headers.append(key, v); - } - } else { - headers.set(key, value); - } - } - const body = NULL_BODY_STATUSES.has(result.statusCode) ? null : result.body; - return new Response(body, { - status: result.statusCode, - headers - }); - }, - name: "edge" - }; - edge_default = converter; - } -}); - -// node_modules/@opennextjs/aws/dist/overrides/wrappers/cloudflare-edge.js -var cloudflare_edge_exports = {}; -__export(cloudflare_edge_exports, { - default: () => cloudflare_edge_default -}); -var cfPropNameMapping, handler, cloudflare_edge_default; -var init_cloudflare_edge = __esm({ - "node_modules/@opennextjs/aws/dist/overrides/wrappers/cloudflare-edge.js"() { - cfPropNameMapping = { - // The city name is percent-encoded. - // See https://github.com/vercel/vercel/blob/4cb6143/packages/functions/src/headers.ts#L94C19-L94C37 - city: [encodeURIComponent, "x-open-next-city"], - country: "x-open-next-country", - regionCode: "x-open-next-region", - latitude: "x-open-next-latitude", - longitude: "x-open-next-longitude" - }; - handler = async (handler3, converter2) => async (request, env, ctx) => { - globalThis.process = process; - for (const [key, value] of Object.entries(env)) { - if (typeof value === "string") { - process.env[key] = value; - } - } - const internalEvent = await converter2.convertFrom(request); - const cfProperties = request.cf; - for (const [propName, mapping] of Object.entries(cfPropNameMapping)) { - const propValue = cfProperties?.[propName]; - if (propValue != null) { - const [encode, headerName] = Array.isArray(mapping) ? mapping : [null, mapping]; - internalEvent.headers[headerName] = encode ? encode(propValue) : propValue; - } - } - const response = await handler3(internalEvent, { - waitUntil: ctx.waitUntil.bind(ctx) - }); - const result = await converter2.convertTo(response); - return result; - }; - cloudflare_edge_default = { - wrapper: handler, - name: "cloudflare-edge", - supportStreaming: true, - edgeRuntime: true - }; - } -}); - -// node_modules/@opennextjs/aws/dist/overrides/originResolver/pattern-env.js -var pattern_env_exports = {}; -__export(pattern_env_exports, { - default: () => pattern_env_default -}); -function initializeOnce() { - if (initialized) - return; - cachedOrigins = JSON.parse(process.env.OPEN_NEXT_ORIGIN ?? "{}"); - const functions = globalThis.openNextConfig.functions ?? {}; - for (const key in functions) { - if (key !== "default") { - const value = functions[key]; - const regexes = []; - for (const pattern of value.patterns) { - const regexPattern = `/${pattern.replace(/\*\*/g, "(.*)").replace(/\*/g, "([^/]*)").replace(/\//g, "\\/").replace(/\?/g, ".")}`; - regexes.push(new RegExp(regexPattern)); - } - cachedPatterns.push({ - key, - patterns: value.patterns, - regexes - }); - } - } - initialized = true; -} -var cachedOrigins, cachedPatterns, initialized, envLoader, pattern_env_default; -var init_pattern_env = __esm({ - "node_modules/@opennextjs/aws/dist/overrides/originResolver/pattern-env.js"() { - init_logger(); - cachedPatterns = []; - initialized = false; - envLoader = { - name: "env", - resolve: async (_path) => { - try { - initializeOnce(); - for (const { key, patterns, regexes } of cachedPatterns) { - for (const regex of regexes) { - if (regex.test(_path)) { - debug("Using origin", key, patterns); - return cachedOrigins[key]; - } - } - } - if (_path.startsWith("/_next/image") && cachedOrigins.imageOptimizer) { - debug("Using origin", "imageOptimizer", _path); - return cachedOrigins.imageOptimizer; - } - if (cachedOrigins.default) { - debug("Using default origin", cachedOrigins.default, _path); - return cachedOrigins.default; - } - return false; - } catch (e) { - error("Error while resolving origin", e); - return false; - } - } - }; - pattern_env_default = envLoader; - } -}); - -// node_modules/@opennextjs/aws/dist/overrides/assetResolver/dummy.js -var dummy_exports = {}; -__export(dummy_exports, { - default: () => dummy_default -}); -var resolver, dummy_default; -var init_dummy = __esm({ - "node_modules/@opennextjs/aws/dist/overrides/assetResolver/dummy.js"() { - resolver = { - name: "dummy" - }; - dummy_default = resolver; - } -}); - -// node_modules/@opennextjs/aws/dist/utils/stream.js -import { ReadableStream } from "node:stream/web"; -function toReadableStream(value, isBase64) { - return new ReadableStream({ - pull(controller) { - controller.enqueue(Buffer.from(value, isBase64 ? "base64" : "utf8")); - controller.close(); - } - }, { highWaterMark: 0 }); -} -function emptyReadableStream() { - if (process.env.OPEN_NEXT_FORCE_NON_EMPTY_RESPONSE === "true") { - return new ReadableStream({ - pull(controller) { - maybeSomethingBuffer ??= Buffer.from("SOMETHING"); - controller.enqueue(maybeSomethingBuffer); - controller.close(); - } - }, { highWaterMark: 0 }); - } - return new ReadableStream({ - start(controller) { - controller.close(); - } - }); -} -var maybeSomethingBuffer; -var init_stream = __esm({ - "node_modules/@opennextjs/aws/dist/utils/stream.js"() { - } -}); - -// node_modules/@opennextjs/aws/dist/overrides/proxyExternalRequest/fetch.js -var fetch_exports = {}; -__export(fetch_exports, { - default: () => fetch_default -}); -var fetchProxy, fetch_default; -var init_fetch = __esm({ - "node_modules/@opennextjs/aws/dist/overrides/proxyExternalRequest/fetch.js"() { - init_stream(); - fetchProxy = { - name: "fetch-proxy", - // @ts-ignore - proxy: async (internalEvent) => { - const { url, headers: eventHeaders, method, body } = internalEvent; - const headers = Object.fromEntries(Object.entries(eventHeaders).filter(([key]) => key.toLowerCase() !== "cf-connecting-ip")); - const response = await fetch(url, { - method, - headers, - body - }); - const responseHeaders = {}; - response.headers.forEach((value, key) => { - responseHeaders[key] = value; - }); - return { - type: "core", - headers: responseHeaders, - statusCode: response.status, - isBase64Encoded: true, - body: response.body ?? emptyReadableStream() - }; - } - }; - fetch_default = fetchProxy; - } -}); - -// node_modules/@opennextjs/aws/dist/core/edgeFunctionHandler.js -var edgeFunctionHandler_exports = {}; -__export(edgeFunctionHandler_exports, { - default: () => edgeFunctionHandler -}); -async function edgeFunctionHandler(request) { - const path3 = new URL(request.url).pathname; - const routes = globalThis._ROUTES; - const correspondingRoute = routes.find((route) => route.regex.some((r) => new RegExp(r).test(path3))); - if (!correspondingRoute) { - throw new Error(`No route found for ${request.url}`); - } - const entry = await self._ENTRIES[`middleware_${correspondingRoute.name}`]; - const result = await entry.default({ - page: correspondingRoute.page, - request: { - ...request, - page: { - name: correspondingRoute.name - } - } - }); - globalThis.__openNextAls.getStore()?.pendingPromiseRunner.add(result.waitUntil); - const response = result.response; - return response; -} -var init_edgeFunctionHandler = __esm({ - "node_modules/@opennextjs/aws/dist/core/edgeFunctionHandler.js"() { - globalThis._ENTRIES = {}; - globalThis.self = globalThis; - globalThis._ROUTES = []; - } -}); - -// node_modules/@opennextjs/aws/dist/utils/promise.js -init_logger(); -var DetachedPromise = class { - resolve; - reject; - promise; - constructor() { - let resolve; - let reject; - this.promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - this.resolve = resolve; - this.reject = reject; - } -}; -var DetachedPromiseRunner = class { - promises = []; - withResolvers() { - const detachedPromise = new DetachedPromise(); - this.promises.push(detachedPromise); - return detachedPromise; - } - add(promise) { - const detachedPromise = new DetachedPromise(); - this.promises.push(detachedPromise); - promise.then(detachedPromise.resolve, detachedPromise.reject); - } - async await() { - debug(`Awaiting ${this.promises.length} detached promises`); - const results = await Promise.allSettled(this.promises.map((p) => p.promise)); - const rejectedPromises = results.filter((r) => r.status === "rejected"); - rejectedPromises.forEach((r) => { - error(r.reason); - }); - } -}; -async function awaitAllDetachedPromise() { - const store = globalThis.__openNextAls.getStore(); - const promisesToAwait = store?.pendingPromiseRunner.await() ?? Promise.resolve(); - if (store?.waitUntil) { - store.waitUntil(promisesToAwait); - return; - } - await promisesToAwait; -} -function provideNextAfterProvider() { - const NEXT_REQUEST_CONTEXT_SYMBOL = Symbol.for("@next/request-context"); - const VERCEL_REQUEST_CONTEXT_SYMBOL = Symbol.for("@vercel/request-context"); - const store = globalThis.__openNextAls.getStore(); - const waitUntil = store?.waitUntil ?? ((promise) => store?.pendingPromiseRunner.add(promise)); - const nextAfterContext = { - get: () => ({ - waitUntil - }) - }; - globalThis[NEXT_REQUEST_CONTEXT_SYMBOL] = nextAfterContext; - if (process.env.EMULATE_VERCEL_REQUEST_CONTEXT) { - globalThis[VERCEL_REQUEST_CONTEXT_SYMBOL] = nextAfterContext; - } -} -function runWithOpenNextRequestContext({ isISRRevalidation, waitUntil, requestId = Math.random().toString(36) }, fn) { - return globalThis.__openNextAls.run({ - requestId, - pendingPromiseRunner: new DetachedPromiseRunner(), - isISRRevalidation, - waitUntil, - writtenTags: /* @__PURE__ */ new Set() - }, async () => { - provideNextAfterProvider(); - let result; - try { - result = await fn(); - } finally { - await awaitAllDetachedPromise(); - } - return result; - }); -} - -// node_modules/@opennextjs/aws/dist/adapters/middleware.js -init_logger(); - -// node_modules/@opennextjs/aws/dist/core/createGenericHandler.js -init_logger(); - -// node_modules/@opennextjs/aws/dist/core/resolve.js -async function resolveConverter(converter2) { - if (typeof converter2 === "function") { - return converter2(); - } - const m_1 = await Promise.resolve().then(() => (init_edge(), edge_exports)); - return m_1.default; -} -async function resolveWrapper(wrapper) { - if (typeof wrapper === "function") { - return wrapper(); - } - const m_1 = await Promise.resolve().then(() => (init_cloudflare_edge(), cloudflare_edge_exports)); - return m_1.default; -} -async function resolveOriginResolver(originResolver) { - if (typeof originResolver === "function") { - return originResolver(); - } - const m_1 = await Promise.resolve().then(() => (init_pattern_env(), pattern_env_exports)); - return m_1.default; -} -async function resolveAssetResolver(assetResolver) { - if (typeof assetResolver === "function") { - return assetResolver(); - } - const m_1 = await Promise.resolve().then(() => (init_dummy(), dummy_exports)); - return m_1.default; -} -async function resolveProxyRequest(proxyRequest) { - if (typeof proxyRequest === "function") { - return proxyRequest(); - } - const m_1 = await Promise.resolve().then(() => (init_fetch(), fetch_exports)); - return m_1.default; -} - -// node_modules/@opennextjs/aws/dist/core/createGenericHandler.js -async function createGenericHandler(handler3) { - const config = await import("./open-next.config.mjs").then((m) => m.default); - globalThis.openNextConfig = config; - const handlerConfig = config[handler3.type]; - const override = handlerConfig && "override" in handlerConfig ? handlerConfig.override : void 0; - const converter2 = await resolveConverter(override?.converter); - const { name, wrapper } = await resolveWrapper(override?.wrapper); - debug("Using wrapper", name); - return wrapper(handler3.handler, converter2); -} - -// node_modules/@opennextjs/aws/dist/core/routing/util.js -import crypto from "node:crypto"; -import { parse as parseQs, stringify as stringifyQs } from "node:querystring"; - -// node_modules/@opennextjs/aws/dist/adapters/config/index.js -init_logger(); -import path from "node:path"; -globalThis.__dirname ??= ""; -var NEXT_DIR = path.join(__dirname, ".next"); -var OPEN_NEXT_DIR = path.join(__dirname, ".open-next"); -debug({ NEXT_DIR, OPEN_NEXT_DIR }); -var NextConfig = { "env": {}, "webpack": null, "typescript": { "ignoreBuildErrors": false }, "typedRoutes": false, "distDir": ".next", "cleanDistDir": true, "assetPrefix": "", "cacheMaxMemorySize": 52428800, "configOrigin": "next.config.ts", "useFileSystemPublicRoutes": true, "generateEtags": true, "pageExtensions": ["tsx", "ts", "jsx", "js"], "poweredByHeader": true, "compress": true, "images": { "deviceSizes": [640, 750, 828, 1080, 1200, 1920, 2048, 3840], "imageSizes": [32, 48, 64, 96, 128, 256, 384], "path": "/_next/image", "loader": "default", "loaderFile": "", "domains": [], "disableStaticImages": false, "minimumCacheTTL": 14400, "formats": ["image/webp"], "maximumRedirects": 3, "dangerouslyAllowLocalIP": false, "dangerouslyAllowSVG": false, "contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;", "contentDispositionType": "attachment", "localPatterns": [{ "pathname": "**", "search": "" }], "remotePatterns": [{ "protocol": "https", "hostname": "m.media-amazon.com" }], "qualities": [75], "unoptimized": false }, "devIndicators": { "position": "bottom-left" }, "onDemandEntries": { "maxInactiveAge": 6e4, "pagesBufferLength": 5 }, "basePath": "", "sassOptions": {}, "trailingSlash": false, "i18n": null, "productionBrowserSourceMaps": false, "excludeDefaultMomentLocales": true, "reactProductionProfiling": false, "reactStrictMode": null, "reactMaxHeadersLength": 6e3, "httpAgentOptions": { "keepAlive": true }, "logging": {}, "compiler": {}, "expireTime": 31536e3, "staticPageGenerationTimeout": 60, "output": "standalone", "modularizeImports": { "@mui/icons-material": { "transform": "@mui/icons-material/{{member}}" }, "lodash": { "transform": "lodash/{{member}}" } }, "outputFileTracingRoot": "/Users/averyfelts/Documents/dev/quit_smoking_website", "cacheComponents": false, "cacheLife": { "default": { "stale": 300, "revalidate": 900, "expire": 4294967294 }, "seconds": { "stale": 30, "revalidate": 1, "expire": 60 }, "minutes": { "stale": 300, "revalidate": 60, "expire": 3600 }, "hours": { "stale": 300, "revalidate": 3600, "expire": 86400 }, "days": { "stale": 300, "revalidate": 86400, "expire": 604800 }, "weeks": { "stale": 300, "revalidate": 604800, "expire": 2592e3 }, "max": { "stale": 300, "revalidate": 2592e3, "expire": 31536e3 } }, "cacheHandlers": {}, "experimental": { "useSkewCookie": false, "cssChunking": true, "multiZoneDraftMode": false, "appNavFailHandling": false, "prerenderEarlyExit": true, "serverMinification": true, "linkNoTouchStart": false, "caseSensitiveRoutes": false, "dynamicOnHover": false, "preloadEntriesOnStart": true, "clientRouterFilter": true, "clientRouterFilterRedirects": false, "fetchCacheKeyPrefix": "", "proxyPrefetch": "flexible", "optimisticClientCache": true, "manualClientBasePath": false, "cpus": 9, "memoryBasedWorkersCount": false, "imgOptConcurrency": null, "imgOptTimeoutInSeconds": 7, "imgOptMaxInputPixels": 268402689, "imgOptSequentialRead": null, "imgOptSkipMetadata": null, "isrFlushToDisk": true, "workerThreads": false, "optimizeCss": false, "nextScriptWorkers": false, "scrollRestoration": false, "externalDir": false, "disableOptimizedLoading": false, "gzipSize": true, "craCompat": false, "esmExternals": true, "fullySpecified": false, "swcTraceProfiling": false, "forceSwcTransforms": false, "largePageDataBytes": 128e3, "typedEnv": false, "parallelServerCompiles": false, "parallelServerBuildTraces": false, "ppr": false, "authInterrupts": false, "webpackMemoryOptimizations": false, "optimizeServerReact": true, "viewTransition": false, "removeUncaughtErrorAndRejectionListeners": false, "validateRSCRequestHeaders": false, "staleTimes": { "dynamic": 0, "static": 300 }, "reactDebugChannel": false, "serverComponentsHmrCache": true, "staticGenerationMaxConcurrency": 8, "staticGenerationMinPagesPerWorker": 25, "transitionIndicator": false, "inlineCss": false, "useCache": false, "globalNotFound": false, "browserDebugInfoInTerminal": false, "lockDistDir": true, "isolatedDevBuild": true, "proxyClientMaxBodySize": 10485760, "hideLogsAfterAbort": false, "mcpServer": true, "turbopackFileSystemCacheForDev": true, "turbopackFileSystemCacheForBuild": false, "turbopackInferModuleSideEffects": false, "optimizePackageImports": ["lucide-react", "date-fns", "lodash-es", "ramda", "antd", "react-bootstrap", "ahooks", "@ant-design/icons", "@headlessui/react", "@headlessui-float/react", "@heroicons/react/20/solid", "@heroicons/react/24/solid", "@heroicons/react/24/outline", "@visx/visx", "@tremor/react", "rxjs", "@mui/material", "@mui/icons-material", "recharts", "react-use", "effect", "@effect/schema", "@effect/platform", "@effect/platform-node", "@effect/platform-browser", "@effect/platform-bun", "@effect/sql", "@effect/sql-mssql", "@effect/sql-mysql2", "@effect/sql-pg", "@effect/sql-sqlite-node", "@effect/sql-sqlite-bun", "@effect/sql-sqlite-wasm", "@effect/sql-sqlite-react-native", "@effect/rpc", "@effect/rpc-http", "@effect/typeclass", "@effect/experimental", "@effect/opentelemetry", "@material-ui/core", "@material-ui/icons", "@tabler/icons-react", "mui-core", "react-icons/ai", "react-icons/bi", "react-icons/bs", "react-icons/cg", "react-icons/ci", "react-icons/di", "react-icons/fa", "react-icons/fa6", "react-icons/fc", "react-icons/fi", "react-icons/gi", "react-icons/go", "react-icons/gr", "react-icons/hi", "react-icons/hi2", "react-icons/im", "react-icons/io", "react-icons/io5", "react-icons/lia", "react-icons/lib", "react-icons/lu", "react-icons/md", "react-icons/pi", "react-icons/ri", "react-icons/rx", "react-icons/si", "react-icons/sl", "react-icons/tb", "react-icons/tfi", "react-icons/ti", "react-icons/vsc", "react-icons/wi"], "trustHostHeader": false, "isExperimentalCompile": false }, "htmlLimitedBots": "[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight", "bundlePagesRouterDependencies": false, "configFileName": "next.config.ts", "turbopack": { "root": "/Users/averyfelts/Documents/dev/quit_smoking_website" }, "distDirRoot": ".next" }; -var BuildId = "Bi3XXPy0fxaJxYXDBsshm"; -var RoutesManifest = { "basePath": "", "rewrites": { "beforeFiles": [], "afterFiles": [], "fallback": [] }, "redirects": [{ "source": "/:path+/", "destination": "/:path+", "internal": true, "priority": true, "statusCode": 308, "regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$" }], "routes": { "static": [{ "page": "/", "regex": "^/(?:/)?$", "routeKeys": {}, "namedRegex": "^/(?:/)?$" }, { "page": "/_global-error", "regex": "^/_global\\-error(?:/)?$", "routeKeys": {}, "namedRegex": "^/_global\\-error(?:/)?$" }, { "page": "/_not-found", "regex": "^/_not\\-found(?:/)?$", "routeKeys": {}, "namedRegex": "^/_not\\-found(?:/)?$" }, { "page": "/api/achievements", "regex": "^/api/achievements(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/achievements(?:/)?$" }, { "page": "/api/auth/callback", "regex": "^/api/auth/callback(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/auth/callback(?:/)?$" }, { "page": "/api/auth/login", "regex": "^/api/auth/login(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/auth/login(?:/)?$" }, { "page": "/api/auth/logout", "regex": "^/api/auth/logout(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/auth/logout(?:/)?$" }, { "page": "/api/cron/reminders", "regex": "^/api/cron/reminders(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/cron/reminders(?:/)?$" }, { "page": "/api/mood", "regex": "^/api/mood(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/mood(?:/)?$" }, { "page": "/api/notifications/subscribe", "regex": "^/api/notifications/subscribe(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/notifications/subscribe(?:/)?$" }, { "page": "/api/notifications/test", "regex": "^/api/notifications/test(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/notifications/test(?:/)?$" }, { "page": "/api/preferences", "regex": "^/api/preferences(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/preferences(?:/)?$" }, { "page": "/api/reminders", "regex": "^/api/reminders(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/reminders(?:/)?$" }, { "page": "/api/savings", "regex": "^/api/savings(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/savings(?:/)?$" }, { "page": "/api/usage", "regex": "^/api/usage(?:/)?$", "routeKeys": {}, "namedRegex": "^/api/usage(?:/)?$" }, { "page": "/callback", "regex": "^/callback(?:/)?$", "routeKeys": {}, "namedRegex": "^/callback(?:/)?$" }, { "page": "/login", "regex": "^/login(?:/)?$", "routeKeys": {}, "namedRegex": "^/login(?:/)?$" }, { "page": "/signout", "regex": "^/signout(?:/)?$", "routeKeys": {}, "namedRegex": "^/signout(?:/)?$" }, { "page": "/smoking-aids", "regex": "^/smoking\\-aids(?:/)?$", "routeKeys": {}, "namedRegex": "^/smoking\\-aids(?:/)?$" }, { "page": "/track/marijuana", "regex": "^/track/marijuana(?:/)?$", "routeKeys": {}, "namedRegex": "^/track/marijuana(?:/)?$" }, { "page": "/track/nicotine", "regex": "^/track/nicotine(?:/)?$", "routeKeys": {}, "namedRegex": "^/track/nicotine(?:/)?$" }], "dynamic": [], "data": { "static": [], "dynamic": [] } }, "locales": [] }; -var ConfigHeaders = []; -var PrerenderManifest = { "version": 4, "routes": { "/_global-error": { "experimentalBypassFor": [{ "type": "header", "key": "next-action" }, { "type": "header", "key": "content-type", "value": "multipart/form-data;.*" }], "initialRevalidateSeconds": false, "srcRoute": "/_global-error", "dataRoute": "/_global-error.rsc", "allowHeader": ["host", "x-matched-path", "x-prerender-revalidate", "x-prerender-revalidate-if-generated", "x-next-revalidated-tags", "x-next-revalidate-tag-token"] }, "/_not-found": { "initialStatus": 404, "experimentalBypassFor": [{ "type": "header", "key": "next-action" }, { "type": "header", "key": "content-type", "value": "multipart/form-data;.*" }], "initialRevalidateSeconds": false, "srcRoute": "/_not-found", "dataRoute": "/_not-found.rsc", "allowHeader": ["host", "x-matched-path", "x-prerender-revalidate", "x-prerender-revalidate-if-generated", "x-next-revalidated-tags", "x-next-revalidate-tag-token"] }, "/login": { "experimentalBypassFor": [{ "type": "header", "key": "next-action" }, { "type": "header", "key": "content-type", "value": "multipart/form-data;.*" }], "initialRevalidateSeconds": false, "srcRoute": "/login", "dataRoute": "/login.rsc", "allowHeader": ["host", "x-matched-path", "x-prerender-revalidate", "x-prerender-revalidate-if-generated", "x-next-revalidated-tags", "x-next-revalidate-tag-token"] } }, "dynamicRoutes": {}, "notFoundRoutes": [], "preview": { "previewModeId": "9212b8c54d8f2aaa5cb15dca46a16684", "previewModeSigningKey": "970022af34c137d34636787754aa5b8e46159f8524197b5b3d66d7ace9ce3c6a", "previewModeEncryptionKey": "d6060e1793fa715d98400804ca07bb25f76906348149090433c9ce4ce78f050a" } }; -var MiddlewareManifest = { "version": 3, "middleware": {}, "sortedMiddleware": [], "functions": {} }; -var AppPathRoutesManifest = { "/_global-error/page": "/_global-error", "/_not-found/page": "/_not-found", "/api/achievements/route": "/api/achievements", "/api/auth/callback/route": "/api/auth/callback", "/api/auth/login/route": "/api/auth/login", "/api/auth/logout/route": "/api/auth/logout", "/api/cron/reminders/route": "/api/cron/reminders", "/api/mood/route": "/api/mood", "/api/notifications/subscribe/route": "/api/notifications/subscribe", "/api/notifications/test/route": "/api/notifications/test", "/api/preferences/route": "/api/preferences", "/api/reminders/route": "/api/reminders", "/api/savings/route": "/api/savings", "/api/usage/route": "/api/usage", "/callback/route": "/callback", "/login/page": "/login", "/page": "/", "/signout/page": "/signout", "/smoking-aids/page": "/smoking-aids", "/track/marijuana/page": "/track/marijuana", "/track/nicotine/page": "/track/nicotine" }; -var FunctionsConfigManifest = { "version": 1, "functions": {} }; -var PagesManifest = { "/404": "pages/404.html", "/500": "pages/500.html" }; -process.env.NEXT_BUILD_ID = BuildId; -process.env.NEXT_PREVIEW_MODE_ID = PrerenderManifest?.preview?.previewModeId; - -// node_modules/@opennextjs/aws/dist/http/openNextResponse.js -init_logger(); -init_util(); -import { Transform } from "node:stream"; - -// node_modules/@opennextjs/aws/dist/core/routing/util.js -init_util(); -init_logger(); -import { ReadableStream as ReadableStream2 } from "node:stream/web"; - -// node_modules/@opennextjs/aws/dist/utils/binary.js -var commonBinaryMimeTypes = /* @__PURE__ */ new Set([ - "application/octet-stream", - // Docs - "application/epub+zip", - "application/msword", - "application/pdf", - "application/rtf", - "application/vnd.amazon.ebook", - "application/vnd.ms-excel", - "application/vnd.ms-powerpoint", - "application/vnd.openxmlformats-officedocument.presentationml.presentation", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - // Fonts - "font/otf", - "font/woff", - "font/woff2", - // Images - "image/bmp", - "image/gif", - "image/jpeg", - "image/png", - "image/tiff", - "image/vnd.microsoft.icon", - "image/webp", - // Audio - "audio/3gpp", - "audio/aac", - "audio/basic", - "audio/flac", - "audio/mpeg", - "audio/ogg", - "audio/wavaudio/webm", - "audio/x-aiff", - "audio/x-midi", - "audio/x-wav", - // Video - "video/3gpp", - "video/mp2t", - "video/mpeg", - "video/ogg", - "video/quicktime", - "video/webm", - "video/x-msvideo", - // Archives - "application/java-archive", - "application/vnd.apple.installer+xml", - "application/x-7z-compressed", - "application/x-apple-diskimage", - "application/x-bzip", - "application/x-bzip2", - "application/x-gzip", - "application/x-java-archive", - "application/x-rar-compressed", - "application/x-tar", - "application/x-zip", - "application/zip", - // Serialized data - "application/x-protobuf" -]); -function isBinaryContentType(contentType) { - if (!contentType) - return false; - const value = contentType.split(";")[0]; - return commonBinaryMimeTypes.has(value); -} - -// node_modules/@opennextjs/aws/dist/core/routing/i18n/index.js -init_stream(); -init_logger(); - -// node_modules/@opennextjs/aws/dist/core/routing/i18n/accept-header.js -function parse(raw, preferences, options) { - const lowers = /* @__PURE__ */ new Map(); - const header = raw.replace(/[ \t]/g, ""); - if (preferences) { - let pos = 0; - for (const preference of preferences) { - const lower = preference.toLowerCase(); - lowers.set(lower, { orig: preference, pos: pos++ }); - if (options.prefixMatch) { - const parts2 = lower.split("-"); - while (parts2.pop(), parts2.length > 0) { - const joined = parts2.join("-"); - if (!lowers.has(joined)) { - lowers.set(joined, { orig: preference, pos: pos++ }); - } - } - } - } - } - const parts = header.split(","); - const selections = []; - const map = /* @__PURE__ */ new Set(); - for (let i = 0; i < parts.length; ++i) { - const part = parts[i]; - if (!part) { - continue; - } - const params = part.split(";"); - if (params.length > 2) { - throw new Error(`Invalid ${options.type} header`); - } - const token = params[0].toLowerCase(); - if (!token) { - throw new Error(`Invalid ${options.type} header`); - } - const selection = { token, pos: i, q: 1 }; - if (preferences && lowers.has(token)) { - selection.pref = lowers.get(token).pos; - } - map.add(selection.token); - if (params.length === 2) { - const q = params[1]; - const [key, value] = q.split("="); - if (!value || key !== "q" && key !== "Q") { - throw new Error(`Invalid ${options.type} header`); - } - const score = Number.parseFloat(value); - if (score === 0) { - continue; - } - if (Number.isFinite(score) && score <= 1 && score >= 1e-3) { - selection.q = score; - } - } - selections.push(selection); - } - selections.sort((a, b) => { - if (b.q !== a.q) { - return b.q - a.q; - } - if (b.pref !== a.pref) { - if (a.pref === void 0) { - return 1; - } - if (b.pref === void 0) { - return -1; - } - return a.pref - b.pref; - } - return a.pos - b.pos; - }); - const values = selections.map((selection) => selection.token); - if (!preferences || !preferences.length) { - return values; - } - const preferred = []; - for (const selection of values) { - if (selection === "*") { - for (const [preference, value] of lowers) { - if (!map.has(preference)) { - preferred.push(value.orig); - } - } - } else { - const lower = selection.toLowerCase(); - if (lowers.has(lower)) { - preferred.push(lowers.get(lower).orig); - } - } - } - return preferred; -} -function acceptLanguage(header = "", preferences) { - return parse(header, preferences, { - type: "accept-language", - prefixMatch: true - })[0] || void 0; -} - -// node_modules/@opennextjs/aws/dist/core/routing/i18n/index.js -function isLocalizedPath(path3) { - return NextConfig.i18n?.locales.includes(path3.split("/")[1].toLowerCase()) ?? false; -} -function getLocaleFromCookie(cookies) { - const i18n = NextConfig.i18n; - const nextLocale = cookies.NEXT_LOCALE?.toLowerCase(); - return nextLocale ? i18n?.locales.find((locale) => nextLocale === locale.toLowerCase()) : void 0; -} -function detectDomainLocale({ hostname, detectedLocale }) { - const i18n = NextConfig.i18n; - const domains = i18n?.domains; - if (!domains) { - return; - } - const lowercasedLocale = detectedLocale?.toLowerCase(); - for (const domain of domains) { - const domainHostname = domain.domain.split(":", 1)[0].toLowerCase(); - if (hostname === domainHostname || lowercasedLocale === domain.defaultLocale.toLowerCase() || domain.locales?.some((locale) => lowercasedLocale === locale.toLowerCase())) { - return domain; - } - } -} -function detectLocale(internalEvent, i18n) { - const domainLocale = detectDomainLocale({ - hostname: internalEvent.headers.host - }); - if (i18n.localeDetection === false) { - return domainLocale?.defaultLocale ?? i18n.defaultLocale; - } - const cookiesLocale = getLocaleFromCookie(internalEvent.cookies); - const preferredLocale = acceptLanguage(internalEvent.headers["accept-language"], i18n?.locales); - debug({ - cookiesLocale, - preferredLocale, - defaultLocale: i18n.defaultLocale, - domainLocale - }); - return domainLocale?.defaultLocale ?? cookiesLocale ?? preferredLocale ?? i18n.defaultLocale; -} -function localizePath(internalEvent) { - const i18n = NextConfig.i18n; - if (!i18n) { - return internalEvent.rawPath; - } - if (isLocalizedPath(internalEvent.rawPath)) { - return internalEvent.rawPath; - } - const detectedLocale = detectLocale(internalEvent, i18n); - return `/${detectedLocale}${internalEvent.rawPath}`; -} -function handleLocaleRedirect(internalEvent) { - const i18n = NextConfig.i18n; - if (!i18n || i18n.localeDetection === false || internalEvent.rawPath !== "/") { - return false; - } - const preferredLocale = acceptLanguage(internalEvent.headers["accept-language"], i18n?.locales); - const detectedLocale = detectLocale(internalEvent, i18n); - const domainLocale = detectDomainLocale({ - hostname: internalEvent.headers.host - }); - const preferredDomain = detectDomainLocale({ - detectedLocale: preferredLocale - }); - if (domainLocale && preferredDomain) { - const isPDomain = preferredDomain.domain === domainLocale.domain; - const isPLocale = preferredDomain.defaultLocale === preferredLocale; - if (!isPDomain || !isPLocale) { - const scheme = `http${preferredDomain.http ? "" : "s"}`; - const rlocale = isPLocale ? "" : preferredLocale; - return { - type: "core", - statusCode: 307, - headers: { - Location: `${scheme}://${preferredDomain.domain}/${rlocale}` - }, - body: emptyReadableStream(), - isBase64Encoded: false - }; - } - } - const defaultLocale = domainLocale?.defaultLocale ?? i18n.defaultLocale; - if (detectedLocale.toLowerCase() !== defaultLocale.toLowerCase()) { - return { - type: "core", - statusCode: 307, - headers: { - Location: constructNextUrl(internalEvent.url, `/${detectedLocale}`) - }, - body: emptyReadableStream(), - isBase64Encoded: false - }; - } - return false; -} - -// node_modules/@opennextjs/aws/dist/core/routing/queue.js -function generateShardId(rawPath, maxConcurrency, prefix) { - let a = cyrb128(rawPath); - let t = a += 1831565813; - t = Math.imul(t ^ t >>> 15, t | 1); - t ^= t + Math.imul(t ^ t >>> 7, t | 61); - const randomFloat = ((t ^ t >>> 14) >>> 0) / 4294967296; - const randomInt = Math.floor(randomFloat * maxConcurrency); - return `${prefix}-${randomInt}`; -} -function generateMessageGroupId(rawPath) { - const maxConcurrency = Number.parseInt(process.env.MAX_REVALIDATE_CONCURRENCY ?? "10"); - return generateShardId(rawPath, maxConcurrency, "revalidate"); -} -function cyrb128(str) { - let h1 = 1779033703; - let h2 = 3144134277; - let h3 = 1013904242; - let h4 = 2773480762; - for (let i = 0, k; i < str.length; i++) { - k = str.charCodeAt(i); - h1 = h2 ^ Math.imul(h1 ^ k, 597399067); - h2 = h3 ^ Math.imul(h2 ^ k, 2869860233); - h3 = h4 ^ Math.imul(h3 ^ k, 951274213); - h4 = h1 ^ Math.imul(h4 ^ k, 2716044179); - } - h1 = Math.imul(h3 ^ h1 >>> 18, 597399067); - h2 = Math.imul(h4 ^ h2 >>> 22, 2869860233); - h3 = Math.imul(h1 ^ h3 >>> 17, 951274213); - h4 = Math.imul(h2 ^ h4 >>> 19, 2716044179); - h1 ^= h2 ^ h3 ^ h4, h2 ^= h1, h3 ^= h1, h4 ^= h1; - return h1 >>> 0; -} - -// node_modules/@opennextjs/aws/dist/core/routing/util.js -function isExternal(url, host) { - if (!url) - return false; - const pattern = /^https?:\/\//; - if (!pattern.test(url)) - return false; - if (host) { - try { - const parsedUrl = new URL(url); - return parsedUrl.host !== host; - } catch { - return !url.includes(host); - } - } - return true; -} -function convertFromQueryString(query) { - if (query === "") - return {}; - const queryParts = query.split("&"); - return getQueryFromIterator(queryParts.map((p) => { - const [key, value] = p.split("="); - return [key, value]; - })); -} -function getUrlParts(url, isExternal2) { - if (!isExternal2) { - const regex2 = /\/([^?]*)\??(.*)/; - const match3 = url.match(regex2); - return { - hostname: "", - pathname: match3?.[1] ? `/${match3[1]}` : url, - protocol: "", - queryString: match3?.[2] ?? "" - }; - } - const regex = /^(https?:)\/\/?([^\/\s]+)(\/[^?]*)?(\?.*)?/; - const match2 = url.match(regex); - if (!match2) { - throw new Error(`Invalid external URL: ${url}`); - } - return { - protocol: match2[1] ?? "https:", - hostname: match2[2], - pathname: match2[3] ?? "", - queryString: match2[4]?.slice(1) ?? "" - }; -} -function constructNextUrl(baseUrl, path3) { - const nextBasePath = NextConfig.basePath ?? ""; - const url = new URL(`${nextBasePath}${path3}`, baseUrl); - return url.href; -} -function convertToQueryString(query) { - const queryStrings = []; - Object.entries(query).forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach((entry) => queryStrings.push(`${key}=${entry}`)); - } else { - queryStrings.push(`${key}=${value}`); - } - }); - return queryStrings.length > 0 ? `?${queryStrings.join("&")}` : ""; -} -function getMiddlewareMatch(middlewareManifest2, functionsManifest) { - if (functionsManifest?.functions?.["/_middleware"]) { - return functionsManifest.functions["/_middleware"].matchers?.map(({ regexp }) => new RegExp(regexp)) ?? [/.*/]; - } - const rootMiddleware = middlewareManifest2.middleware["/"]; - if (!rootMiddleware?.matchers) - return []; - return rootMiddleware.matchers.map(({ regexp }) => new RegExp(regexp)); -} -function escapeRegex(str, { isPath } = {}) { - const result = str.replaceAll("(.)", "_\xB51_").replaceAll("(..)", "_\xB52_").replaceAll("(...)", "_\xB53_"); - return isPath ? result : result.replaceAll("+", "_\xB54_"); -} -function unescapeRegex(str) { - return str.replaceAll("_\xB51_", "(.)").replaceAll("_\xB52_", "(..)").replaceAll("_\xB53_", "(...)").replaceAll("_\xB54_", "+"); -} -function convertBodyToReadableStream(method, body) { - if (method === "GET" || method === "HEAD") - return void 0; - if (!body) - return void 0; - return new ReadableStream2({ - start(controller) { - controller.enqueue(body); - controller.close(); - } - }); -} -var CommonHeaders; -(function(CommonHeaders2) { - CommonHeaders2["CACHE_CONTROL"] = "cache-control"; - CommonHeaders2["NEXT_CACHE"] = "x-nextjs-cache"; -})(CommonHeaders || (CommonHeaders = {})); -function normalizeLocationHeader(location, baseUrl, encodeQuery = false) { - if (!URL.canParse(location)) { - return location; - } - const locationURL = new URL(location); - const origin = new URL(baseUrl).origin; - let search = locationURL.search; - if (encodeQuery && search) { - search = `?${stringifyQs(parseQs(search.slice(1)))}`; - } - const href = `${locationURL.origin}${locationURL.pathname}${search}${locationURL.hash}`; - if (locationURL.origin === origin) { - return href.slice(origin.length); - } - return href; -} - -// node_modules/@opennextjs/aws/dist/core/routingHandler.js -init_logger(); - -// node_modules/@opennextjs/aws/dist/core/routing/cacheInterceptor.js -import { createHash } from "node:crypto"; -init_stream(); - -// node_modules/@opennextjs/aws/dist/utils/cache.js -init_logger(); -async function hasBeenRevalidated(key, tags, cacheEntry) { - if (globalThis.openNextConfig.dangerous?.disableTagCache) { - return false; - } - const value = cacheEntry.value; - if (!value) { - return true; - } - if ("type" in cacheEntry && cacheEntry.type === "page") { - return false; - } - const lastModified = cacheEntry.lastModified ?? Date.now(); - if (globalThis.tagCache.mode === "nextMode") { - return tags.length === 0 ? false : await globalThis.tagCache.hasBeenRevalidated(tags, lastModified); - } - const _lastModified = await globalThis.tagCache.getLastModified(key, lastModified); - return _lastModified === -1; -} -function getTagsFromValue(value) { - if (!value) { - return []; - } - try { - const cacheTags = value.meta?.headers?.["x-next-cache-tags"]?.split(",") ?? []; - delete value.meta?.headers?.["x-next-cache-tags"]; - return cacheTags; - } catch (e) { - return []; - } -} - -// node_modules/@opennextjs/aws/dist/core/routing/cacheInterceptor.js -init_logger(); -var CACHE_ONE_YEAR = 60 * 60 * 24 * 365; -var CACHE_ONE_MONTH = 60 * 60 * 24 * 30; -var VARY_HEADER = "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Next-Url"; -var NEXT_SEGMENT_PREFETCH_HEADER = "next-router-segment-prefetch"; -var NEXT_PRERENDER_HEADER = "x-nextjs-prerender"; -var NEXT_POSTPONED_HEADER = "x-nextjs-postponed"; -async function computeCacheControl(path3, body, host, revalidate, lastModified) { - let finalRevalidate = CACHE_ONE_YEAR; - const existingRoute = Object.entries(PrerenderManifest?.routes ?? {}).find((p) => p[0] === path3)?.[1]; - if (revalidate === void 0 && existingRoute) { - finalRevalidate = existingRoute.initialRevalidateSeconds === false ? CACHE_ONE_YEAR : existingRoute.initialRevalidateSeconds; - } else if (revalidate !== void 0) { - finalRevalidate = revalidate === false ? CACHE_ONE_YEAR : revalidate; - } - const age = Math.round((Date.now() - (lastModified ?? 0)) / 1e3); - const hash = (str) => createHash("md5").update(str).digest("hex"); - const etag = hash(body); - if (revalidate === 0) { - return { - "cache-control": "private, no-cache, no-store, max-age=0, must-revalidate", - "x-opennext-cache": "ERROR", - etag - }; - } - if (finalRevalidate !== CACHE_ONE_YEAR) { - const sMaxAge = Math.max(finalRevalidate - age, 1); - debug("sMaxAge", { - finalRevalidate, - age, - lastModified, - revalidate - }); - const isStale = sMaxAge === 1; - if (isStale) { - let url = NextConfig.trailingSlash ? `${path3}/` : path3; - if (NextConfig.basePath) { - url = `${NextConfig.basePath}${url}`; - } - await globalThis.queue.send({ - MessageBody: { - host, - url, - eTag: etag, - lastModified: lastModified ?? Date.now() - }, - MessageDeduplicationId: hash(`${path3}-${lastModified}-${etag}`), - MessageGroupId: generateMessageGroupId(path3) - }); - } - return { - "cache-control": `s-maxage=${sMaxAge}, stale-while-revalidate=${CACHE_ONE_MONTH}`, - "x-opennext-cache": isStale ? "STALE" : "HIT", - etag - }; - } - return { - "cache-control": `s-maxage=${CACHE_ONE_YEAR}, stale-while-revalidate=${CACHE_ONE_MONTH}`, - "x-opennext-cache": "HIT", - etag - }; -} -function getBodyForAppRouter(event, cachedValue) { - if (cachedValue.type !== "app") { - throw new Error("getBodyForAppRouter called with non-app cache value"); - } - try { - const segmentHeader = `${event.headers[NEXT_SEGMENT_PREFETCH_HEADER]}`; - const isSegmentResponse = Boolean(segmentHeader) && segmentHeader in (cachedValue.segmentData || {}); - const body = isSegmentResponse ? cachedValue.segmentData[segmentHeader] : cachedValue.rsc; - return { - body, - additionalHeaders: isSegmentResponse ? { [NEXT_PRERENDER_HEADER]: "1", [NEXT_POSTPONED_HEADER]: "2" } : {} - }; - } catch (e) { - error("Error while getting body for app router from cache:", e); - return { body: cachedValue.rsc, additionalHeaders: {} }; - } -} -async function generateResult(event, localizedPath, cachedValue, lastModified) { - debug("Returning result from experimental cache"); - let body = ""; - let type = "application/octet-stream"; - let isDataRequest = false; - let additionalHeaders = {}; - if (cachedValue.type === "app") { - isDataRequest = Boolean(event.headers.rsc); - if (isDataRequest) { - const { body: appRouterBody, additionalHeaders: appHeaders } = getBodyForAppRouter(event, cachedValue); - body = appRouterBody; - additionalHeaders = appHeaders; - } else { - body = cachedValue.html; - } - type = isDataRequest ? "text/x-component" : "text/html; charset=utf-8"; - } else if (cachedValue.type === "page") { - isDataRequest = Boolean(event.query.__nextDataReq); - body = isDataRequest ? JSON.stringify(cachedValue.json) : cachedValue.html; - type = isDataRequest ? "application/json" : "text/html; charset=utf-8"; - } else { - throw new Error("generateResult called with unsupported cache value type, only 'app' and 'page' are supported"); - } - const cacheControl = await computeCacheControl(localizedPath, body, event.headers.host, cachedValue.revalidate, lastModified); - return { - type: "core", - // Sometimes other status codes can be cached, like 404. For these cases, we should return the correct status code - // Also set the status code to the rewriteStatusCode if defined - // This can happen in handleMiddleware in routingHandler. - // `NextResponse.rewrite(url, { status: xxx}) - // The rewrite status code should take precedence over the cached one - statusCode: event.rewriteStatusCode ?? cachedValue.meta?.status ?? 200, - body: toReadableStream(body, false), - isBase64Encoded: false, - headers: { - ...cacheControl, - "content-type": type, - ...cachedValue.meta?.headers, - vary: VARY_HEADER, - ...additionalHeaders - } - }; -} -function escapePathDelimiters(segment, escapeEncoded) { - return segment.replace(new RegExp(`([/#?]${escapeEncoded ? "|%(2f|23|3f|5c)" : ""})`, "gi"), (char) => encodeURIComponent(char)); -} -function decodePathParams(pathname) { - return pathname.split("/").map((segment) => { - try { - return escapePathDelimiters(decodeURIComponent(segment), true); - } catch (e) { - return segment; - } - }).join("/"); -} -async function cacheInterceptor(event) { - if (Boolean(event.headers["next-action"]) || Boolean(event.headers["x-prerender-revalidate"])) - return event; - const cookies = event.headers.cookie || ""; - const hasPreviewData = cookies.includes("__prerender_bypass") || cookies.includes("__next_preview_data"); - if (hasPreviewData) { - debug("Preview mode detected, passing through to handler"); - return event; - } - let localizedPath = localizePath(event); - if (NextConfig.basePath) { - localizedPath = localizedPath.replace(NextConfig.basePath, ""); - } - localizedPath = localizedPath.replace(/\/$/, ""); - localizedPath = decodePathParams(localizedPath); - debug("Checking cache for", localizedPath, PrerenderManifest); - const isISR = Object.keys(PrerenderManifest?.routes ?? {}).includes(localizedPath ?? "/") || Object.values(PrerenderManifest?.dynamicRoutes ?? {}).some((dr) => new RegExp(dr.routeRegex).test(localizedPath)); - debug("isISR", isISR); - if (isISR) { - try { - const cachedData = await globalThis.incrementalCache.get(localizedPath ?? "/index"); - debug("cached data in interceptor", cachedData); - if (!cachedData?.value) { - return event; - } - if (cachedData.value?.type === "app" || cachedData.value?.type === "route") { - const tags = getTagsFromValue(cachedData.value); - const _hasBeenRevalidated = cachedData.shouldBypassTagCache ? false : await hasBeenRevalidated(localizedPath, tags, cachedData); - if (_hasBeenRevalidated) { - return event; - } - } - const host = event.headers.host; - switch (cachedData?.value?.type) { - case "app": - case "page": - return generateResult(event, localizedPath, cachedData.value, cachedData.lastModified); - case "redirect": { - const cacheControl = await computeCacheControl(localizedPath, "", host, cachedData.value.revalidate, cachedData.lastModified); - return { - type: "core", - statusCode: cachedData.value.meta?.status ?? 307, - body: emptyReadableStream(), - headers: { - ...cachedData.value.meta?.headers ?? {}, - ...cacheControl - }, - isBase64Encoded: false - }; - } - case "route": { - const cacheControl = await computeCacheControl(localizedPath, cachedData.value.body, host, cachedData.value.revalidate, cachedData.lastModified); - const isBinary = isBinaryContentType(String(cachedData.value.meta?.headers?.["content-type"])); - return { - type: "core", - statusCode: event.rewriteStatusCode ?? cachedData.value.meta?.status ?? 200, - body: toReadableStream(cachedData.value.body, isBinary), - headers: { - ...cacheControl, - ...cachedData.value.meta?.headers, - vary: VARY_HEADER - }, - isBase64Encoded: isBinary - }; - } - default: - return event; - } - } catch (e) { - debug("Error while fetching cache", e); - return event; - } - } - return event; -} - -// node_modules/path-to-regexp/dist.es2015/index.js -function lexer(str) { - var tokens = []; - var i = 0; - while (i < str.length) { - var char = str[i]; - if (char === "*" || char === "+" || char === "?") { - tokens.push({ type: "MODIFIER", index: i, value: str[i++] }); - continue; - } - if (char === "\\") { - tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] }); - continue; - } - if (char === "{") { - tokens.push({ type: "OPEN", index: i, value: str[i++] }); - continue; - } - if (char === "}") { - tokens.push({ type: "CLOSE", index: i, value: str[i++] }); - continue; - } - if (char === ":") { - var name = ""; - var j = i + 1; - while (j < str.length) { - var code = str.charCodeAt(j); - if ( - // `0-9` - code >= 48 && code <= 57 || // `A-Z` - code >= 65 && code <= 90 || // `a-z` - code >= 97 && code <= 122 || // `_` - code === 95 - ) { - name += str[j++]; - continue; - } - break; - } - if (!name) - throw new TypeError("Missing parameter name at ".concat(i)); - tokens.push({ type: "NAME", index: i, value: name }); - i = j; - continue; - } - if (char === "(") { - var count = 1; - var pattern = ""; - var j = i + 1; - if (str[j] === "?") { - throw new TypeError('Pattern cannot start with "?" at '.concat(j)); - } - while (j < str.length) { - if (str[j] === "\\") { - pattern += str[j++] + str[j++]; - continue; - } - if (str[j] === ")") { - count--; - if (count === 0) { - j++; - break; - } - } else if (str[j] === "(") { - count++; - if (str[j + 1] !== "?") { - throw new TypeError("Capturing groups are not allowed at ".concat(j)); - } - } - pattern += str[j++]; - } - if (count) - throw new TypeError("Unbalanced pattern at ".concat(i)); - if (!pattern) - throw new TypeError("Missing pattern at ".concat(i)); - tokens.push({ type: "PATTERN", index: i, value: pattern }); - i = j; - continue; - } - tokens.push({ type: "CHAR", index: i, value: str[i++] }); - } - tokens.push({ type: "END", index: i, value: "" }); - return tokens; -} -function parse2(str, options) { - if (options === void 0) { - options = {}; - } - var tokens = lexer(str); - var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a, _b = options.delimiter, delimiter = _b === void 0 ? "/#?" : _b; - var result = []; - var key = 0; - var i = 0; - var path3 = ""; - var tryConsume = function(type) { - if (i < tokens.length && tokens[i].type === type) - return tokens[i++].value; - }; - var mustConsume = function(type) { - var value2 = tryConsume(type); - if (value2 !== void 0) - return value2; - var _a2 = tokens[i], nextType = _a2.type, index = _a2.index; - throw new TypeError("Unexpected ".concat(nextType, " at ").concat(index, ", expected ").concat(type)); - }; - var consumeText = function() { - var result2 = ""; - var value2; - while (value2 = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR")) { - result2 += value2; - } - return result2; - }; - var isSafe = function(value2) { - for (var _i = 0, delimiter_1 = delimiter; _i < delimiter_1.length; _i++) { - var char2 = delimiter_1[_i]; - if (value2.indexOf(char2) > -1) - return true; - } - return false; - }; - var safePattern = function(prefix2) { - var prev = result[result.length - 1]; - var prevText = prefix2 || (prev && typeof prev === "string" ? prev : ""); - if (prev && !prevText) { - throw new TypeError('Must have text between two parameters, missing text after "'.concat(prev.name, '"')); - } - if (!prevText || isSafe(prevText)) - return "[^".concat(escapeString(delimiter), "]+?"); - return "(?:(?!".concat(escapeString(prevText), ")[^").concat(escapeString(delimiter), "])+?"); - }; - while (i < tokens.length) { - var char = tryConsume("CHAR"); - var name = tryConsume("NAME"); - var pattern = tryConsume("PATTERN"); - if (name || pattern) { - var prefix = char || ""; - if (prefixes.indexOf(prefix) === -1) { - path3 += prefix; - prefix = ""; - } - if (path3) { - result.push(path3); - path3 = ""; - } - result.push({ - name: name || key++, - prefix, - suffix: "", - pattern: pattern || safePattern(prefix), - modifier: tryConsume("MODIFIER") || "" - }); - continue; - } - var value = char || tryConsume("ESCAPED_CHAR"); - if (value) { - path3 += value; - continue; - } - if (path3) { - result.push(path3); - path3 = ""; - } - var open = tryConsume("OPEN"); - if (open) { - var prefix = consumeText(); - var name_1 = tryConsume("NAME") || ""; - var pattern_1 = tryConsume("PATTERN") || ""; - var suffix = consumeText(); - mustConsume("CLOSE"); - result.push({ - name: name_1 || (pattern_1 ? key++ : ""), - pattern: name_1 && !pattern_1 ? safePattern(prefix) : pattern_1, - prefix, - suffix, - modifier: tryConsume("MODIFIER") || "" - }); - continue; - } - mustConsume("END"); - } - return result; -} -function compile(str, options) { - return tokensToFunction(parse2(str, options), options); -} -function tokensToFunction(tokens, options) { - if (options === void 0) { - options = {}; - } - var reFlags = flags(options); - var _a = options.encode, encode = _a === void 0 ? function(x) { - return x; - } : _a, _b = options.validate, validate = _b === void 0 ? true : _b; - var matches = tokens.map(function(token) { - if (typeof token === "object") { - return new RegExp("^(?:".concat(token.pattern, ")$"), reFlags); - } - }); - return function(data) { - var path3 = ""; - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - if (typeof token === "string") { - path3 += token; - continue; - } - var value = data ? data[token.name] : void 0; - var optional = token.modifier === "?" || token.modifier === "*"; - var repeat = token.modifier === "*" || token.modifier === "+"; - if (Array.isArray(value)) { - if (!repeat) { - throw new TypeError('Expected "'.concat(token.name, '" to not repeat, but got an array')); - } - if (value.length === 0) { - if (optional) - continue; - throw new TypeError('Expected "'.concat(token.name, '" to not be empty')); - } - for (var j = 0; j < value.length; j++) { - var segment = encode(value[j], token); - if (validate && !matches[i].test(segment)) { - throw new TypeError('Expected all "'.concat(token.name, '" to match "').concat(token.pattern, '", but got "').concat(segment, '"')); - } - path3 += token.prefix + segment + token.suffix; - } - continue; - } - if (typeof value === "string" || typeof value === "number") { - var segment = encode(String(value), token); - if (validate && !matches[i].test(segment)) { - throw new TypeError('Expected "'.concat(token.name, '" to match "').concat(token.pattern, '", but got "').concat(segment, '"')); - } - path3 += token.prefix + segment + token.suffix; - continue; - } - if (optional) - continue; - var typeOfMessage = repeat ? "an array" : "a string"; - throw new TypeError('Expected "'.concat(token.name, '" to be ').concat(typeOfMessage)); - } - return path3; - }; -} -function match(str, options) { - var keys = []; - var re = pathToRegexp(str, keys, options); - return regexpToFunction(re, keys, options); -} -function regexpToFunction(re, keys, options) { - if (options === void 0) { - options = {}; - } - var _a = options.decode, decode = _a === void 0 ? function(x) { - return x; - } : _a; - return function(pathname) { - var m = re.exec(pathname); - if (!m) - return false; - var path3 = m[0], index = m.index; - var params = /* @__PURE__ */ Object.create(null); - var _loop_1 = function(i2) { - if (m[i2] === void 0) - return "continue"; - var key = keys[i2 - 1]; - if (key.modifier === "*" || key.modifier === "+") { - params[key.name] = m[i2].split(key.prefix + key.suffix).map(function(value) { - return decode(value, key); - }); - } else { - params[key.name] = decode(m[i2], key); - } - }; - for (var i = 1; i < m.length; i++) { - _loop_1(i); - } - return { path: path3, index, params }; - }; -} -function escapeString(str) { - return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1"); -} -function flags(options) { - return options && options.sensitive ? "" : "i"; -} -function regexpToRegexp(path3, keys) { - if (!keys) - return path3; - var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g; - var index = 0; - var execResult = groupsRegex.exec(path3.source); - while (execResult) { - keys.push({ - // Use parenthesized substring match if available, index otherwise - name: execResult[1] || index++, - prefix: "", - suffix: "", - modifier: "", - pattern: "" - }); - execResult = groupsRegex.exec(path3.source); - } - return path3; -} -function arrayToRegexp(paths, keys, options) { - var parts = paths.map(function(path3) { - return pathToRegexp(path3, keys, options).source; - }); - return new RegExp("(?:".concat(parts.join("|"), ")"), flags(options)); -} -function stringToRegexp(path3, keys, options) { - return tokensToRegexp(parse2(path3, options), keys, options); -} -function tokensToRegexp(tokens, keys, options) { - if (options === void 0) { - options = {}; - } - var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function(x) { - return x; - } : _d, _e = options.delimiter, delimiter = _e === void 0 ? "/#?" : _e, _f = options.endsWith, endsWith = _f === void 0 ? "" : _f; - var endsWithRe = "[".concat(escapeString(endsWith), "]|$"); - var delimiterRe = "[".concat(escapeString(delimiter), "]"); - var route = start ? "^" : ""; - for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) { - var token = tokens_1[_i]; - if (typeof token === "string") { - route += escapeString(encode(token)); - } else { - var prefix = escapeString(encode(token.prefix)); - var suffix = escapeString(encode(token.suffix)); - if (token.pattern) { - if (keys) - keys.push(token); - if (prefix || suffix) { - if (token.modifier === "+" || token.modifier === "*") { - var mod = token.modifier === "*" ? "?" : ""; - route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod); - } else { - route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier); - } - } else { - if (token.modifier === "+" || token.modifier === "*") { - throw new TypeError('Can not repeat "'.concat(token.name, '" without a prefix and suffix')); - } - route += "(".concat(token.pattern, ")").concat(token.modifier); - } - } else { - route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier); - } - } - } - if (end) { - if (!strict) - route += "".concat(delimiterRe, "?"); - route += !options.endsWith ? "$" : "(?=".concat(endsWithRe, ")"); - } else { - var endToken = tokens[tokens.length - 1]; - var isEndDelimited = typeof endToken === "string" ? delimiterRe.indexOf(endToken[endToken.length - 1]) > -1 : endToken === void 0; - if (!strict) { - route += "(?:".concat(delimiterRe, "(?=").concat(endsWithRe, "))?"); - } - if (!isEndDelimited) { - route += "(?=".concat(delimiterRe, "|").concat(endsWithRe, ")"); - } - } - return new RegExp(route, flags(options)); -} -function pathToRegexp(path3, keys, options) { - if (path3 instanceof RegExp) - return regexpToRegexp(path3, keys); - if (Array.isArray(path3)) - return arrayToRegexp(path3, keys, options); - return stringToRegexp(path3, keys, options); -} - -// node_modules/@opennextjs/aws/dist/utils/normalize-path.js -import path2 from "node:path"; -function normalizeRepeatedSlashes(url) { - const urlNoQuery = url.host + url.pathname; - return `${url.protocol}//${urlNoQuery.replace(/\\/g, "/").replace(/\/\/+/g, "/")}${url.search}`; -} - -// node_modules/@opennextjs/aws/dist/core/routing/matcher.js -init_stream(); -init_logger(); - -// node_modules/@opennextjs/aws/dist/core/routing/routeMatcher.js -var optionalLocalePrefixRegex = `^/(?:${RoutesManifest.locales.map((locale) => `${locale}/?`).join("|")})?`; -var optionalBasepathPrefixRegex = RoutesManifest.basePath ? `^${RoutesManifest.basePath}/?` : "^/"; -var optionalPrefix = optionalLocalePrefixRegex.replace("^/", optionalBasepathPrefixRegex); -function routeMatcher(routeDefinitions) { - const regexp = routeDefinitions.map((route) => ({ - page: route.page, - regexp: new RegExp(route.regex.replace("^/", optionalPrefix)) - })); - const appPathsSet = /* @__PURE__ */ new Set(); - const routePathsSet = /* @__PURE__ */ new Set(); - for (const [k, v] of Object.entries(AppPathRoutesManifest)) { - if (k.endsWith("page")) { - appPathsSet.add(v); - } else if (k.endsWith("route")) { - routePathsSet.add(v); - } - } - return function matchRoute(path3) { - const foundRoutes = regexp.filter((route) => route.regexp.test(path3)); - return foundRoutes.map((foundRoute) => { - let routeType = "page"; - if (appPathsSet.has(foundRoute.page)) { - routeType = "app"; - } else if (routePathsSet.has(foundRoute.page)) { - routeType = "route"; - } - return { - route: foundRoute.page, - type: routeType - }; - }); - }; -} -var staticRouteMatcher = routeMatcher([ - ...RoutesManifest.routes.static, - ...getStaticAPIRoutes() -]); -var dynamicRouteMatcher = routeMatcher(RoutesManifest.routes.dynamic); -function getStaticAPIRoutes() { - const createRouteDefinition = (route) => ({ - page: route, - regex: `^${route}(?:/)?$` - }); - const dynamicRoutePages = new Set(RoutesManifest.routes.dynamic.map(({ page }) => page)); - const pagesStaticAPIRoutes = Object.keys(PagesManifest).filter((route) => route.startsWith("/api/") && !dynamicRoutePages.has(route)).map(createRouteDefinition); - const appPathsStaticAPIRoutes = Object.values(AppPathRoutesManifest).filter((route) => (route.startsWith("/api/") || route === "/api") && !dynamicRoutePages.has(route)).map(createRouteDefinition); - return [...pagesStaticAPIRoutes, ...appPathsStaticAPIRoutes]; -} - -// node_modules/@opennextjs/aws/dist/core/routing/matcher.js -var routeHasMatcher = (headers, cookies, query) => (redirect) => { - switch (redirect.type) { - case "header": - return !!headers?.[redirect.key.toLowerCase()] && new RegExp(redirect.value ?? "").test(headers[redirect.key.toLowerCase()] ?? ""); - case "cookie": - return !!cookies?.[redirect.key] && new RegExp(redirect.value ?? "").test(cookies[redirect.key] ?? ""); - case "query": - return query[redirect.key] && Array.isArray(redirect.value) ? redirect.value.reduce((prev, current) => prev || new RegExp(current).test(query[redirect.key]), false) : new RegExp(redirect.value ?? "").test(query[redirect.key] ?? ""); - case "host": - return headers?.host !== "" && new RegExp(redirect.value ?? "").test(headers.host); - default: - return false; - } -}; -function checkHas(matcher, has, inverted = false) { - return has ? has.reduce((acc, cur) => { - if (acc === false) - return false; - return inverted ? !matcher(cur) : matcher(cur); - }, true) : true; -} -var getParamsFromSource = (source) => (value) => { - debug("value", value); - const _match = source(value); - return _match ? _match.params : {}; -}; -var computeParamHas = (headers, cookies, query) => (has) => { - if (!has.value) - return {}; - const matcher = new RegExp(`^${has.value}$`); - const fromSource = (value) => { - const matches = value.match(matcher); - return matches?.groups ?? {}; - }; - switch (has.type) { - case "header": - return fromSource(headers[has.key.toLowerCase()] ?? ""); - case "cookie": - return fromSource(cookies[has.key] ?? ""); - case "query": - return Array.isArray(query[has.key]) ? fromSource(query[has.key].join(",")) : fromSource(query[has.key] ?? ""); - case "host": - return fromSource(headers.host ?? ""); - } -}; -function convertMatch(match2, toDestination, destination) { - if (!match2) { - return destination; - } - const { params } = match2; - const isUsingParams = Object.keys(params).length > 0; - return isUsingParams ? toDestination(params) : destination; -} -function getNextConfigHeaders(event, configHeaders) { - if (!configHeaders) { - return {}; - } - const matcher = routeHasMatcher(event.headers, event.cookies, event.query); - const requestHeaders = {}; - const localizedRawPath = localizePath(event); - for (const { headers, has, missing, regex, source, locale } of configHeaders) { - const path3 = locale === false ? event.rawPath : localizedRawPath; - if (new RegExp(regex).test(path3) && checkHas(matcher, has) && checkHas(matcher, missing, true)) { - const fromSource = match(source); - const _match = fromSource(path3); - headers.forEach((h) => { - try { - const key = convertMatch(_match, compile(h.key), h.key); - const value = convertMatch(_match, compile(h.value), h.value); - requestHeaders[key] = value; - } catch { - debug(`Error matching header ${h.key} with value ${h.value}`); - requestHeaders[h.key] = h.value; - } - }); - } - } - return requestHeaders; -} -function handleRewrites(event, rewrites) { - const { rawPath, headers, query, cookies, url } = event; - const localizedRawPath = localizePath(event); - const matcher = routeHasMatcher(headers, cookies, query); - const computeHas = computeParamHas(headers, cookies, query); - const rewrite = rewrites.find((route) => { - const path3 = route.locale === false ? rawPath : localizedRawPath; - return new RegExp(route.regex).test(path3) && checkHas(matcher, route.has) && checkHas(matcher, route.missing, true); - }); - let finalQuery = query; - let rewrittenUrl = url; - const isExternalRewrite = isExternal(rewrite?.destination); - debug("isExternalRewrite", isExternalRewrite); - if (rewrite) { - const { pathname, protocol, hostname, queryString } = getUrlParts(rewrite.destination, isExternalRewrite); - const pathToUse = rewrite.locale === false ? rawPath : localizedRawPath; - debug("urlParts", { pathname, protocol, hostname, queryString }); - const toDestinationPath = compile(escapeRegex(pathname, { isPath: true })); - const toDestinationHost = compile(escapeRegex(hostname)); - const toDestinationQuery = compile(escapeRegex(queryString)); - const params = { - // params for the source - ...getParamsFromSource(match(escapeRegex(rewrite.source, { isPath: true })))(pathToUse), - // params for the has - ...rewrite.has?.reduce((acc, cur) => { - return Object.assign(acc, computeHas(cur)); - }, {}), - // params for the missing - ...rewrite.missing?.reduce((acc, cur) => { - return Object.assign(acc, computeHas(cur)); - }, {}) - }; - const isUsingParams = Object.keys(params).length > 0; - let rewrittenQuery = queryString; - let rewrittenHost = hostname; - let rewrittenPath = pathname; - if (isUsingParams) { - rewrittenPath = unescapeRegex(toDestinationPath(params)); - rewrittenHost = unescapeRegex(toDestinationHost(params)); - rewrittenQuery = unescapeRegex(toDestinationQuery(params)); - } - if (NextConfig.i18n && !isExternalRewrite) { - const strippedPathLocale = rewrittenPath.replace(new RegExp(`^/(${NextConfig.i18n.locales.join("|")})`), ""); - if (strippedPathLocale.startsWith("/api/")) { - rewrittenPath = strippedPathLocale; - } - } - rewrittenUrl = isExternalRewrite ? `${protocol}//${rewrittenHost}${rewrittenPath}` : new URL(rewrittenPath, event.url).href; - finalQuery = { - ...query, - ...convertFromQueryString(rewrittenQuery) - }; - rewrittenUrl += convertToQueryString(finalQuery); - debug("rewrittenUrl", { rewrittenUrl, finalQuery, isUsingParams }); - } - return { - internalEvent: { - ...event, - query: finalQuery, - rawPath: new URL(rewrittenUrl).pathname, - url: rewrittenUrl - }, - __rewrite: rewrite, - isExternalRewrite - }; -} -function handleRepeatedSlashRedirect(event) { - if (event.rawPath.match(/(\\|\/\/)/)) { - return { - type: event.type, - statusCode: 308, - headers: { - Location: normalizeRepeatedSlashes(new URL(event.url)) - }, - body: emptyReadableStream(), - isBase64Encoded: false - }; - } - return false; -} -function handleTrailingSlashRedirect(event) { - const url = new URL(event.rawPath, "http://localhost"); - if ( - // Someone is trying to redirect to a different origin, let's not do that - url.host !== "localhost" || NextConfig.skipTrailingSlashRedirect || // We should not apply trailing slash redirect to API routes - event.rawPath.startsWith("/api/") - ) { - return false; - } - const emptyBody = emptyReadableStream(); - if (NextConfig.trailingSlash && !event.headers["x-nextjs-data"] && !event.rawPath.endsWith("/") && !event.rawPath.match(/[\w-]+\.[\w]+$/g)) { - const headersLocation = event.url.split("?"); - return { - type: event.type, - statusCode: 308, - headers: { - Location: `${headersLocation[0]}/${headersLocation[1] ? `?${headersLocation[1]}` : ""}` - }, - body: emptyBody, - isBase64Encoded: false - }; - } - if (!NextConfig.trailingSlash && event.rawPath.endsWith("/") && event.rawPath !== "/") { - const headersLocation = event.url.split("?"); - return { - type: event.type, - statusCode: 308, - headers: { - Location: `${headersLocation[0].replace(/\/$/, "")}${headersLocation[1] ? `?${headersLocation[1]}` : ""}` - }, - body: emptyBody, - isBase64Encoded: false - }; - } - return false; -} -function handleRedirects(event, redirects) { - const repeatedSlashRedirect = handleRepeatedSlashRedirect(event); - if (repeatedSlashRedirect) - return repeatedSlashRedirect; - const trailingSlashRedirect = handleTrailingSlashRedirect(event); - if (trailingSlashRedirect) - return trailingSlashRedirect; - const localeRedirect = handleLocaleRedirect(event); - if (localeRedirect) - return localeRedirect; - const { internalEvent, __rewrite } = handleRewrites(event, redirects.filter((r) => !r.internal)); - if (__rewrite && !__rewrite.internal) { - return { - type: event.type, - statusCode: __rewrite.statusCode ?? 308, - headers: { - Location: internalEvent.url - }, - body: emptyReadableStream(), - isBase64Encoded: false - }; - } -} -function fixDataPage(internalEvent, buildId) { - const { rawPath, query } = internalEvent; - const basePath = NextConfig.basePath ?? ""; - const dataPattern = `${basePath}/_next/data/${buildId}`; - if (rawPath.startsWith("/_next/data") && !rawPath.startsWith(dataPattern)) { - return { - type: internalEvent.type, - statusCode: 404, - body: toReadableStream("{}"), - headers: { - "Content-Type": "application/json" - }, - isBase64Encoded: false - }; - } - if (rawPath.startsWith(dataPattern) && rawPath.endsWith(".json")) { - const newPath = `${basePath}${rawPath.slice(dataPattern.length, -".json".length).replace(/^\/index$/, "/")}`; - query.__nextDataReq = "1"; - return { - ...internalEvent, - rawPath: newPath, - query, - url: new URL(`${newPath}${convertToQueryString(query)}`, internalEvent.url).href - }; - } - return internalEvent; -} -function handleFallbackFalse(internalEvent, prerenderManifest) { - const { rawPath } = internalEvent; - const { dynamicRoutes = {}, routes = {} } = prerenderManifest ?? {}; - const prerenderedFallbackRoutes = Object.entries(dynamicRoutes).filter(([, { fallback }]) => fallback === false); - const routeFallback = prerenderedFallbackRoutes.some(([, { routeRegex }]) => { - const routeRegexExp = new RegExp(routeRegex); - return routeRegexExp.test(rawPath); - }); - const locales = NextConfig.i18n?.locales; - const routesAlreadyHaveLocale = locales?.includes(rawPath.split("/")[1]) || // If we don't use locales, we don't need to add the default locale - locales === void 0; - let localizedPath = routesAlreadyHaveLocale ? rawPath : `/${NextConfig.i18n?.defaultLocale}${rawPath}`; - if ( - // Not if localizedPath is "/" tho, because that would not make it find `isPregenerated` below since it would be try to match an empty string. - localizedPath !== "/" && NextConfig.trailingSlash && localizedPath.endsWith("/") - ) { - localizedPath = localizedPath.slice(0, -1); - } - const matchedStaticRoute = staticRouteMatcher(localizedPath); - const prerenderedFallbackRoutesName = prerenderedFallbackRoutes.map(([name]) => name); - const matchedDynamicRoute = dynamicRouteMatcher(localizedPath).filter(({ route }) => !prerenderedFallbackRoutesName.includes(route)); - const isPregenerated = Object.keys(routes).includes(localizedPath); - if (routeFallback && !isPregenerated && matchedStaticRoute.length === 0 && matchedDynamicRoute.length === 0) { - return { - event: { - ...internalEvent, - rawPath: "/404", - url: constructNextUrl(internalEvent.url, "/404"), - headers: { - ...internalEvent.headers, - "x-invoke-status": "404" - } - }, - isISR: false - }; - } - return { - event: internalEvent, - isISR: routeFallback || isPregenerated - }; -} - -// node_modules/@opennextjs/aws/dist/core/routing/middleware.js -init_stream(); -init_utils(); -var middlewareManifest = MiddlewareManifest; -var functionsConfigManifest = FunctionsConfigManifest; -var middleMatch = getMiddlewareMatch(middlewareManifest, functionsConfigManifest); -var REDIRECTS = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]); -function defaultMiddlewareLoader() { - return Promise.resolve().then(() => (init_edgeFunctionHandler(), edgeFunctionHandler_exports)); -} -async function handleMiddleware(internalEvent, initialSearch, middlewareLoader = defaultMiddlewareLoader) { - const headers = internalEvent.headers; - if (headers["x-isr"] && headers["x-prerender-revalidate"] === PrerenderManifest?.preview?.previewModeId) - return internalEvent; - const normalizedPath = localizePath(internalEvent); - const hasMatch = middleMatch.some((r) => r.test(normalizedPath)); - if (!hasMatch) - return internalEvent; - const initialUrl = new URL(normalizedPath, internalEvent.url); - initialUrl.search = initialSearch; - const url = initialUrl.href; - const middleware = await middlewareLoader(); - const result = await middleware.default({ - // `geo` is pre Next 15. - geo: { - // The city name is percent-encoded. - // See https://github.com/vercel/vercel/blob/4cb6143/packages/functions/src/headers.ts#L94C19-L94C37 - city: decodeURIComponent(headers["x-open-next-city"]), - country: headers["x-open-next-country"], - region: headers["x-open-next-region"], - latitude: headers["x-open-next-latitude"], - longitude: headers["x-open-next-longitude"] - }, - headers, - method: internalEvent.method || "GET", - nextConfig: { - basePath: NextConfig.basePath, - i18n: NextConfig.i18n, - trailingSlash: NextConfig.trailingSlash - }, - url, - body: convertBodyToReadableStream(internalEvent.method, internalEvent.body) - }); - const statusCode = result.status; - const responseHeaders = result.headers; - const reqHeaders = {}; - const resHeaders = {}; - const filteredHeaders = [ - "x-middleware-override-headers", - "x-middleware-next", - "x-middleware-rewrite", - // We need to drop `content-encoding` because it will be decoded - "content-encoding" - ]; - const xMiddlewareKey = "x-middleware-request-"; - responseHeaders.forEach((value, key) => { - if (key.startsWith(xMiddlewareKey)) { - const k = key.substring(xMiddlewareKey.length); - reqHeaders[k] = value; - } else { - if (filteredHeaders.includes(key.toLowerCase())) - return; - if (key.toLowerCase() === "set-cookie") { - resHeaders[key] = resHeaders[key] ? [...resHeaders[key], value] : [value]; - } else if (REDIRECTS.has(statusCode) && key.toLowerCase() === "location") { - resHeaders[key] = normalizeLocationHeader(value, internalEvent.url); - } else { - resHeaders[key] = value; - } - } - }); - const rewriteUrl = responseHeaders.get("x-middleware-rewrite"); - let isExternalRewrite = false; - let middlewareQuery = internalEvent.query; - let newUrl = internalEvent.url; - if (rewriteUrl) { - newUrl = rewriteUrl; - if (isExternal(newUrl, internalEvent.headers.host)) { - isExternalRewrite = true; - } else { - const rewriteUrlObject = new URL(rewriteUrl); - middlewareQuery = getQueryFromSearchParams(rewriteUrlObject.searchParams); - if ("__nextDataReq" in internalEvent.query) { - middlewareQuery.__nextDataReq = internalEvent.query.__nextDataReq; - } - } - } - if (!rewriteUrl && !responseHeaders.get("x-middleware-next")) { - const body = result.body ?? emptyReadableStream(); - return { - type: internalEvent.type, - statusCode, - headers: resHeaders, - body, - isBase64Encoded: false - }; - } - return { - responseHeaders: resHeaders, - url: newUrl, - rawPath: new URL(newUrl).pathname, - type: internalEvent.type, - headers: { ...internalEvent.headers, ...reqHeaders }, - body: internalEvent.body, - method: internalEvent.method, - query: middlewareQuery, - cookies: internalEvent.cookies, - remoteAddress: internalEvent.remoteAddress, - isExternalRewrite, - rewriteStatusCode: rewriteUrl && !isExternalRewrite ? statusCode : void 0 - }; -} - -// node_modules/@opennextjs/aws/dist/core/routingHandler.js -var MIDDLEWARE_HEADER_PREFIX = "x-middleware-response-"; -var MIDDLEWARE_HEADER_PREFIX_LEN = MIDDLEWARE_HEADER_PREFIX.length; -var INTERNAL_HEADER_PREFIX = "x-opennext-"; -var INTERNAL_HEADER_INITIAL_URL = `${INTERNAL_HEADER_PREFIX}initial-url`; -var INTERNAL_HEADER_LOCALE = `${INTERNAL_HEADER_PREFIX}locale`; -var INTERNAL_HEADER_RESOLVED_ROUTES = `${INTERNAL_HEADER_PREFIX}resolved-routes`; -var INTERNAL_HEADER_REWRITE_STATUS_CODE = `${INTERNAL_HEADER_PREFIX}rewrite-status-code`; -var INTERNAL_EVENT_REQUEST_ID = `${INTERNAL_HEADER_PREFIX}request-id`; -var geoHeaderToNextHeader = { - "x-open-next-city": "x-vercel-ip-city", - "x-open-next-country": "x-vercel-ip-country", - "x-open-next-region": "x-vercel-ip-country-region", - "x-open-next-latitude": "x-vercel-ip-latitude", - "x-open-next-longitude": "x-vercel-ip-longitude" -}; -function applyMiddlewareHeaders(eventOrResult, middlewareHeaders) { - const isResult = isInternalResult(eventOrResult); - const headers = eventOrResult.headers; - const keyPrefix = isResult ? "" : MIDDLEWARE_HEADER_PREFIX; - Object.entries(middlewareHeaders).forEach(([key, value]) => { - if (value) { - headers[keyPrefix + key] = Array.isArray(value) ? value.join(",") : value; - } - }); -} -async function routingHandler(event, { assetResolver }) { - try { - for (const [openNextGeoName, nextGeoName] of Object.entries(geoHeaderToNextHeader)) { - const value = event.headers[openNextGeoName]; - if (value) { - event.headers[nextGeoName] = value; - } - } - for (const key of Object.keys(event.headers)) { - if (key.startsWith(INTERNAL_HEADER_PREFIX) || key.startsWith(MIDDLEWARE_HEADER_PREFIX)) { - delete event.headers[key]; - } - } - let headers = getNextConfigHeaders(event, ConfigHeaders); - let eventOrResult = fixDataPage(event, BuildId); - if (isInternalResult(eventOrResult)) { - return eventOrResult; - } - const redirect = handleRedirects(eventOrResult, RoutesManifest.redirects); - if (redirect) { - redirect.headers.Location = normalizeLocationHeader(redirect.headers.Location, event.url, true); - debug("redirect", redirect); - return redirect; - } - const middlewareEventOrResult = await handleMiddleware( - eventOrResult, - // We need to pass the initial search without any decoding - // TODO: we'd need to refactor InternalEvent to include the initial querystring directly - // Should be done in another PR because it is a breaking change - new URL(event.url).search - ); - if (isInternalResult(middlewareEventOrResult)) { - return middlewareEventOrResult; - } - const middlewareHeadersPrioritized = globalThis.openNextConfig.dangerous?.middlewareHeadersOverrideNextConfigHeaders ?? false; - if (middlewareHeadersPrioritized) { - headers = { - ...headers, - ...middlewareEventOrResult.responseHeaders - }; - } else { - headers = { - ...middlewareEventOrResult.responseHeaders, - ...headers - }; - } - let isExternalRewrite = middlewareEventOrResult.isExternalRewrite ?? false; - eventOrResult = middlewareEventOrResult; - if (!isExternalRewrite) { - const beforeRewrite = handleRewrites(eventOrResult, RoutesManifest.rewrites.beforeFiles); - eventOrResult = beforeRewrite.internalEvent; - isExternalRewrite = beforeRewrite.isExternalRewrite; - if (!isExternalRewrite) { - const assetResult = await assetResolver?.maybeGetAssetResult?.(eventOrResult); - if (assetResult) { - applyMiddlewareHeaders(assetResult, headers); - return assetResult; - } - } - } - const foundStaticRoute = staticRouteMatcher(eventOrResult.rawPath); - const isStaticRoute = !isExternalRewrite && foundStaticRoute.length > 0; - if (!(isStaticRoute || isExternalRewrite)) { - const afterRewrite = handleRewrites(eventOrResult, RoutesManifest.rewrites.afterFiles); - eventOrResult = afterRewrite.internalEvent; - isExternalRewrite = afterRewrite.isExternalRewrite; - } - let isISR = false; - if (!isExternalRewrite) { - const fallbackResult = handleFallbackFalse(eventOrResult, PrerenderManifest); - eventOrResult = fallbackResult.event; - isISR = fallbackResult.isISR; - } - const foundDynamicRoute = dynamicRouteMatcher(eventOrResult.rawPath); - const isDynamicRoute = !isExternalRewrite && foundDynamicRoute.length > 0; - if (!(isDynamicRoute || isStaticRoute || isExternalRewrite)) { - const fallbackRewrites = handleRewrites(eventOrResult, RoutesManifest.rewrites.fallback); - eventOrResult = fallbackRewrites.internalEvent; - isExternalRewrite = fallbackRewrites.isExternalRewrite; - } - const isNextImageRoute = eventOrResult.rawPath.startsWith("/_next/image"); - const isRouteFoundBeforeAllRewrites = isStaticRoute || isDynamicRoute || isExternalRewrite; - if (!(isRouteFoundBeforeAllRewrites || isNextImageRoute || // We need to check again once all rewrites have been applied - staticRouteMatcher(eventOrResult.rawPath).length > 0 || dynamicRouteMatcher(eventOrResult.rawPath).length > 0)) { - eventOrResult = { - ...eventOrResult, - rawPath: "/404", - url: constructNextUrl(eventOrResult.url, "/404"), - headers: { - ...eventOrResult.headers, - "x-middleware-response-cache-control": "private, no-cache, no-store, max-age=0, must-revalidate" - } - }; - } - if (globalThis.openNextConfig.dangerous?.enableCacheInterception && !isInternalResult(eventOrResult)) { - debug("Cache interception enabled"); - eventOrResult = await cacheInterceptor(eventOrResult); - if (isInternalResult(eventOrResult)) { - applyMiddlewareHeaders(eventOrResult, headers); - return eventOrResult; - } - } - applyMiddlewareHeaders(eventOrResult, headers); - const resolvedRoutes = [ - ...foundStaticRoute, - ...foundDynamicRoute - ]; - debug("resolvedRoutes", resolvedRoutes); - return { - internalEvent: eventOrResult, - isExternalRewrite, - origin: false, - isISR, - resolvedRoutes, - initialURL: event.url, - locale: NextConfig.i18n ? detectLocale(eventOrResult, NextConfig.i18n) : void 0, - rewriteStatusCode: middlewareEventOrResult.rewriteStatusCode - }; - } catch (e) { - error("Error in routingHandler", e); - return { - internalEvent: { - type: "core", - method: "GET", - rawPath: "/500", - url: constructNextUrl(event.url, "/500"), - headers: { - ...event.headers - }, - query: event.query, - cookies: event.cookies, - remoteAddress: event.remoteAddress - }, - isExternalRewrite: false, - origin: false, - isISR: false, - resolvedRoutes: [], - initialURL: event.url, - locale: NextConfig.i18n ? detectLocale(event, NextConfig.i18n) : void 0 - }; - } -} -function isInternalResult(eventOrResult) { - return eventOrResult != null && "statusCode" in eventOrResult; -} - -// node_modules/@opennextjs/aws/dist/adapters/middleware.js -globalThis.internalFetch = fetch; -globalThis.__openNextAls = new AsyncLocalStorage(); -var defaultHandler = async (internalEvent, options) => { - const middlewareConfig = globalThis.openNextConfig.middleware; - const originResolver = await resolveOriginResolver(middlewareConfig?.originResolver); - const externalRequestProxy = await resolveProxyRequest(middlewareConfig?.override?.proxyExternalRequest); - const assetResolver = await resolveAssetResolver(middlewareConfig?.assetResolver); - const requestId = Math.random().toString(36); - return runWithOpenNextRequestContext({ - isISRRevalidation: internalEvent.headers["x-isr"] === "1", - waitUntil: options?.waitUntil, - requestId - }, async () => { - const result = await routingHandler(internalEvent, { assetResolver }); - if ("internalEvent" in result) { - debug("Middleware intercepted event", internalEvent); - if (!result.isExternalRewrite) { - const origin = await originResolver.resolve(result.internalEvent.rawPath); - return { - type: "middleware", - internalEvent: { - ...result.internalEvent, - headers: { - ...result.internalEvent.headers, - [INTERNAL_HEADER_INITIAL_URL]: internalEvent.url, - [INTERNAL_HEADER_RESOLVED_ROUTES]: JSON.stringify(result.resolvedRoutes), - [INTERNAL_EVENT_REQUEST_ID]: requestId, - [INTERNAL_HEADER_REWRITE_STATUS_CODE]: String(result.rewriteStatusCode) - } - }, - isExternalRewrite: result.isExternalRewrite, - origin, - isISR: result.isISR, - initialURL: result.initialURL, - resolvedRoutes: result.resolvedRoutes - }; - } - try { - return externalRequestProxy.proxy(result.internalEvent); - } catch (e) { - error("External request failed.", e); - return { - type: "middleware", - internalEvent: { - ...result.internalEvent, - headers: { - ...result.internalEvent.headers, - [INTERNAL_EVENT_REQUEST_ID]: requestId - }, - rawPath: "/500", - url: constructNextUrl(result.internalEvent.url, "/500"), - method: "GET" - }, - // On error we need to rewrite to the 500 page which is an internal rewrite - isExternalRewrite: false, - origin: false, - isISR: result.isISR, - initialURL: result.internalEvent.url, - resolvedRoutes: [{ route: "/500", type: "page" }] - }; - } - } - if (process.env.OPEN_NEXT_REQUEST_ID_HEADER || globalThis.openNextDebug) { - result.headers[INTERNAL_EVENT_REQUEST_ID] = requestId; - } - debug("Middleware response", result); - return result; - }); -}; -var handler2 = await createGenericHandler({ - handler: defaultHandler, - type: "middleware" -}); -var middleware_default = { - fetch: handler2 -}; -export { - middleware_default as default, - handler2 as handler -}; diff --git a/.open-next 2/middleware/open-next.config.mjs b/.open-next 2/middleware/open-next.config.mjs deleted file mode 100644 index 4638007..0000000 --- a/.open-next 2/middleware/open-next.config.mjs +++ /dev/null @@ -1,29 +0,0 @@ -// open-next.config.ts -var config = { - default: { - override: { - wrapper: "cloudflare-node", - converter: "edge", - proxyExternalRequest: "fetch", - incrementalCache: "dummy", - tagCache: "dummy", - queue: "dummy" - } - }, - edgeExternals: ["node:crypto"], - middleware: { - external: true, - override: { - wrapper: "cloudflare-edge", - converter: "edge", - proxyExternalRequest: "fetch", - incrementalCache: "dummy", - tagCache: "dummy", - queue: "dummy" - } - } -}; -var open_next_config_default = config; -export { - open_next_config_default as default -}; diff --git a/.open-next 2/worker 8.js b/.open-next 2/worker 8.js new file mode 100644 index 0000000..0e5a82a --- /dev/null +++ b/.open-next 2/worker 8.js @@ -0,0 +1,50 @@ +//@ts-expect-error: Will be resolved by wrangler build +import { handleImageRequest } from "./cloudflare/images.js"; +//@ts-expect-error: Will be resolved by wrangler build +import { runWithCloudflareRequestContext } from "./cloudflare/init.js"; +//@ts-expect-error: Will be resolved by wrangler build +import { maybeGetSkewProtectionResponse } from "./cloudflare/skew-protection.js"; +// @ts-expect-error: Will be resolved by wrangler build +import { handler as middlewareHandler } from "./middleware/handler.mjs"; +//@ts-expect-error: Will be resolved by wrangler build +export { DOQueueHandler } from "./.build/durable-objects/queue.js"; +//@ts-expect-error: Will be resolved by wrangler build +export { DOShardedTagCache } from "./.build/durable-objects/sharded-tag-cache.js"; +//@ts-expect-error: Will be resolved by wrangler build +export { BucketCachePurge } from "./.build/durable-objects/bucket-cache-purge.js"; +export default { + async fetch(request, env, ctx) { + return runWithCloudflareRequestContext(request, env, ctx, async () => { + const response = maybeGetSkewProtectionResponse(request); + if (response) { + return response; + } + const url = new URL(request.url); + // Serve images in development. + // Note: "/cdn-cgi/image/..." requests do not reach production workers. + if (url.pathname.startsWith("/cdn-cgi/image/")) { + const m = url.pathname.match(/\/cdn-cgi\/image\/.+?\/(?.+)$/); + if (m === null) { + return new Response("Not Found!", { status: 404 }); + } + const imageUrl = m.groups.url; + return imageUrl.match(/^https?:\/\//) + ? fetch(imageUrl, { cf: { cacheEverything: true } }) + : env.ASSETS?.fetch(new URL(`/${imageUrl}`, url)); + } + // Fallback for the Next default image loader. + if (url.pathname === + `${globalThis.__NEXT_BASE_PATH__}/_next/image${globalThis.__TRAILING_SLASH__ ? "/" : ""}`) { + return await handleImageRequest(url, request.headers, env); + } + // - `Request`s are handled by the Next server + const reqOrResp = await middlewareHandler(request, env, ctx); + if (reqOrResp instanceof Response) { + return reqOrResp; + } + // @ts-expect-error: resolved by wrangler build + const { handler } = await import("./server-functions/default/handler.mjs"); + return handler(reqOrResp, env, ctx, request.signal); + }); + }, +}; diff --git a/.open-next 2/worker 9.js b/.open-next 2/worker 9.js new file mode 100644 index 0000000..0e5a82a --- /dev/null +++ b/.open-next 2/worker 9.js @@ -0,0 +1,50 @@ +//@ts-expect-error: Will be resolved by wrangler build +import { handleImageRequest } from "./cloudflare/images.js"; +//@ts-expect-error: Will be resolved by wrangler build +import { runWithCloudflareRequestContext } from "./cloudflare/init.js"; +//@ts-expect-error: Will be resolved by wrangler build +import { maybeGetSkewProtectionResponse } from "./cloudflare/skew-protection.js"; +// @ts-expect-error: Will be resolved by wrangler build +import { handler as middlewareHandler } from "./middleware/handler.mjs"; +//@ts-expect-error: Will be resolved by wrangler build +export { DOQueueHandler } from "./.build/durable-objects/queue.js"; +//@ts-expect-error: Will be resolved by wrangler build +export { DOShardedTagCache } from "./.build/durable-objects/sharded-tag-cache.js"; +//@ts-expect-error: Will be resolved by wrangler build +export { BucketCachePurge } from "./.build/durable-objects/bucket-cache-purge.js"; +export default { + async fetch(request, env, ctx) { + return runWithCloudflareRequestContext(request, env, ctx, async () => { + const response = maybeGetSkewProtectionResponse(request); + if (response) { + return response; + } + const url = new URL(request.url); + // Serve images in development. + // Note: "/cdn-cgi/image/..." requests do not reach production workers. + if (url.pathname.startsWith("/cdn-cgi/image/")) { + const m = url.pathname.match(/\/cdn-cgi\/image\/.+?\/(?.+)$/); + if (m === null) { + return new Response("Not Found!", { status: 404 }); + } + const imageUrl = m.groups.url; + return imageUrl.match(/^https?:\/\//) + ? fetch(imageUrl, { cf: { cacheEverything: true } }) + : env.ASSETS?.fetch(new URL(`/${imageUrl}`, url)); + } + // Fallback for the Next default image loader. + if (url.pathname === + `${globalThis.__NEXT_BASE_PATH__}/_next/image${globalThis.__TRAILING_SLASH__ ? "/" : ""}`) { + return await handleImageRequest(url, request.headers, env); + } + // - `Request`s are handled by the Next server + const reqOrResp = await middlewareHandler(request, env, ctx); + if (reqOrResp instanceof Response) { + return reqOrResp; + } + // @ts-expect-error: resolved by wrangler build + const { handler } = await import("./server-functions/default/handler.mjs"); + return handler(reqOrResp, env, ctx, request.signal); + }); + }, +}; diff --git a/src/app/globals.css b/src/app/globals.css index b1c0044..57a0eeb 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -628,4 +628,30 @@ animation-delay: -15s; opacity: 0.7; filter: blur(5px); -} \ No newline at end of file +} +/* Swipe ecosystem for mobile placards */ +@media (max-width: 640px) { + .swipe-container { + display: flex; + overflow-x: auto; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + -ms-overflow-style: none; + gap: 1.25rem; + padding: 1rem 0 2.5rem; + margin: 0 -1rem; + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + .swipe-container::-webkit-scrollbar { + display: none; + } + + .swipe-item { + flex: 0 0 calc(100vw - 3rem); + scroll-snap-align: center; + } +} diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index 1b6a3da..86fbfca 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -234,70 +234,89 @@ export function Dashboard({ user }: DashboardProps) { -
-
-
- { - const updatedPrefs = { ...preferences, religion }; - setPreferences(updatedPrefs); - await savePreferencesAsync(updatedPrefs); - }} - preferences={preferences} - onPreferencesUpdate={async (updatedPrefs) => { - await savePreferencesAsync(updatedPrefs); - setPreferences(updatedPrefs); - }} - /> + {/* Dashboard Sections */} +
+ + {/* SECTION: Daily Snapshot (Horizontal Swipe on Mobile) */} +
+
+

Daily Snapshot

+
+
+
+
+
-
- + +
+
+ +
+
+ +
+
+ { + const updatedPrefs = { ...preferences, religion }; + setPreferences(updatedPrefs); + await savePreferencesAsync(updatedPrefs); + }} + preferences={preferences} + onPreferencesUpdate={async (updatedPrefs) => { + await savePreferencesAsync(updatedPrefs); + setPreferences(updatedPrefs); + }} + /> +
-
- +
+ + {/* SECTION: Your Journey */} +
+
+

Your Journey

-
- + +
+
+ +
+
+ +
+
+ +
+
+ +
-
-
-
- -
-
- -
-
- -
-
- -
-
+
)} diff --git a/src/components/SideMenu.tsx b/src/components/SideMenu.tsx new file mode 100644 index 0000000..aac59a3 --- /dev/null +++ b/src/components/SideMenu.tsx @@ -0,0 +1,200 @@ +'use client'; + +import { + Cigarette, + Leaf, + LogOut, + Home, + Sparkles, + X, + Settings, + Shield, + Heart, + Calendar +} from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { cn } from '@/lib/utils'; +import { useTheme } from '@/lib/theme-context'; +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; + +interface SideMenuProps { + isOpen: boolean; + onClose: () => void; + user: { + id: string; + email: string; + firstName?: string | null; + lastName?: string | null; + profilePictureUrl?: string | null; + }; + userName: string | null; +} + +export function SideMenu({ isOpen, onClose, user, userName }: SideMenuProps) { + const router = useRouter(); + const { theme } = useTheme(); + + if (!isOpen) return null; + + const handleNavigate = (path: string) => { + router.push(path); + onClose(); + }; + + const handleLogout = () => { + window.location.href = '/api/auth/logout'; + }; + + const initials = [user.firstName?.[0], user.lastName?.[0]] + .filter(Boolean) + .join('') + .toUpperCase() || user.email[0].toUpperCase(); + + return ( +
+ {/* Backdrop */} +
+ + {/* Menu Content */} +
+ {/* Header/Profile Info */} +
+
+ + + {initials} + + +
+
+

{userName || 'User'}

+

{user.email}

+
+
+ + {/* Navigation Links */} +
+ handleNavigate('/')} + /> +
+ Tracking +
+ handleNavigate('/track/nicotine')} + color="rose" + /> + handleNavigate('/track/marijuana')} + color="emerald" + /> + +
+ Resources +
+ handleNavigate('/smoking-aids')} + color="purple" + /> + + +
+ + {/* Footer Actions */} +
+ + +
+
+
+ ); +} + +interface MenuLinkProps { + icon: any; + label: string; + onClick: () => void; + color?: 'rose' | 'emerald' | 'purple' | 'blue' | 'amber'; +} + +function MenuLink({ icon: Icon, label, onClick, color }: MenuLinkProps) { + const { theme } = useTheme(); + + const colors = { + rose: "text-rose-500 bg-rose-500/5", + emerald: "text-emerald-500 bg-emerald-500/5", + purple: "text-purple-500 bg-purple-500/5", + blue: "text-blue-500 bg-blue-500/5", + amber: "text-amber-500 bg-amber-500/5", + }; + + return ( + + ); +} diff --git a/src/components/UserHeader.tsx b/src/components/UserHeader.tsx index e539a70..a3d18b9 100644 --- a/src/components/UserHeader.tsx +++ b/src/components/UserHeader.tsx @@ -121,10 +121,13 @@ function HourlyTimePicker({ value, onChange }: HourlyTimePickerProps) { ); } +import { SideMenu } from './SideMenu'; + export function UserHeader({ user, preferences }: UserHeaderProps) { const [userName, setUserName] = useState(null); const [reminderSettings, setReminderSettings] = useState({ enabled: false, reminderTime: '09:00', frequency: 'daily' }); const [showReminderDialog, setShowReminderDialog] = useState(false); + const [isSideMenuOpen, setIsSideMenuOpen] = useState(false); const [localTime, setLocalTime] = useState('09:00'); const [localFrequency, setLocalFrequency] = useState<'daily' | 'hourly'>('daily'); const router = useRouter(); @@ -157,8 +160,6 @@ export function UserHeader({ user, preferences }: UserHeaderProps) { useEffect(() => { const loadData = async () => { - // If preferences passed from parent, use them. Otherwise fetch. - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ const [prefs, reminders] = await Promise.all([ preferences ? Promise.resolve(preferences) : fetchPreferences(), fetchReminderSettings(), @@ -171,7 +172,6 @@ export function UserHeader({ user, preferences }: UserHeaderProps) { const detectedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; let settingsToUse = reminders; - // If timezone is missing or different, update it if (reminders.timezone !== detectedTimezone) { settingsToUse = { ...reminders, timezone: detectedTimezone }; await saveReminderSettings(settingsToUse); @@ -194,8 +194,6 @@ export function UserHeader({ user, preferences }: UserHeaderProps) { await saveReminderSettings(newSettings); }; - - const handleFrequencyChange = async (newFrequency: 'daily' | 'hourly') => { setLocalFrequency(newFrequency); const newSettings = { ...reminderSettings, frequency: newFrequency }; @@ -208,60 +206,48 @@ export function UserHeader({ user, preferences }: UserHeaderProps) { .join('') .toUpperCase() || user.email[0].toUpperCase(); - const handleLogout = () => { - window.location.href = '/api/auth/logout'; - }; - const handleNavigate = (path: string) => { router.push(path); + setIsSideMenuOpen(false); }; return ( <> -
{/* Cloudy/Foggy effect overlay */} -
-
-
-
- - {/* Subtle moving fog layers - CSS procedural animation */} -
-
-
-
+
+
+
- {/* Edge blur overlay - fades content into header */} -
-
-
+
+ {/* LEFT: User Profile / Side Menu Trigger */} +
+ +
+ + {/* CENTER: Title and Welcome Message */} +

handleNavigate('/')} style={{ background: theme === 'light' @@ -270,174 +256,133 @@ export function UserHeader({ user, preferences }: UserHeaderProps) { WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text', - filter: theme === 'light' - ? 'none' - : 'drop-shadow(0 0 10px rgba(167, 139, 250, 0.4))' + filter: theme === 'dark' ? 'drop-shadow(0 0 10px rgba(167, 139, 250, 0.3))' : 'none' }} > QuitTraq

{userName && ( -

+

Welcome {userName}, you got this!

)}
-
+ {/* RIGHT: Action Buttons */} +
- - {/* Main Navigation Menu */} - - - - - - handleNavigate('/')}> - - Dashboard - - - handleNavigate('/track/nicotine')}> - - Track Nicotine Usage - - handleNavigate('/track/marijuana')}> - - Track Marijuana Usage - - - handleNavigate('/smoking-aids')}> - - Smoking Aids - - - - - - - - - - - - - Sign out - - -
- {userName && ( -
-

- Welcome {userName}, you got this! -

-
- )} + + {/* Side Menu Integration */} + setIsSideMenuOpen(false)} + user={user} + userName={userName} + /> {/* Reminder Settings Dialog */} - + Notification Settings -
- - +
{/* Enable/Disable Toggle */} -
-
- {reminderSettings.enabled ? ( - - ) : ( - - )} +
+
+
+ {reminderSettings.enabled ? : } +
- - {reminderSettings.enabled ? 'Notifications On' : 'Notifications Off'} + + {reminderSettings.enabled ? 'Enabled' : 'Disabled'} - - {reminderSettings.enabled ? 'You will be notified to log usage' : 'Turn on to get reminders'} + + {reminderSettings.enabled ? 'Reminders active' : 'Turn on to get alerts'}
{/* Frequency Selection */} {reminderSettings.enabled && (
- +
Reminder Frequency
@@ -445,184 +390,127 @@ export function UserHeader({ user, preferences }: UserHeaderProps) { {/* Time Picker (Only for Daily) */} {reminderSettings.enabled && localFrequency === 'daily' && ( -
- -
- {/* Hour Select */} +
+
Preferred Time
+
- {/* Minute Select */}
- {/* AM/PM Select */} -
+
-

- You'll receive a reminder at this time each day -

)} - {/* Hourly Time Pickers */} + {/* Hourly Alerts Window */} {reminderSettings.enabled && localFrequency === 'hourly' && ( -
- - {/* Start Time */} +
- -
- { - const [h, m] = newTime.split(':'); - const end = (reminderSettings.hourlyEnd || '21:00').split(':'); - const newEnd = `${end[0]}:${m}`; - - const newSettings = { - ...reminderSettings, - hourlyStart: newTime, - hourlyEnd: newEnd - }; - setReminderSettings(newSettings); - await saveReminderSettings(newSettings); - }} - /> -
+
Start Time
+ { + const [h, m] = newTime.split(':'); + const end = (reminderSettings.hourlyEnd || '21:00').split(':'); + const newSettings = { ...reminderSettings, hourlyStart: newTime, hourlyEnd: `${end[0]}:${m}` }; + setReminderSettings(newSettings); + await saveReminderSettings(newSettings); + }} + />
- {/* End Time */}
- -
- { - const [h, m] = newTime.split(':'); - const start = (reminderSettings.hourlyStart || '09:00').split(':'); - const newStart = `${start[0]}:${m}`; - - const newSettings = { - ...reminderSettings, - hourlyEnd: newTime, - hourlyStart: newStart - }; - setReminderSettings(newSettings); - await saveReminderSettings(newSettings); - }} - /> -
+
End Time
+ { + const [h, m] = newTime.split(':'); + const start = (reminderSettings.hourlyStart || '09:00').split(':'); + const newSettings = { ...reminderSettings, hourlyEnd: newTime, hourlyStart: `${start[0]}:${m}` }; + setReminderSettings(newSettings); + await saveReminderSettings(newSettings); + }} + />
-

- - You'll receive reminders every hour between these times. -

+
+ +

Reminders every 60 minutes

+
)} - {/* Push Permission / Re-Sync Button */} + {/* Notification Permission Sync */} {reminderSettings.enabled && isSupported && ( -
- -

- {permission === 'granted' - ? 'Tap if you are not receiving alerts' - : 'Required for background alerts'} -

+ + {permission === 'granted' ? 'Permissions Verified' : 'Enable Push Alerts'} +
)} - {/* Denied Message */} {permission === 'denied' && ( -
-

- Notifications are blocked. Please enable them in your browser settings to receive reminders. +

+

+ Browser notifications are currently blocked. To get reminders, please update your site settings.

)}