@olmocms/front 0.1.2 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client/index.ts","../src/seo/index.ts","../src/jsonld/index.ts","../src/middleware/chain.ts","../src/middleware/headermiddleware.ts","../src/middleware/redirectmiddleware.ts","../src/components/RouteContext.tsx","../src/components/RouteSetter.tsx","../src/components/JsonLd.tsx","../src/components/GtmPage.tsx"],"sourcesContent":["export * from './client/index.js';\nexport * from './seo/index.js';\nexport * from './jsonld/index.js';\nexport * from './middleware/index.js';\nexport * from './components/index.js';\n","// Next.js extends RequestInit with a `next` property for cache tags / revalidation.\ntype NextRequestInit = RequestInit & {\n next?: { revalidate?: number | false; tags?: string[] };\n};\n\nconst API_BASE_URL = process.env.NEXT_PUBLIC_API_URL;\nconst API_TOKEN = process.env.NEXT_PUBLIC_OLMO_TOKEN as string;\n\nconst BASE_HEADERS: HeadersInit = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'front-token': API_TOKEN,\n};\n\nexport async function getting<T = unknown>(\n lang: string,\n path: string,\n model = '',\n): Promise<T | undefined> {\n const isPreview = path.includes('?olmopreview');\n\n try {\n const response = await fetch(`${API_BASE_URL}${path}`, {\n method: 'GET',\n headers: BASE_HEADERS,\n cache: isPreview ? 'no-cache' : 'force-cache',\n next: { tags: ['olmo', lang, path, model] },\n } as NextRequestInit);\n\n if (!response.ok) {\n console.error(`[olmo:get] ${response.status} ${response.statusText} — ${path}`);\n return undefined;\n }\n\n return (await response.json()) as T;\n } catch (error) {\n console.error(`[olmo:get] Network error — ${path}:`, error);\n return undefined;\n }\n}\n\nexport async function posting<T = unknown>(\n lang = 'it',\n path: string,\n body: object,\n): Promise<T> {\n try {\n const response = await fetch(`${API_BASE_URL}/${lang}/${path}`, {\n method: 'POST',\n headers: BASE_HEADERS,\n body: JSON.stringify(body),\n cache: 'force-cache',\n next: { tags: ['olmo', `/${lang}/allmodel/${path}`] },\n } as NextRequestInit);\n\n if (!response.ok) {\n console.error(`[olmo:post] ${response.status} ${response.statusText} — /${lang}/${path}`);\n throw new Error(`Olmo API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n if (data.errors) {\n throw new Error(`Olmo API returned errors for /${lang}/${path}: ${JSON.stringify(data.errors)}`);\n }\n\n return data.response as T;\n } catch (error) {\n console.error(`[olmo:post] Error — /${lang}/${path}:`, error);\n throw error;\n }\n}\n\nexport async function filter<T = unknown>(\n lang = 'it',\n path: string,\n body: object,\n): Promise<T> {\n try {\n const response = await fetch(`${API_BASE_URL}/${lang}/filters/${path}`, {\n method: 'POST',\n headers: BASE_HEADERS,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n console.error(`[olmo:filter] ${response.status} ${response.statusText} — /${lang}/filters/${path}`);\n throw new Error(`Olmo API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n if (data.errors) {\n console.error(`[olmo:filter] API errors — /${lang}/filters/${path}:`, data.errors);\n throw new Error(`Olmo API returned errors for /${lang}/filters/${path}: ${JSON.stringify(data.errors)}`);\n }\n\n return data as T;\n } catch (error) {\n console.error(`[olmo:filter] Error — /${lang}/filters/${path}:`, error);\n throw error;\n }\n}\n","export interface SeoDataOptions {\n seo: any;\n route: any;\n /**\n * Locale codes for hreflang alternates. Last entry becomes x-default.\n * Defaults to ['it', 'en'] when omitted.\n */\n locales?: string[];\n}\n\nexport const setSeoData = ({ seo, route, locales = ['it', 'en'] }: SeoDataOptions) => {\n if (!seo) return {};\n\n const baseUrl = process.env.NEXT_PUBLIC_API_STORAGE_URL;\n const frontUrl = process.env.NEXT_PUBLIC_BASE_URL;\n const ogImg = seo.og_img?.original;\n const ogUrl = ogImg?.compressed\n ? baseUrl + ogImg.compressed\n : frontUrl + '/images/og-image.jpg';\n\n const languagesMap: Record<string, string> = {};\n for (const loc of locales) {\n if (route.slug?.[loc] !== undefined) {\n languagesMap[loc] = `/${loc}/${route.slug[loc]}`;\n }\n }\n const defaultLocale = locales[locales.length - 1];\n if (route.slug?.[defaultLocale] !== undefined) {\n languagesMap['x-default'] = `/${defaultLocale}/${route.slug[defaultLocale]}`;\n }\n\n return {\n metadataBase: new URL(`${process.env.NEXT_PUBLIC_BASE_URL}`),\n title: seo.meta_title || '',\n description: seo.meta_description || '',\n robots: {\n index: seo.index === 'index',\n follow: seo.follow === 'follow',\n },\n openGraph: {\n title: seo.og_title || '',\n description: seo.og_description || '',\n url: seo.opengraphUrl || '',\n siteName: seo.opengraphSiteName || '',\n images: [\n {\n url: ogUrl,\n width: ogImg?.width || 1200,\n height: ogImg?.height || 630,\n alt: ogImg?.alt || '',\n },\n ],\n locale: route.locale,\n type: seo.opengraphType || 'website',\n },\n alternates: {\n canonical: `${process.env.NEXT_PUBLIC_BASE_URL}/${route.locale}/${route.slug[route.locale]}`,\n languages: languagesMap,\n },\n };\n};\n","const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL!;\nconst STORAGE_URL = process.env.NEXT_PUBLIC_API_STORAGE_URL!;\nconst SITE_NAME = process.env.NEXT_PUBLIC_SITE_NAME ?? 'Website';\n\ntype BreadcrumbItem = { name: string; url: string };\n\nexport const buildBreadcrumb = (items: BreadcrumbItem[]) => ({\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items.map((item, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n});\n\nexport const buildItemList = (items: any[], sectionUrl: string) => ({\n '@context': 'https://schema.org',\n '@type': 'ItemList',\n itemListElement: items.map((item, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: item.title_txt_content || item.name_txt_general,\n url: `${sectionUrl}${item.slug_txt_general}/`,\n })),\n});\n\nexport const buildArticle = (\n page: any,\n pathname: string,\n articleType: 'Article' | 'NewsArticle' = 'Article',\n publisherName?: string,\n) => {\n const name = publisherName ?? SITE_NAME;\n const pageUrl = `${BASE_URL}${pathname.endsWith('/') ? pathname : pathname + '/'}`;\n const imageUrl = (page.primary ?? page.cover)?.original?.compressed\n ? `${STORAGE_URL}${(page.primary ?? page.cover).original.compressed}`\n : undefined;\n const description = page.subtitle\n ? page.subtitle.replace(/<[^>]*>/g, '').trim()\n : undefined;\n\n const publisher = {\n '@type': 'Organization',\n name,\n url: BASE_URL,\n logo: { '@type': 'ImageObject', url: `${BASE_URL}/images/logo/logo.png` },\n };\n\n return {\n '@context': 'https://schema.org',\n '@type': articleType,\n headline: page.title,\n ...(description && { description }),\n ...(imageUrl && { image: imageUrl }),\n url: pageUrl,\n author: publisher,\n publisher,\n ...(page.lastmod && { datePublished: page.lastmod, dateModified: page.lastmod }),\n };\n};\n\nexport const buildWebSite = (locale: string, siteName?: string) => ({\n '@context': 'https://schema.org',\n '@type': 'WebSite',\n name: siteName ?? SITE_NAME,\n url: `${BASE_URL}/${locale}/`,\n});\n","import { NextResponse } from 'next/server';\nimport type { NextMiddleware } from 'next/server';\n\nexport type MiddlewareFactory = (middleware: NextMiddleware) => NextMiddleware;\n\nexport function chain(functions: MiddlewareFactory[] = [], index = 0): NextMiddleware {\n const current = functions[index];\n if (current) {\n const next = chain(functions, index + 1);\n return current(next);\n }\n return () => NextResponse.next();\n}\n","import { NextRequest } from 'next/server';\nimport type { NextFetchEvent } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\nexport const headermiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n const url = new URL(request.url);\n const params = new URLSearchParams(url.search);\n\n const headers = new Headers(request.headers);\n headers.set('x-current-path', request.nextUrl.pathname);\n headers.set('x-server', 'true');\n headers.set('olmo-preview', params.has('olmopreview').toString());\n\n return next(new NextRequest(request.url, { headers }), _next);\n };\n};\n","import { NextResponse } from 'next/server';\nimport type { NextFetchEvent, NextRequest } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\ntype NextFetchRequestInit = RequestInit & { next?: { tags?: string[]; revalidate?: number | false } };\n\nexport const redirectmiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n if (request.headers.has('rsc')) {\n return next(request, _next);\n }\n\n if (!process.env.NEXT_PUBLIC_OLMO_TOKEN || !process.env.NEXT_PUBLIC_API_URL || !process.env.NEXT_PUBLIC_BASE_URL) {\n return next(request, _next);\n }\n\n const pathNameWithTrailingSlash = request.nextUrl.pathname;\n\n const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/all/redirect`, {\n method: 'GET',\n cache: 'force-cache',\n next: { tags: ['olmo', 'redirect'] },\n headers: { 'front-token': process.env.NEXT_PUBLIC_OLMO_TOKEN },\n } as NextFetchRequestInit);\n\n const data = await response.json();\n\n const redirects = data.map((e: any) => ({\n source: e.source,\n destination: e.destination,\n permanent: e.permanent === 'true',\n }));\n\n if (redirects.length > 0) {\n const redirect = redirects.find((item: any) => item.source === pathNameWithTrailingSlash);\n\n if (!redirect) {\n return next(request, _next);\n }\n\n const newUrl = new URL(redirect.destination, process.env.NEXT_PUBLIC_BASE_URL).toString();\n return NextResponse.redirect(newUrl, { status: redirect.permanent ? 308 : 307 });\n }\n\n return next(request, _next);\n };\n};\n","'use client';\n\nimport { createContext, useContext, useState } from 'react';\nimport type { ReactNode } from 'react';\n\ntype LocaleSlugs = Record<string, string>;\n\nconst RouteContext = createContext<{\n slugs: LocaleSlugs;\n setSlugs: (slugs: LocaleSlugs) => void;\n}>({ slugs: {}, setSlugs: () => {} });\n\nexport function RouteProvider({ children }: { children: ReactNode }) {\n const [slugs, setSlugs] = useState<LocaleSlugs>({});\n return (\n <RouteContext.Provider value={{ slugs, setSlugs }}>\n {children}\n </RouteContext.Provider>\n );\n}\n\nexport const useRoute = () => useContext(RouteContext);\n","'use client';\n\nimport { useEffect } from 'react';\nimport { useRoute } from './RouteContext.js';\n\nexport function RouteSetter({ slugs }: { slugs: Record<string, string> }) {\n const { setSlugs } = useRoute();\n\n useEffect(() => {\n const leafSlugs = Object.fromEntries(\n Object.entries(slugs).map(([locale, slug]) => [locale, slug.split('/').pop() ?? slug]),\n );\n setSlugs(leafSlugs);\n return () => setSlugs({});\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(slugs)]);\n\n return null;\n}\n","export function JsonLd({ schema }: { schema: object }) {\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n );\n}\n","'use client';\n\nimport { useEffect } from 'react';\n\ninterface GtmPageProps {\n slug: string | null;\n lang: string | null;\n name: string | null;\n template: string | null;\n}\n\ninterface GtmFormProps {\n data: object | null;\n name: string | null;\n}\n\ninterface GtmClickProps {\n category: string | null;\n action: string | null;\n label: string | null;\n}\n\ndeclare global {\n interface Window {\n dataLayer: any[];\n }\n}\n\nexport function GtmPage({ slug, lang, name, template }: GtmPageProps) {\n useEffect(() => {\n if (slug) {\n gtmPageView({\n page_name: name,\n page_category: (template as any)?.name,\n page_language: lang,\n path_clean: slug,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [slug]);\n\n return <></>;\n}\n\nexport function gtmPageView(props: Record<string, any>) {\n return window.dataLayer?.push({ event: 'page_view', url: window.location.href, ...props });\n}\n\nexport function gtmFormSent({ data, name }: GtmFormProps) {\n return window.dataLayer?.push({ ...data, event: 'form_sent', form: name });\n}\n\nexport function gtmClick({ category, action, label }: GtmClickProps) {\n const cleanLabel = label?.split('/') ?? [];\n return window.dataLayer?.push({\n event: 'click',\n category,\n action,\n label: cleanLabel[cleanLabel.length - 1],\n });\n}\n"],"mappings":"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","names":["import_server","import_server","import_react","import_jsx_runtime","import_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client/index.ts","../src/seo/index.ts","../src/jsonld/index.ts","../src/middleware/chain.ts","../src/middleware/headermiddleware.ts","../src/middleware/redirectmiddleware.ts","../src/middleware/stagegatemiddleware.ts","../src/auth/stage.ts","../src/components/RouteContext.tsx","../src/components/RouteSetter.tsx","../src/components/JsonLd.tsx","../src/components/GtmPage.tsx","../src/components/StageLogin.tsx"],"sourcesContent":["export * from './client/index.js';\nexport * from './seo/index.js';\nexport * from './jsonld/index.js';\nexport * from './middleware/index.js';\nexport * from './components/index.js';\n","// Next.js extends RequestInit with a `next` property for cache tags / revalidation.\ntype NextRequestInit = RequestInit & {\n next?: { revalidate?: number | false; tags?: string[] };\n};\n\nconst API_BASE_URL = process.env.NEXT_PUBLIC_API_URL;\nconst API_TOKEN = process.env.NEXT_PUBLIC_OLMO_TOKEN as string;\n\nconst BASE_HEADERS: HeadersInit = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'front-token': API_TOKEN,\n};\n\nexport async function getting<T = unknown>(\n lang: string,\n path: string,\n model = '',\n): Promise<T | undefined> {\n const isPreview = path.includes('?olmopreview');\n\n try {\n const response = await fetch(`${API_BASE_URL}${path}`, {\n method: 'GET',\n headers: BASE_HEADERS,\n cache: isPreview ? 'no-cache' : 'force-cache',\n next: { tags: ['olmo', lang, path, model] },\n } as NextRequestInit);\n\n if (!response.ok) {\n console.error(`[olmo:get] ${response.status} ${response.statusText} — ${path}`);\n return undefined;\n }\n\n return (await response.json()) as T;\n } catch (error) {\n console.error(`[olmo:get] Network error — ${path}:`, error);\n return undefined;\n }\n}\n\nexport async function posting<T = unknown>(\n lang = 'it',\n path: string,\n body: object,\n): Promise<T> {\n try {\n const response = await fetch(`${API_BASE_URL}/${lang}/${path}`, {\n method: 'POST',\n headers: BASE_HEADERS,\n body: JSON.stringify(body),\n cache: 'force-cache',\n next: { tags: ['olmo', `/${lang}/allmodel/${path}`] },\n } as NextRequestInit);\n\n if (!response.ok) {\n console.error(`[olmo:post] ${response.status} ${response.statusText} — /${lang}/${path}`);\n throw new Error(`Olmo API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n if (data.errors) {\n throw new Error(`Olmo API returned errors for /${lang}/${path}: ${JSON.stringify(data.errors)}`);\n }\n\n return data.response as T;\n } catch (error) {\n console.error(`[olmo:post] Error — /${lang}/${path}:`, error);\n throw error;\n }\n}\n\nexport async function filter<T = unknown>(\n lang = 'it',\n path: string,\n body: object,\n): Promise<T> {\n try {\n const response = await fetch(`${API_BASE_URL}/${lang}/filters/${path}`, {\n method: 'POST',\n headers: BASE_HEADERS,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n console.error(`[olmo:filter] ${response.status} ${response.statusText} — /${lang}/filters/${path}`);\n throw new Error(`Olmo API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n if (data.errors) {\n console.error(`[olmo:filter] API errors — /${lang}/filters/${path}:`, data.errors);\n throw new Error(`Olmo API returned errors for /${lang}/filters/${path}: ${JSON.stringify(data.errors)}`);\n }\n\n return data as T;\n } catch (error) {\n console.error(`[olmo:filter] Error — /${lang}/filters/${path}:`, error);\n throw error;\n }\n}\n","export interface SeoDataOptions {\n seo: any;\n route: any;\n /**\n * Locale codes for hreflang alternates. Last entry becomes x-default.\n * Defaults to ['it', 'en'] when omitted.\n */\n locales?: string[];\n}\n\nexport const setSeoData = ({ seo, route, locales = ['it', 'en'] }: SeoDataOptions) => {\n if (!seo) return {};\n\n const baseUrl = process.env.NEXT_PUBLIC_API_STORAGE_URL;\n const frontUrl = process.env.NEXT_PUBLIC_BASE_URL;\n const ogImg = seo.og_img?.original;\n const ogUrl = ogImg?.compressed\n ? baseUrl + ogImg.compressed\n : frontUrl + '/images/og-image.jpg';\n\n const languagesMap: Record<string, string> = {};\n for (const loc of locales) {\n if (route.slug?.[loc] !== undefined) {\n languagesMap[loc] = `/${loc}/${route.slug[loc]}`;\n }\n }\n const defaultLocale = locales[locales.length - 1];\n if (route.slug?.[defaultLocale] !== undefined) {\n languagesMap['x-default'] = `/${defaultLocale}/${route.slug[defaultLocale]}`;\n }\n\n return {\n metadataBase: new URL(`${process.env.NEXT_PUBLIC_BASE_URL}`),\n title: seo.meta_title || '',\n description: seo.meta_description || '',\n robots: {\n index: seo.index === 'index',\n follow: seo.follow === 'follow',\n },\n openGraph: {\n title: seo.og_title || '',\n description: seo.og_description || '',\n url: seo.opengraphUrl || '',\n siteName: seo.opengraphSiteName || '',\n images: [\n {\n url: ogUrl,\n width: ogImg?.width || 1200,\n height: ogImg?.height || 630,\n alt: ogImg?.alt || '',\n },\n ],\n locale: route.locale,\n type: seo.opengraphType || 'website',\n },\n alternates: {\n canonical: `${process.env.NEXT_PUBLIC_BASE_URL}/${route.locale}/${route.slug[route.locale]}`,\n languages: languagesMap,\n },\n };\n};\n","const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL!;\nconst STORAGE_URL = process.env.NEXT_PUBLIC_API_STORAGE_URL!;\nconst SITE_NAME = process.env.NEXT_PUBLIC_SITE_NAME ?? 'Website';\n\ntype BreadcrumbItem = { name: string; url: string };\n\nexport const buildBreadcrumb = (items: BreadcrumbItem[]) => ({\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items.map((item, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n});\n\nexport const buildItemList = (items: any[], sectionUrl: string) => ({\n '@context': 'https://schema.org',\n '@type': 'ItemList',\n itemListElement: items.map((item, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: item.title_txt_content || item.name_txt_general,\n url: `${sectionUrl}${item.slug_txt_general}/`,\n })),\n});\n\nexport const buildArticle = (\n page: any,\n pathname: string,\n articleType: 'Article' | 'NewsArticle' = 'Article',\n publisherName?: string,\n) => {\n const name = publisherName ?? SITE_NAME;\n const pageUrl = `${BASE_URL}${pathname.endsWith('/') ? pathname : pathname + '/'}`;\n const imageUrl = (page.primary ?? page.cover)?.original?.compressed\n ? `${STORAGE_URL}${(page.primary ?? page.cover).original.compressed}`\n : undefined;\n const description = page.subtitle\n ? page.subtitle.replace(/<[^>]*>/g, '').trim()\n : undefined;\n\n const publisher = {\n '@type': 'Organization',\n name,\n url: BASE_URL,\n logo: { '@type': 'ImageObject', url: `${BASE_URL}/images/logo/logo.png` },\n };\n\n return {\n '@context': 'https://schema.org',\n '@type': articleType,\n headline: page.title,\n ...(description && { description }),\n ...(imageUrl && { image: imageUrl }),\n url: pageUrl,\n author: publisher,\n publisher,\n ...(page.lastmod && { datePublished: page.lastmod, dateModified: page.lastmod }),\n };\n};\n\nexport const buildWebSite = (locale: string, siteName?: string) => ({\n '@context': 'https://schema.org',\n '@type': 'WebSite',\n name: siteName ?? SITE_NAME,\n url: `${BASE_URL}/${locale}/`,\n});\n","import { NextResponse } from 'next/server';\nimport type { NextMiddleware } from 'next/server';\n\nexport type MiddlewareFactory = (middleware: NextMiddleware) => NextMiddleware;\n\nexport function chain(functions: MiddlewareFactory[] = [], index = 0): NextMiddleware {\n const current = functions[index];\n if (current) {\n const next = chain(functions, index + 1);\n return current(next);\n }\n return () => NextResponse.next();\n}\n","import { NextRequest } from 'next/server';\nimport type { NextFetchEvent } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\nexport const headermiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n const url = new URL(request.url);\n const params = new URLSearchParams(url.search);\n\n const headers = new Headers(request.headers);\n headers.set('x-current-path', request.nextUrl.pathname);\n headers.set('x-server', 'true');\n headers.set('olmo-preview', params.has('olmopreview').toString());\n\n return next(new NextRequest(request.url, { headers }), _next);\n };\n};\n","import { NextResponse } from 'next/server';\nimport type { NextFetchEvent, NextRequest } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\ntype NextFetchRequestInit = RequestInit & { next?: { tags?: string[]; revalidate?: number | false } };\n\nexport const redirectmiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n if (request.headers.has('rsc')) {\n return next(request, _next);\n }\n\n if (!process.env.NEXT_PUBLIC_OLMO_TOKEN || !process.env.NEXT_PUBLIC_API_URL || !process.env.NEXT_PUBLIC_BASE_URL) {\n return next(request, _next);\n }\n\n const pathNameWithTrailingSlash = request.nextUrl.pathname;\n\n const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/all/redirect`, {\n method: 'GET',\n cache: 'force-cache',\n next: { tags: ['olmo', 'redirect'] },\n headers: { 'front-token': process.env.NEXT_PUBLIC_OLMO_TOKEN },\n } as NextFetchRequestInit);\n\n const data = await response.json();\n\n const redirects = data.map((e: any) => ({\n source: e.source,\n destination: e.destination,\n permanent: e.permanent === 'true',\n }));\n\n if (redirects.length > 0) {\n const redirect = redirects.find((item: any) => item.source === pathNameWithTrailingSlash);\n\n if (!redirect) {\n return next(request, _next);\n }\n\n const newUrl = new URL(redirect.destination, process.env.NEXT_PUBLIC_BASE_URL).toString();\n return NextResponse.redirect(newUrl, { status: redirect.permanent ? 308 : 307 });\n }\n\n return next(request, _next);\n };\n};\n","import { NextResponse } from 'next/server';\nimport type { NextFetchEvent, NextRequest } from 'next/server';\nimport { getStageCookieName, readStageEnv, verifySession } from '../auth/stage.js';\nimport type { MiddlewareFactory } from './chain.js';\n\nconst LOGIN_PATH = '/olmo-stage-login/';\nconst NOINDEX = 'noindex, nofollow, noarchive';\n\nfunction withNoindex(res: NextResponse): NextResponse {\n res.headers.set('X-Robots-Tag', NOINDEX);\n return res;\n}\n\nexport const stagegatemiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n if (process.env.NEXT_PUBLIC_ENV !== 'stage') {\n return next(request, _next);\n }\n\n const { pathname, search } = request.nextUrl;\n\n if (pathname === LOGIN_PATH) {\n return withNoindex(NextResponse.next());\n }\n\n const env = readStageEnv();\n if (!env) {\n // Misconfigured stage — deny everything except the login page itself.\n const url = request.nextUrl.clone();\n url.pathname = LOGIN_PATH;\n url.search = '';\n return withNoindex(NextResponse.redirect(url, { status: 307 }));\n }\n\n const token = request.cookies.get(getStageCookieName())?.value;\n const session = await verifySession(token, env.secret);\n if (session) {\n const res = await next(request, _next);\n return withNoindex(res instanceof NextResponse ? res : NextResponse.next());\n }\n\n const url = request.nextUrl.clone();\n url.pathname = LOGIN_PATH;\n url.search = `?from=${encodeURIComponent(pathname + search)}`;\n return withNoindex(NextResponse.redirect(url, { status: 307 }));\n };\n};\n","// Internal helpers for the stage-environment auth gate.\n// Edge-runtime safe (uses Web Crypto, no Node APIs).\n\nconst COOKIE_NAME = 'olmo_stage_auth';\nconst DEFAULT_SESSION_DAYS = 7;\n\nexport type StagePayload = { u: string; exp: number };\n\nexport type StageEnv = {\n username: string;\n password: string;\n secret: string;\n sessionDays: number;\n};\n\nexport function readStageEnv(): StageEnv | null {\n const username = process.env.OLMO_STAGE_USERNAME;\n const password = process.env.OLMO_STAGE_PASSWORD;\n const secret = process.env.OLMO_STAGE_SECRET;\n if (!username || !password || !secret) return null;\n const days = Number(process.env.OLMO_STAGE_SESSION_DAYS);\n return {\n username,\n password,\n secret,\n sessionDays: Number.isFinite(days) && days > 0 ? days : DEFAULT_SESSION_DAYS,\n };\n}\n\nexport function getStageCookieName(): string {\n return COOKIE_NAME;\n}\n\nfunction toBase64Url(bytes: ArrayBuffer | Uint8Array): string {\n const arr = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n let str = '';\n for (let i = 0; i < arr.length; i++) str += String.fromCharCode(arr[i]);\n return btoa(str).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction fromBase64Url(input: string): Uint8Array {\n const pad = input.length % 4 === 0 ? '' : '='.repeat(4 - (input.length % 4));\n const b64 = input.replace(/-/g, '+').replace(/_/g, '/') + pad;\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nasync function importKey(secret: string): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign', 'verify'],\n );\n}\n\nexport async function signSession(payload: StagePayload, secret: string): Promise<string> {\n const body = toBase64Url(new TextEncoder().encode(JSON.stringify(payload)));\n const key = await importKey(secret);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return `${body}.${toBase64Url(sig)}`;\n}\n\nexport async function verifySession(token: string | undefined, secret: string): Promise<StagePayload | null> {\n if (!token || typeof token !== 'string' || token.indexOf('.') === -1) return null;\n const [body, sig] = token.split('.');\n if (!body || !sig) return null;\n let key: CryptoKey;\n try {\n key = await importKey(secret);\n } catch {\n return null;\n }\n let valid = false;\n try {\n valid = await crypto.subtle.verify('HMAC', key, fromBase64Url(sig) as BufferSource, new TextEncoder().encode(body));\n } catch {\n return null;\n }\n if (!valid) return null;\n let payload: StagePayload;\n try {\n payload = JSON.parse(new TextDecoder().decode(fromBase64Url(body)));\n } catch {\n return null;\n }\n if (!payload || typeof payload.exp !== 'number' || payload.exp < Date.now()) return null;\n return payload;\n}\n\nexport function verifyCredentials(env: StageEnv, username: unknown, password: unknown): boolean {\n if (typeof username !== 'string' || typeof password !== 'string') return false;\n return username === env.username && password === env.password;\n}\n","'use client';\n\nimport { createContext, useContext, useState } from 'react';\nimport type { ReactNode } from 'react';\n\ntype LocaleSlugs = Record<string, string>;\n\nconst RouteContext = createContext<{\n slugs: LocaleSlugs;\n setSlugs: (slugs: LocaleSlugs) => void;\n}>({ slugs: {}, setSlugs: () => {} });\n\nexport function RouteProvider({ children }: { children: ReactNode }) {\n const [slugs, setSlugs] = useState<LocaleSlugs>({});\n return (\n <RouteContext.Provider value={{ slugs, setSlugs }}>\n {children}\n </RouteContext.Provider>\n );\n}\n\nexport const useRoute = () => useContext(RouteContext);\n","'use client';\n\nimport { useEffect } from 'react';\nimport { useRoute } from './RouteContext.js';\n\nexport function RouteSetter({ slugs }: { slugs: Record<string, string> }) {\n const { setSlugs } = useRoute();\n\n useEffect(() => {\n const leafSlugs = Object.fromEntries(\n Object.entries(slugs).map(([locale, slug]) => [locale, slug.split('/').pop() ?? slug]),\n );\n setSlugs(leafSlugs);\n return () => setSlugs({});\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(slugs)]);\n\n return null;\n}\n","export function JsonLd({ schema }: { schema: object }) {\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n );\n}\n","'use client';\n\nimport { useEffect } from 'react';\n\ninterface GtmPageProps {\n slug: string | null;\n lang: string | null;\n name: string | null;\n template: string | null;\n}\n\ninterface GtmFormProps {\n data: object | null;\n name: string | null;\n}\n\ninterface GtmClickProps {\n category: string | null;\n action: string | null;\n label: string | null;\n}\n\ndeclare global {\n interface Window {\n dataLayer: any[];\n }\n}\n\nexport function GtmPage({ slug, lang, name, template }: GtmPageProps) {\n useEffect(() => {\n if (slug) {\n gtmPageView({\n page_name: name,\n page_category: (template as any)?.name,\n page_language: lang,\n path_clean: slug,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [slug]);\n\n return <></>;\n}\n\nexport function gtmPageView(props: Record<string, any>) {\n return window.dataLayer?.push({ event: 'page_view', url: window.location.href, ...props });\n}\n\nexport function gtmFormSent({ data, name }: GtmFormProps) {\n return window.dataLayer?.push({ ...data, event: 'form_sent', form: name });\n}\n\nexport function gtmClick({ category, action, label }: GtmClickProps) {\n const cleanLabel = label?.split('/') ?? [];\n return window.dataLayer?.push({\n event: 'click',\n category,\n action,\n label: cleanLabel[cleanLabel.length - 1],\n });\n}\n","import { useActionState, useEffect } from 'react';\nimport { useSearchParams, useRouter } from 'next/navigation';\n\nfunction OlmoLogo({ className }: { className?: string }) {\n return (\n <svg\n role=\"img\"\n aria-label=\"Olmo\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 225 232\"\n className={className}\n >\n <path d=\"M102.3,12.2c75-6.4,129.5,63.8,108.1,135.4-23.3,77.6-124.6,98.3-176.6,36.2C-18.2,121.7,19.1,19.2,102.4,12.2h-.1ZM87.4,202.3c35.6,9.9,73.6-2.3,95.6-32.1,37.4-50.9,12.4-125.6-49.4-140.8C59.5,11.2,1.3,86.9,32.6,154.9c7.7,16.8,23.8,34.9,41.6,40.8l5.5-20.1c-20-27-17.3-63.2,7.3-86.4,11-10.3,38.6-24.9,53.1-28.9s8.1-.9,10.4,3.2,6.5,23.1,7.4,28.4c4,22.6,2.1,44.6-13,62.8-13.1,15.8-31,22.5-50.8,25.5l-6.6,22.1h0ZM139.2,77c-33.7,10.7-72,38.9-54.1,79.1l11-20.1c4.1-4.6,12.6-23.1,17.7-24.7,6.3-2,10.9,3.5,8.7,9.7s-11.8,18.1-15.5,25.1-9,17.8-8.3,18.5c43-8.8,54.8-49.5,40.5-87.6h0Z\" />\n </svg>\n );\n}\n\ntype StageLoginState = {\n error?: 'missing_config' | 'invalid_credentials' | null;\n redirectTo?: string | null;\n};\n\ntype StageLoginAction = (prev: StageLoginState, formData: FormData) => Promise<StageLoginState>;\n\nexport type StageLoginProps = {\n action: StageLoginAction;\n title?: string;\n description?: string;\n usernameLabel?: string;\n passwordLabel?: string;\n submitLabel?: string;\n invalidCredentialsMessage?: string;\n missingConfigMessage?: string;\n};\n\nexport function StageLoginOLD({\n action,\n title = 'Staging access',\n description = 'This environment is restricted. Please sign in to continue.',\n usernameLabel = 'Username',\n passwordLabel = 'Password',\n submitLabel = 'Sign in',\n invalidCredentialsMessage = 'Invalid username or password.',\n missingConfigMessage = 'Stage authentication is not configured.',\n}: StageLoginProps) {\n const params = useSearchParams();\n const from = params.get('from') ?? '/';\n const [state, formAction, pending] = useActionState<StageLoginState, FormData>(action, {});\n\n const errorMessage =\n state.error === 'invalid_credentials'\n ? invalidCredentialsMessage\n : state.error === 'missing_config'\n ? missingConfigMessage\n : null;\n\n return (\n <main className=\"flex min-h-screen items-center justify-center bg-neutral-50 px-4 py-12\">\n <form\n action={formAction}\n className=\"relative w-full max-w-md space-y-5 rounded-lg border border-neutral-200 bg-white p-8 shadow-sm\"\n >\n <div className=\"w-full min-w-[200px]\">\n <header className=\"space-y-1 text-center\">\n <h1 className=\"text-xl font-semibold text-neutral-900\">{title}</h1>\n <p className=\"text-sm text-neutral-600\">{description}</p>\n </header>\n\n <input type=\"hidden\" name=\"from\" value={from} />\n\n <label className=\"block space-y-1\">\n <span className=\"text-sm font-medium text-neutral-800\">{usernameLabel}</span>\n <input\n name=\"username\"\n type=\"text\"\n autoComplete=\"username\"\n required\n disabled={pending}\n className=\"w-full rounded border border-neutral-300 px-3 py-2 text-sm outline-none focus:border-neutral-900\"\n />\n </label>\n\n <label className=\"block space-y-1\">\n <span className=\"text-sm font-medium text-neutral-800\">{passwordLabel}</span>\n <input\n name=\"password\"\n type=\"password\"\n autoComplete=\"current-password\"\n required\n disabled={pending}\n className=\"w-full rounded border border-neutral-300 px-3 py-2 text-sm outline-none focus:border-neutral-900\"\n />\n </label>\n\n {errorMessage ? (\n <p role=\"alert\" className=\"text-sm text-red-600\">\n {errorMessage}\n </p>\n ) : null}\n\n <button\n type=\"submit\"\n disabled={pending}\n className=\"w-full rounded bg-neutral-900 px-4 py-2 text-sm font-medium text-white transition hover:bg-neutral-800 disabled:opacity-60\"\n >\n {pending ? '…' : submitLabel}\n </button>\n </div>\n </form>\n </main>\n );\n}\n\n\nexport function StageLogin({\n action,\n title = 'Olmo Staging access',\n description = 'This environment is restricted. Please sign in to continue.',\n usernameLabel = 'Username',\n passwordLabel = 'Password',\n submitLabel = 'Sign in',\n invalidCredentialsMessage = 'Invalid username or password.',\n missingConfigMessage = 'Stage authentication is not configured.', \n}: StageLoginProps) {\n \n const params = useSearchParams();\n const router = useRouter();\n const from = params.get('from') ?? '/';\n const [state, formAction, pending] = useActionState<StageLoginState, FormData>(action, {});\n\n // Once the action returns a redirect target the cookie is already in the\n // browser's jar (it shipped as Set-Cookie on the action response). Only\n // then do we navigate, so the next GET carries the session and middleware\n // doesn't bounce the user back to login.\n useEffect(() => {\n if (state.redirectTo) router.replace(state.redirectTo);\n }, [state.redirectTo, router]);\n\n const errorMessage =\n state.error === 'invalid_credentials'\n ? invalidCredentialsMessage\n : state.error === 'missing_config'\n ? missingConfigMessage\n : null;\n\n return (\n <>\n <div className=\"flex min-h-full flex-col justify-center px-6 py-12 lg:px-8\">\n <div className=\"sm:mx-auto sm:w-full sm:max-w-[384px]\">\n <OlmoLogo className=\"mx-auto h-10 w-auto \" />\n {/* <h2 className=\"mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900\">\n Sign in to your account\n </h2> */}\n <header className=\"space-y-1\">\n <h1 className=\"text-xl text-center font-semibold text-neutral-900\">{title}</h1>\n <p className=\"text-sm text-center text-neutral-600\">{description}</p>\n </header> \n </div>\n\n <div className=\"mt-10 sm:mx-auto sm:w-full sm:max-w-[384px]\">\n <form action={formAction} method=\"POST\" className=\"space-y-6\">\n <input type=\"hidden\" name=\"from\" value={from} />\n <div>\n <label htmlFor=\"username\" className=\"block text-sm/6 font-medium text-gray-900\">\n {usernameLabel}\n </label>\n <div className=\"mt-2\">\n <input\n id=\"username\"\n name=\"username\"\n type=\"username\"\n disabled={pending}\n required\n autoComplete=\"username\"\n className=\"block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-black sm:text-sm/6\"\n />\n </div>\n </div>\n\n <div>\n <div className=\"flex items-center justify-between\">\n <label htmlFor=\"password\" className=\"block text-sm/6 font-medium text-gray-900\">\n {passwordLabel}\n </label>\n </div>\n <div className=\"mt-2\">\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n disabled={pending}\n required\n autoComplete=\"current-password\"\n className=\"block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-black sm:text-sm/6\"\n />\n </div>\n </div>\n\n <div>\n {errorMessage ? (\n <p role=\"alert\" className=\"text-sm text-red-600\">\n {errorMessage}\n </p>\n ) : null} \n <button\n type=\"submit\"\n disabled={pending}\n className=\"cursor-pointer flex w-full justify-center rounded-md bg-black px-3 py-1.5 text-sm/6 font-semibold text-white shadow-xs hover:bg-black focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-black\"\n >\n {pending ? '…' : submitLabel}\n </button>\n </div>\n </form>\n\n </div>\n </div>\n </>\n )\n}\n"],"mappings":"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","names":["import_server","import_server","import_server","url","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime"]}
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { filter, getting, posting } from './client/index.cjs';
2
2
  export { SeoDataOptions, setSeoData } from './seo/index.cjs';
3
3
  export { buildArticle, buildBreadcrumb, buildItemList, buildWebSite } from './jsonld/index.cjs';
4
- export { MiddlewareFactory, chain, headermiddleware, redirectmiddleware } from './middleware/index.cjs';
4
+ export { MiddlewareFactory, chain, headermiddleware, redirectmiddleware, stagegatemiddleware } from './middleware/index.cjs';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { ReactNode } from 'react';
7
7
  import 'next/server';
@@ -48,4 +48,21 @@ declare function gtmPageView(props: Record<string, any>): number;
48
48
  declare function gtmFormSent({ data, name }: GtmFormProps): number;
49
49
  declare function gtmClick({ category, action, label }: GtmClickProps): number;
50
50
 
51
- export { GtmPage, JsonLd, RouteProvider, RouteSetter, gtmClick, gtmFormSent, gtmPageView, useRoute };
51
+ type StageLoginState = {
52
+ error?: 'missing_config' | 'invalid_credentials' | null;
53
+ redirectTo?: string | null;
54
+ };
55
+ type StageLoginAction = (prev: StageLoginState, formData: FormData) => Promise<StageLoginState>;
56
+ type StageLoginProps = {
57
+ action: StageLoginAction;
58
+ title?: string;
59
+ description?: string;
60
+ usernameLabel?: string;
61
+ passwordLabel?: string;
62
+ submitLabel?: string;
63
+ invalidCredentialsMessage?: string;
64
+ missingConfigMessage?: string;
65
+ };
66
+ declare function StageLogin({ action, title, description, usernameLabel, passwordLabel, submitLabel, invalidCredentialsMessage, missingConfigMessage, }: StageLoginProps): react_jsx_runtime.JSX.Element;
67
+
68
+ export { GtmPage, JsonLd, RouteProvider, RouteSetter, StageLogin, type StageLoginProps, gtmClick, gtmFormSent, gtmPageView, useRoute };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { filter, getting, posting } from './client/index.js';
2
2
  export { SeoDataOptions, setSeoData } from './seo/index.js';
3
3
  export { buildArticle, buildBreadcrumb, buildItemList, buildWebSite } from './jsonld/index.js';
4
- export { MiddlewareFactory, chain, headermiddleware, redirectmiddleware } from './middleware/index.js';
4
+ export { MiddlewareFactory, chain, headermiddleware, redirectmiddleware, stagegatemiddleware } from './middleware/index.js';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { ReactNode } from 'react';
7
7
  import 'next/server';
@@ -48,4 +48,21 @@ declare function gtmPageView(props: Record<string, any>): number;
48
48
  declare function gtmFormSent({ data, name }: GtmFormProps): number;
49
49
  declare function gtmClick({ category, action, label }: GtmClickProps): number;
50
50
 
51
- export { GtmPage, JsonLd, RouteProvider, RouteSetter, gtmClick, gtmFormSent, gtmPageView, useRoute };
51
+ type StageLoginState = {
52
+ error?: 'missing_config' | 'invalid_credentials' | null;
53
+ redirectTo?: string | null;
54
+ };
55
+ type StageLoginAction = (prev: StageLoginState, formData: FormData) => Promise<StageLoginState>;
56
+ type StageLoginProps = {
57
+ action: StageLoginAction;
58
+ title?: string;
59
+ description?: string;
60
+ usernameLabel?: string;
61
+ passwordLabel?: string;
62
+ submitLabel?: string;
63
+ invalidCredentialsMessage?: string;
64
+ missingConfigMessage?: string;
65
+ };
66
+ declare function StageLogin({ action, title, description, usernameLabel, passwordLabel, submitLabel, invalidCredentialsMessage, missingConfigMessage, }: StageLoginProps): react_jsx_runtime.JSX.Element;
67
+
68
+ export { GtmPage, JsonLd, RouteProvider, RouteSetter, StageLogin, type StageLoginProps, gtmClick, gtmFormSent, gtmPageView, useRoute };
package/dist/index.js CHANGED
@@ -15,8 +15,9 @@ import {
15
15
  import {
16
16
  chain,
17
17
  headermiddleware,
18
- redirectmiddleware
19
- } from "./chunk-GQITFXCV.js";
18
+ redirectmiddleware,
19
+ stagegatemiddleware
20
+ } from "./chunk-UCR7WW3X.js";
20
21
 
21
22
  // src/components/RouteContext.tsx
22
23
  import { createContext, useContext, useState } from "react";
@@ -86,11 +87,103 @@ function gtmClick({ category, action, label }) {
86
87
  label: cleanLabel[cleanLabel.length - 1]
87
88
  });
88
89
  }
90
+
91
+ // src/components/StageLogin.tsx
92
+ import { useActionState, useEffect as useEffect3 } from "react";
93
+ import { useSearchParams, useRouter } from "next/navigation";
94
+ import { Fragment as Fragment2, jsx as jsx4, jsxs } from "react/jsx-runtime";
95
+ function OlmoLogo({ className }) {
96
+ return /* @__PURE__ */ jsx4(
97
+ "svg",
98
+ {
99
+ role: "img",
100
+ "aria-label": "Olmo",
101
+ xmlns: "http://www.w3.org/2000/svg",
102
+ viewBox: "0 0 225 232",
103
+ className,
104
+ children: /* @__PURE__ */ jsx4("path", { d: "M102.3,12.2c75-6.4,129.5,63.8,108.1,135.4-23.3,77.6-124.6,98.3-176.6,36.2C-18.2,121.7,19.1,19.2,102.4,12.2h-.1ZM87.4,202.3c35.6,9.9,73.6-2.3,95.6-32.1,37.4-50.9,12.4-125.6-49.4-140.8C59.5,11.2,1.3,86.9,32.6,154.9c7.7,16.8,23.8,34.9,41.6,40.8l5.5-20.1c-20-27-17.3-63.2,7.3-86.4,11-10.3,38.6-24.9,53.1-28.9s8.1-.9,10.4,3.2,6.5,23.1,7.4,28.4c4,22.6,2.1,44.6-13,62.8-13.1,15.8-31,22.5-50.8,25.5l-6.6,22.1h0ZM139.2,77c-33.7,10.7-72,38.9-54.1,79.1l11-20.1c4.1-4.6,12.6-23.1,17.7-24.7,6.3-2,10.9,3.5,8.7,9.7s-11.8,18.1-15.5,25.1-9,17.8-8.3,18.5c43-8.8,54.8-49.5,40.5-87.6h0Z" })
105
+ }
106
+ );
107
+ }
108
+ function StageLogin({
109
+ action,
110
+ title = "Olmo Staging access",
111
+ description = "This environment is restricted. Please sign in to continue.",
112
+ usernameLabel = "Username",
113
+ passwordLabel = "Password",
114
+ submitLabel = "Sign in",
115
+ invalidCredentialsMessage = "Invalid username or password.",
116
+ missingConfigMessage = "Stage authentication is not configured."
117
+ }) {
118
+ const params = useSearchParams();
119
+ const router = useRouter();
120
+ const from = params.get("from") ?? "/";
121
+ const [state, formAction, pending] = useActionState(action, {});
122
+ useEffect3(() => {
123
+ if (state.redirectTo) router.replace(state.redirectTo);
124
+ }, [state.redirectTo, router]);
125
+ const errorMessage = state.error === "invalid_credentials" ? invalidCredentialsMessage : state.error === "missing_config" ? missingConfigMessage : null;
126
+ return /* @__PURE__ */ jsx4(Fragment2, { children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-full flex-col justify-center px-6 py-12 lg:px-8", children: [
127
+ /* @__PURE__ */ jsxs("div", { className: "sm:mx-auto sm:w-full sm:max-w-[384px]", children: [
128
+ /* @__PURE__ */ jsx4(OlmoLogo, { className: "mx-auto h-10 w-auto " }),
129
+ /* @__PURE__ */ jsxs("header", { className: "space-y-1", children: [
130
+ /* @__PURE__ */ jsx4("h1", { className: "text-xl text-center font-semibold text-neutral-900", children: title }),
131
+ /* @__PURE__ */ jsx4("p", { className: "text-sm text-center text-neutral-600", children: description })
132
+ ] })
133
+ ] }),
134
+ /* @__PURE__ */ jsx4("div", { className: "mt-10 sm:mx-auto sm:w-full sm:max-w-[384px]", children: /* @__PURE__ */ jsxs("form", { action: formAction, method: "POST", className: "space-y-6", children: [
135
+ /* @__PURE__ */ jsx4("input", { type: "hidden", name: "from", value: from }),
136
+ /* @__PURE__ */ jsxs("div", { children: [
137
+ /* @__PURE__ */ jsx4("label", { htmlFor: "username", className: "block text-sm/6 font-medium text-gray-900", children: usernameLabel }),
138
+ /* @__PURE__ */ jsx4("div", { className: "mt-2", children: /* @__PURE__ */ jsx4(
139
+ "input",
140
+ {
141
+ id: "username",
142
+ name: "username",
143
+ type: "username",
144
+ disabled: pending,
145
+ required: true,
146
+ autoComplete: "username",
147
+ className: "block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-black sm:text-sm/6"
148
+ }
149
+ ) })
150
+ ] }),
151
+ /* @__PURE__ */ jsxs("div", { children: [
152
+ /* @__PURE__ */ jsx4("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx4("label", { htmlFor: "password", className: "block text-sm/6 font-medium text-gray-900", children: passwordLabel }) }),
153
+ /* @__PURE__ */ jsx4("div", { className: "mt-2", children: /* @__PURE__ */ jsx4(
154
+ "input",
155
+ {
156
+ id: "password",
157
+ name: "password",
158
+ type: "password",
159
+ disabled: pending,
160
+ required: true,
161
+ autoComplete: "current-password",
162
+ className: "block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-black sm:text-sm/6"
163
+ }
164
+ ) })
165
+ ] }),
166
+ /* @__PURE__ */ jsxs("div", { children: [
167
+ errorMessage ? /* @__PURE__ */ jsx4("p", { role: "alert", className: "text-sm text-red-600", children: errorMessage }) : null,
168
+ /* @__PURE__ */ jsx4(
169
+ "button",
170
+ {
171
+ type: "submit",
172
+ disabled: pending,
173
+ className: "cursor-pointer flex w-full justify-center rounded-md bg-black px-3 py-1.5 text-sm/6 font-semibold text-white shadow-xs hover:bg-black focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-black",
174
+ children: pending ? "\u2026" : submitLabel
175
+ }
176
+ )
177
+ ] })
178
+ ] }) })
179
+ ] }) });
180
+ }
89
181
  export {
90
182
  GtmPage,
91
183
  JsonLd,
92
184
  RouteProvider,
93
185
  RouteSetter,
186
+ StageLogin,
94
187
  buildArticle,
95
188
  buildBreadcrumb,
96
189
  buildItemList,
@@ -105,6 +198,7 @@ export {
105
198
  posting,
106
199
  redirectmiddleware,
107
200
  setSeoData,
201
+ stagegatemiddleware,
108
202
  useRoute
109
203
  };
110
204
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/RouteContext.tsx","../src/components/RouteSetter.tsx","../src/components/JsonLd.tsx","../src/components/GtmPage.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useState } from 'react';\nimport type { ReactNode } from 'react';\n\ntype LocaleSlugs = Record<string, string>;\n\nconst RouteContext = createContext<{\n slugs: LocaleSlugs;\n setSlugs: (slugs: LocaleSlugs) => void;\n}>({ slugs: {}, setSlugs: () => {} });\n\nexport function RouteProvider({ children }: { children: ReactNode }) {\n const [slugs, setSlugs] = useState<LocaleSlugs>({});\n return (\n <RouteContext.Provider value={{ slugs, setSlugs }}>\n {children}\n </RouteContext.Provider>\n );\n}\n\nexport const useRoute = () => useContext(RouteContext);\n","'use client';\n\nimport { useEffect } from 'react';\nimport { useRoute } from './RouteContext.js';\n\nexport function RouteSetter({ slugs }: { slugs: Record<string, string> }) {\n const { setSlugs } = useRoute();\n\n useEffect(() => {\n const leafSlugs = Object.fromEntries(\n Object.entries(slugs).map(([locale, slug]) => [locale, slug.split('/').pop() ?? slug]),\n );\n setSlugs(leafSlugs);\n return () => setSlugs({});\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(slugs)]);\n\n return null;\n}\n","export function JsonLd({ schema }: { schema: object }) {\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n );\n}\n","'use client';\n\nimport { useEffect } from 'react';\n\ninterface GtmPageProps {\n slug: string | null;\n lang: string | null;\n name: string | null;\n template: string | null;\n}\n\ninterface GtmFormProps {\n data: object | null;\n name: string | null;\n}\n\ninterface GtmClickProps {\n category: string | null;\n action: string | null;\n label: string | null;\n}\n\ndeclare global {\n interface Window {\n dataLayer: any[];\n }\n}\n\nexport function GtmPage({ slug, lang, name, template }: GtmPageProps) {\n useEffect(() => {\n if (slug) {\n gtmPageView({\n page_name: name,\n page_category: (template as any)?.name,\n page_language: lang,\n path_clean: slug,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [slug]);\n\n return <></>;\n}\n\nexport function gtmPageView(props: Record<string, any>) {\n return window.dataLayer?.push({ event: 'page_view', url: window.location.href, ...props });\n}\n\nexport function gtmFormSent({ data, name }: GtmFormProps) {\n return window.dataLayer?.push({ ...data, event: 'form_sent', form: name });\n}\n\nexport function gtmClick({ category, action, label }: GtmClickProps) {\n const cleanLabel = label?.split('/') ?? [];\n return window.dataLayer?.push({\n event: 'click',\n category,\n action,\n label: cleanLabel[cleanLabel.length - 1],\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAEA,SAAS,eAAe,YAAY,gBAAgB;AAahD;AARJ,IAAM,eAAe,cAGlB,EAAE,OAAO,CAAC,GAAG,UAAU,MAAM;AAAC,EAAE,CAAC;AAE7B,SAAS,cAAc,EAAE,SAAS,GAA4B;AACnE,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAsB,CAAC,CAAC;AAClD,SACE,oBAAC,aAAa,UAAb,EAAsB,OAAO,EAAE,OAAO,SAAS,GAC7C,UACH;AAEJ;AAEO,IAAM,WAAW,MAAM,WAAW,YAAY;;;ACnBrD,SAAS,iBAAiB;AAGnB,SAAS,YAAY,EAAE,MAAM,GAAsC;AACxE,QAAM,EAAE,SAAS,IAAI,SAAS;AAE9B,YAAU,MAAM;AACd,UAAM,YAAY,OAAO;AAAA,MACvB,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC;AAAA,IACvF;AACA,aAAS,SAAS;AAClB,WAAO,MAAM,SAAS,CAAC,CAAC;AAAA,EAE1B,GAAG,CAAC,KAAK,UAAU,KAAK,CAAC,CAAC;AAE1B,SAAO;AACT;;;AChBI,gBAAAA,YAAA;AAFG,SAAS,OAAO,EAAE,OAAO,GAAuB;AACrD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,yBAAyB,EAAE,QAAQ,KAAK,UAAU,MAAM,EAAE;AAAA;AAAA,EAC5D;AAEJ;;;ACLA,SAAS,aAAAC,kBAAiB;AAuCjB,0BAAAC,YAAA;AAbF,SAAS,QAAQ,EAAE,MAAM,MAAM,MAAM,SAAS,GAAiB;AACpE,EAAAD,WAAU,MAAM;AACd,QAAI,MAAM;AACR,kBAAY;AAAA,QACV,WAAW;AAAA,QACX,eAAgB,UAAkB;AAAA,QAClC,eAAe;AAAA,QACf,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EAEF,GAAG,CAAC,IAAI,CAAC;AAET,SAAO,gBAAAC,KAAA,YAAE;AACX;AAEO,SAAS,YAAY,OAA4B;AACtD,SAAO,OAAO,WAAW,KAAK,EAAE,OAAO,aAAa,KAAK,OAAO,SAAS,MAAM,GAAG,MAAM,CAAC;AAC3F;AAEO,SAAS,YAAY,EAAE,MAAM,KAAK,GAAiB;AACxD,SAAO,OAAO,WAAW,KAAK,EAAE,GAAG,MAAM,OAAO,aAAa,MAAM,KAAK,CAAC;AAC3E;AAEO,SAAS,SAAS,EAAE,UAAU,QAAQ,MAAM,GAAkB;AACnE,QAAM,aAAa,OAAO,MAAM,GAAG,KAAK,CAAC;AACzC,SAAO,OAAO,WAAW,KAAK;AAAA,IAC5B,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,OAAO,WAAW,WAAW,SAAS,CAAC;AAAA,EACzC,CAAC;AACH;","names":["jsx","useEffect","jsx"]}
1
+ {"version":3,"sources":["../src/components/RouteContext.tsx","../src/components/RouteSetter.tsx","../src/components/JsonLd.tsx","../src/components/GtmPage.tsx","../src/components/StageLogin.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useState } from 'react';\nimport type { ReactNode } from 'react';\n\ntype LocaleSlugs = Record<string, string>;\n\nconst RouteContext = createContext<{\n slugs: LocaleSlugs;\n setSlugs: (slugs: LocaleSlugs) => void;\n}>({ slugs: {}, setSlugs: () => {} });\n\nexport function RouteProvider({ children }: { children: ReactNode }) {\n const [slugs, setSlugs] = useState<LocaleSlugs>({});\n return (\n <RouteContext.Provider value={{ slugs, setSlugs }}>\n {children}\n </RouteContext.Provider>\n );\n}\n\nexport const useRoute = () => useContext(RouteContext);\n","'use client';\n\nimport { useEffect } from 'react';\nimport { useRoute } from './RouteContext.js';\n\nexport function RouteSetter({ slugs }: { slugs: Record<string, string> }) {\n const { setSlugs } = useRoute();\n\n useEffect(() => {\n const leafSlugs = Object.fromEntries(\n Object.entries(slugs).map(([locale, slug]) => [locale, slug.split('/').pop() ?? slug]),\n );\n setSlugs(leafSlugs);\n return () => setSlugs({});\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(slugs)]);\n\n return null;\n}\n","export function JsonLd({ schema }: { schema: object }) {\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n );\n}\n","'use client';\n\nimport { useEffect } from 'react';\n\ninterface GtmPageProps {\n slug: string | null;\n lang: string | null;\n name: string | null;\n template: string | null;\n}\n\ninterface GtmFormProps {\n data: object | null;\n name: string | null;\n}\n\ninterface GtmClickProps {\n category: string | null;\n action: string | null;\n label: string | null;\n}\n\ndeclare global {\n interface Window {\n dataLayer: any[];\n }\n}\n\nexport function GtmPage({ slug, lang, name, template }: GtmPageProps) {\n useEffect(() => {\n if (slug) {\n gtmPageView({\n page_name: name,\n page_category: (template as any)?.name,\n page_language: lang,\n path_clean: slug,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [slug]);\n\n return <></>;\n}\n\nexport function gtmPageView(props: Record<string, any>) {\n return window.dataLayer?.push({ event: 'page_view', url: window.location.href, ...props });\n}\n\nexport function gtmFormSent({ data, name }: GtmFormProps) {\n return window.dataLayer?.push({ ...data, event: 'form_sent', form: name });\n}\n\nexport function gtmClick({ category, action, label }: GtmClickProps) {\n const cleanLabel = label?.split('/') ?? [];\n return window.dataLayer?.push({\n event: 'click',\n category,\n action,\n label: cleanLabel[cleanLabel.length - 1],\n });\n}\n","import { useActionState, useEffect } from 'react';\nimport { useSearchParams, useRouter } from 'next/navigation';\n\nfunction OlmoLogo({ className }: { className?: string }) {\n return (\n <svg\n role=\"img\"\n aria-label=\"Olmo\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 225 232\"\n className={className}\n >\n <path d=\"M102.3,12.2c75-6.4,129.5,63.8,108.1,135.4-23.3,77.6-124.6,98.3-176.6,36.2C-18.2,121.7,19.1,19.2,102.4,12.2h-.1ZM87.4,202.3c35.6,9.9,73.6-2.3,95.6-32.1,37.4-50.9,12.4-125.6-49.4-140.8C59.5,11.2,1.3,86.9,32.6,154.9c7.7,16.8,23.8,34.9,41.6,40.8l5.5-20.1c-20-27-17.3-63.2,7.3-86.4,11-10.3,38.6-24.9,53.1-28.9s8.1-.9,10.4,3.2,6.5,23.1,7.4,28.4c4,22.6,2.1,44.6-13,62.8-13.1,15.8-31,22.5-50.8,25.5l-6.6,22.1h0ZM139.2,77c-33.7,10.7-72,38.9-54.1,79.1l11-20.1c4.1-4.6,12.6-23.1,17.7-24.7,6.3-2,10.9,3.5,8.7,9.7s-11.8,18.1-15.5,25.1-9,17.8-8.3,18.5c43-8.8,54.8-49.5,40.5-87.6h0Z\" />\n </svg>\n );\n}\n\ntype StageLoginState = {\n error?: 'missing_config' | 'invalid_credentials' | null;\n redirectTo?: string | null;\n};\n\ntype StageLoginAction = (prev: StageLoginState, formData: FormData) => Promise<StageLoginState>;\n\nexport type StageLoginProps = {\n action: StageLoginAction;\n title?: string;\n description?: string;\n usernameLabel?: string;\n passwordLabel?: string;\n submitLabel?: string;\n invalidCredentialsMessage?: string;\n missingConfigMessage?: string;\n};\n\nexport function StageLoginOLD({\n action,\n title = 'Staging access',\n description = 'This environment is restricted. Please sign in to continue.',\n usernameLabel = 'Username',\n passwordLabel = 'Password',\n submitLabel = 'Sign in',\n invalidCredentialsMessage = 'Invalid username or password.',\n missingConfigMessage = 'Stage authentication is not configured.',\n}: StageLoginProps) {\n const params = useSearchParams();\n const from = params.get('from') ?? '/';\n const [state, formAction, pending] = useActionState<StageLoginState, FormData>(action, {});\n\n const errorMessage =\n state.error === 'invalid_credentials'\n ? invalidCredentialsMessage\n : state.error === 'missing_config'\n ? missingConfigMessage\n : null;\n\n return (\n <main className=\"flex min-h-screen items-center justify-center bg-neutral-50 px-4 py-12\">\n <form\n action={formAction}\n className=\"relative w-full max-w-md space-y-5 rounded-lg border border-neutral-200 bg-white p-8 shadow-sm\"\n >\n <div className=\"w-full min-w-[200px]\">\n <header className=\"space-y-1 text-center\">\n <h1 className=\"text-xl font-semibold text-neutral-900\">{title}</h1>\n <p className=\"text-sm text-neutral-600\">{description}</p>\n </header>\n\n <input type=\"hidden\" name=\"from\" value={from} />\n\n <label className=\"block space-y-1\">\n <span className=\"text-sm font-medium text-neutral-800\">{usernameLabel}</span>\n <input\n name=\"username\"\n type=\"text\"\n autoComplete=\"username\"\n required\n disabled={pending}\n className=\"w-full rounded border border-neutral-300 px-3 py-2 text-sm outline-none focus:border-neutral-900\"\n />\n </label>\n\n <label className=\"block space-y-1\">\n <span className=\"text-sm font-medium text-neutral-800\">{passwordLabel}</span>\n <input\n name=\"password\"\n type=\"password\"\n autoComplete=\"current-password\"\n required\n disabled={pending}\n className=\"w-full rounded border border-neutral-300 px-3 py-2 text-sm outline-none focus:border-neutral-900\"\n />\n </label>\n\n {errorMessage ? (\n <p role=\"alert\" className=\"text-sm text-red-600\">\n {errorMessage}\n </p>\n ) : null}\n\n <button\n type=\"submit\"\n disabled={pending}\n className=\"w-full rounded bg-neutral-900 px-4 py-2 text-sm font-medium text-white transition hover:bg-neutral-800 disabled:opacity-60\"\n >\n {pending ? '…' : submitLabel}\n </button>\n </div>\n </form>\n </main>\n );\n}\n\n\nexport function StageLogin({\n action,\n title = 'Olmo Staging access',\n description = 'This environment is restricted. Please sign in to continue.',\n usernameLabel = 'Username',\n passwordLabel = 'Password',\n submitLabel = 'Sign in',\n invalidCredentialsMessage = 'Invalid username or password.',\n missingConfigMessage = 'Stage authentication is not configured.', \n}: StageLoginProps) {\n \n const params = useSearchParams();\n const router = useRouter();\n const from = params.get('from') ?? '/';\n const [state, formAction, pending] = useActionState<StageLoginState, FormData>(action, {});\n\n // Once the action returns a redirect target the cookie is already in the\n // browser's jar (it shipped as Set-Cookie on the action response). Only\n // then do we navigate, so the next GET carries the session and middleware\n // doesn't bounce the user back to login.\n useEffect(() => {\n if (state.redirectTo) router.replace(state.redirectTo);\n }, [state.redirectTo, router]);\n\n const errorMessage =\n state.error === 'invalid_credentials'\n ? invalidCredentialsMessage\n : state.error === 'missing_config'\n ? missingConfigMessage\n : null;\n\n return (\n <>\n <div className=\"flex min-h-full flex-col justify-center px-6 py-12 lg:px-8\">\n <div className=\"sm:mx-auto sm:w-full sm:max-w-[384px]\">\n <OlmoLogo className=\"mx-auto h-10 w-auto \" />\n {/* <h2 className=\"mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900\">\n Sign in to your account\n </h2> */}\n <header className=\"space-y-1\">\n <h1 className=\"text-xl text-center font-semibold text-neutral-900\">{title}</h1>\n <p className=\"text-sm text-center text-neutral-600\">{description}</p>\n </header> \n </div>\n\n <div className=\"mt-10 sm:mx-auto sm:w-full sm:max-w-[384px]\">\n <form action={formAction} method=\"POST\" className=\"space-y-6\">\n <input type=\"hidden\" name=\"from\" value={from} />\n <div>\n <label htmlFor=\"username\" className=\"block text-sm/6 font-medium text-gray-900\">\n {usernameLabel}\n </label>\n <div className=\"mt-2\">\n <input\n id=\"username\"\n name=\"username\"\n type=\"username\"\n disabled={pending}\n required\n autoComplete=\"username\"\n className=\"block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-black sm:text-sm/6\"\n />\n </div>\n </div>\n\n <div>\n <div className=\"flex items-center justify-between\">\n <label htmlFor=\"password\" className=\"block text-sm/6 font-medium text-gray-900\">\n {passwordLabel}\n </label>\n </div>\n <div className=\"mt-2\">\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n disabled={pending}\n required\n autoComplete=\"current-password\"\n className=\"block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-black sm:text-sm/6\"\n />\n </div>\n </div>\n\n <div>\n {errorMessage ? (\n <p role=\"alert\" className=\"text-sm text-red-600\">\n {errorMessage}\n </p>\n ) : null} \n <button\n type=\"submit\"\n disabled={pending}\n className=\"cursor-pointer flex w-full justify-center rounded-md bg-black px-3 py-1.5 text-sm/6 font-semibold text-white shadow-xs hover:bg-black focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-black\"\n >\n {pending ? '…' : submitLabel}\n </button>\n </div>\n </form>\n\n </div>\n </div>\n </>\n )\n}\n"],"mappings":"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","names":["jsx","useEffect","jsx","useEffect","Fragment","jsx","useEffect","jsx","Fragment"]}
@@ -22,7 +22,8 @@ var middleware_exports = {};
22
22
  __export(middleware_exports, {
23
23
  chain: () => chain,
24
24
  headermiddleware: () => headermiddleware,
25
- redirectmiddleware: () => redirectmiddleware
25
+ redirectmiddleware: () => redirectmiddleware,
26
+ stagegatemiddleware: () => stagegatemiddleware
26
27
  });
27
28
  module.exports = __toCommonJS(middleware_exports);
28
29
 
@@ -85,10 +86,113 @@ var redirectmiddleware = (next) => {
85
86
  return next(request, _next);
86
87
  };
87
88
  };
89
+
90
+ // src/middleware/stagegatemiddleware.ts
91
+ var import_server4 = require("next/server");
92
+
93
+ // src/auth/stage.ts
94
+ var COOKIE_NAME = "olmo_stage_auth";
95
+ var DEFAULT_SESSION_DAYS = 7;
96
+ function readStageEnv() {
97
+ const username = process.env.OLMO_STAGE_USERNAME;
98
+ const password = process.env.OLMO_STAGE_PASSWORD;
99
+ const secret = process.env.OLMO_STAGE_SECRET;
100
+ if (!username || !password || !secret) return null;
101
+ const days = Number(process.env.OLMO_STAGE_SESSION_DAYS);
102
+ return {
103
+ username,
104
+ password,
105
+ secret,
106
+ sessionDays: Number.isFinite(days) && days > 0 ? days : DEFAULT_SESSION_DAYS
107
+ };
108
+ }
109
+ function getStageCookieName() {
110
+ return COOKIE_NAME;
111
+ }
112
+ function fromBase64Url(input) {
113
+ const pad = input.length % 4 === 0 ? "" : "=".repeat(4 - input.length % 4);
114
+ const b64 = input.replace(/-/g, "+").replace(/_/g, "/") + pad;
115
+ const bin = atob(b64);
116
+ const out = new Uint8Array(bin.length);
117
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
118
+ return out;
119
+ }
120
+ async function importKey(secret) {
121
+ return crypto.subtle.importKey(
122
+ "raw",
123
+ new TextEncoder().encode(secret),
124
+ { name: "HMAC", hash: "SHA-256" },
125
+ false,
126
+ ["sign", "verify"]
127
+ );
128
+ }
129
+ async function verifySession(token, secret) {
130
+ if (!token || typeof token !== "string" || token.indexOf(".") === -1) return null;
131
+ const [body, sig] = token.split(".");
132
+ if (!body || !sig) return null;
133
+ let key;
134
+ try {
135
+ key = await importKey(secret);
136
+ } catch {
137
+ return null;
138
+ }
139
+ let valid = false;
140
+ try {
141
+ valid = await crypto.subtle.verify("HMAC", key, fromBase64Url(sig), new TextEncoder().encode(body));
142
+ } catch {
143
+ return null;
144
+ }
145
+ if (!valid) return null;
146
+ let payload;
147
+ try {
148
+ payload = JSON.parse(new TextDecoder().decode(fromBase64Url(body)));
149
+ } catch {
150
+ return null;
151
+ }
152
+ if (!payload || typeof payload.exp !== "number" || payload.exp < Date.now()) return null;
153
+ return payload;
154
+ }
155
+
156
+ // src/middleware/stagegatemiddleware.ts
157
+ var LOGIN_PATH = "/olmo-stage-login/";
158
+ var NOINDEX = "noindex, nofollow, noarchive";
159
+ function withNoindex(res) {
160
+ res.headers.set("X-Robots-Tag", NOINDEX);
161
+ return res;
162
+ }
163
+ var stagegatemiddleware = (next) => {
164
+ return async (request, _next) => {
165
+ if (process.env.NEXT_PUBLIC_ENV !== "stage") {
166
+ return next(request, _next);
167
+ }
168
+ const { pathname, search } = request.nextUrl;
169
+ if (pathname === LOGIN_PATH) {
170
+ return withNoindex(import_server4.NextResponse.next());
171
+ }
172
+ const env = readStageEnv();
173
+ if (!env) {
174
+ const url2 = request.nextUrl.clone();
175
+ url2.pathname = LOGIN_PATH;
176
+ url2.search = "";
177
+ return withNoindex(import_server4.NextResponse.redirect(url2, { status: 307 }));
178
+ }
179
+ const token = request.cookies.get(getStageCookieName())?.value;
180
+ const session = await verifySession(token, env.secret);
181
+ if (session) {
182
+ const res = await next(request, _next);
183
+ return withNoindex(res instanceof import_server4.NextResponse ? res : import_server4.NextResponse.next());
184
+ }
185
+ const url = request.nextUrl.clone();
186
+ url.pathname = LOGIN_PATH;
187
+ url.search = `?from=${encodeURIComponent(pathname + search)}`;
188
+ return withNoindex(import_server4.NextResponse.redirect(url, { status: 307 }));
189
+ };
190
+ };
88
191
  // Annotate the CommonJS export names for ESM import in node:
89
192
  0 && (module.exports = {
90
193
  chain,
91
194
  headermiddleware,
92
- redirectmiddleware
195
+ redirectmiddleware,
196
+ stagegatemiddleware
93
197
  });
94
198
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/middleware/index.ts","../../src/middleware/chain.ts","../../src/middleware/headermiddleware.ts","../../src/middleware/redirectmiddleware.ts"],"sourcesContent":["export { chain } from './chain.js';\nexport type { MiddlewareFactory } from './chain.js';\nexport { headermiddleware } from './headermiddleware.js';\nexport { redirectmiddleware } from './redirectmiddleware.js';\n","import { NextResponse } from 'next/server';\nimport type { NextMiddleware } from 'next/server';\n\nexport type MiddlewareFactory = (middleware: NextMiddleware) => NextMiddleware;\n\nexport function chain(functions: MiddlewareFactory[] = [], index = 0): NextMiddleware {\n const current = functions[index];\n if (current) {\n const next = chain(functions, index + 1);\n return current(next);\n }\n return () => NextResponse.next();\n}\n","import { NextRequest } from 'next/server';\nimport type { NextFetchEvent } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\nexport const headermiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n const url = new URL(request.url);\n const params = new URLSearchParams(url.search);\n\n const headers = new Headers(request.headers);\n headers.set('x-current-path', request.nextUrl.pathname);\n headers.set('x-server', 'true');\n headers.set('olmo-preview', params.has('olmopreview').toString());\n\n return next(new NextRequest(request.url, { headers }), _next);\n };\n};\n","import { NextResponse } from 'next/server';\nimport type { NextFetchEvent, NextRequest } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\ntype NextFetchRequestInit = RequestInit & { next?: { tags?: string[]; revalidate?: number | false } };\n\nexport const redirectmiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n if (request.headers.has('rsc')) {\n return next(request, _next);\n }\n\n if (!process.env.NEXT_PUBLIC_OLMO_TOKEN || !process.env.NEXT_PUBLIC_API_URL || !process.env.NEXT_PUBLIC_BASE_URL) {\n return next(request, _next);\n }\n\n const pathNameWithTrailingSlash = request.nextUrl.pathname;\n\n const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/all/redirect`, {\n method: 'GET',\n cache: 'force-cache',\n next: { tags: ['olmo', 'redirect'] },\n headers: { 'front-token': process.env.NEXT_PUBLIC_OLMO_TOKEN },\n } as NextFetchRequestInit);\n\n const data = await response.json();\n\n const redirects = data.map((e: any) => ({\n source: e.source,\n destination: e.destination,\n permanent: e.permanent === 'true',\n }));\n\n if (redirects.length > 0) {\n const redirect = redirects.find((item: any) => item.source === pathNameWithTrailingSlash);\n\n if (!redirect) {\n return next(request, _next);\n }\n\n const newUrl = new URL(redirect.destination, process.env.NEXT_PUBLIC_BASE_URL).toString();\n return NextResponse.redirect(newUrl, { status: redirect.permanent ? 308 : 307 });\n }\n\n return next(request, _next);\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA6B;AAKtB,SAAS,MAAM,YAAiC,CAAC,GAAG,QAAQ,GAAmB;AACpF,QAAM,UAAU,UAAU,KAAK;AAC/B,MAAI,SAAS;AACX,UAAM,OAAO,MAAM,WAAW,QAAQ,CAAC;AACvC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,SAAO,MAAM,2BAAa,KAAK;AACjC;;;ACZA,IAAAA,iBAA4B;AAIrB,IAAM,mBAAsC,CAAC,SAAS;AAC3D,SAAO,OAAO,SAAsB,UAA0B;AAC5D,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,UAAM,SAAS,IAAI,gBAAgB,IAAI,MAAM;AAE7C,UAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,YAAQ,IAAI,kBAAkB,QAAQ,QAAQ,QAAQ;AACtD,YAAQ,IAAI,YAAY,MAAM;AAC9B,YAAQ,IAAI,gBAAgB,OAAO,IAAI,aAAa,EAAE,SAAS,CAAC;AAEhE,WAAO,KAAK,IAAI,2BAAY,QAAQ,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK;AAAA,EAC9D;AACF;;;AChBA,IAAAC,iBAA6B;AAMtB,IAAM,qBAAwC,CAAC,SAAS;AAC7D,SAAO,OAAO,SAAsB,UAA0B;AAC5D,QAAI,QAAQ,QAAQ,IAAI,KAAK,GAAG;AAC9B,aAAO,KAAK,SAAS,KAAK;AAAA,IAC5B;AAEA,QAAI,CAAC,QAAQ,IAAI,0BAA0B,CAAC,QAAQ,IAAI,uBAAuB,CAAC,QAAQ,IAAI,sBAAsB;AAChH,aAAO,KAAK,SAAS,KAAK;AAAA,IAC5B;AAEA,UAAM,4BAA4B,QAAQ,QAAQ;AAElD,UAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,IAAI,mBAAmB,iBAAiB;AAAA,MAC9E,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM,EAAE,MAAM,CAAC,QAAQ,UAAU,EAAE;AAAA,MACnC,SAAS,EAAE,eAAe,QAAQ,IAAI,uBAAuB;AAAA,IAC/D,CAAyB;AAEzB,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,UAAM,YAAY,KAAK,IAAI,CAAC,OAAY;AAAA,MACtC,QAAQ,EAAE;AAAA,MACV,aAAa,EAAE;AAAA,MACf,WAAW,EAAE,cAAc;AAAA,IAC7B,EAAE;AAEF,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,WAAW,UAAU,KAAK,CAAC,SAAc,KAAK,WAAW,yBAAyB;AAExF,UAAI,CAAC,UAAU;AACb,eAAO,KAAK,SAAS,KAAK;AAAA,MAC5B;AAEA,YAAM,SAAS,IAAI,IAAI,SAAS,aAAa,QAAQ,IAAI,oBAAoB,EAAE,SAAS;AACxF,aAAO,4BAAa,SAAS,QAAQ,EAAE,QAAQ,SAAS,YAAY,MAAM,IAAI,CAAC;AAAA,IACjF;AAEA,WAAO,KAAK,SAAS,KAAK;AAAA,EAC5B;AACF;","names":["import_server","import_server"]}
1
+ {"version":3,"sources":["../../src/middleware/index.ts","../../src/middleware/chain.ts","../../src/middleware/headermiddleware.ts","../../src/middleware/redirectmiddleware.ts","../../src/middleware/stagegatemiddleware.ts","../../src/auth/stage.ts"],"sourcesContent":["export { chain } from './chain.js';\nexport type { MiddlewareFactory } from './chain.js';\nexport { headermiddleware } from './headermiddleware.js';\nexport { redirectmiddleware } from './redirectmiddleware.js';\nexport { stagegatemiddleware } from './stagegatemiddleware.js';\n","import { NextResponse } from 'next/server';\nimport type { NextMiddleware } from 'next/server';\n\nexport type MiddlewareFactory = (middleware: NextMiddleware) => NextMiddleware;\n\nexport function chain(functions: MiddlewareFactory[] = [], index = 0): NextMiddleware {\n const current = functions[index];\n if (current) {\n const next = chain(functions, index + 1);\n return current(next);\n }\n return () => NextResponse.next();\n}\n","import { NextRequest } from 'next/server';\nimport type { NextFetchEvent } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\nexport const headermiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n const url = new URL(request.url);\n const params = new URLSearchParams(url.search);\n\n const headers = new Headers(request.headers);\n headers.set('x-current-path', request.nextUrl.pathname);\n headers.set('x-server', 'true');\n headers.set('olmo-preview', params.has('olmopreview').toString());\n\n return next(new NextRequest(request.url, { headers }), _next);\n };\n};\n","import { NextResponse } from 'next/server';\nimport type { NextFetchEvent, NextRequest } from 'next/server';\nimport type { MiddlewareFactory } from './chain.js';\n\ntype NextFetchRequestInit = RequestInit & { next?: { tags?: string[]; revalidate?: number | false } };\n\nexport const redirectmiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n if (request.headers.has('rsc')) {\n return next(request, _next);\n }\n\n if (!process.env.NEXT_PUBLIC_OLMO_TOKEN || !process.env.NEXT_PUBLIC_API_URL || !process.env.NEXT_PUBLIC_BASE_URL) {\n return next(request, _next);\n }\n\n const pathNameWithTrailingSlash = request.nextUrl.pathname;\n\n const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/all/redirect`, {\n method: 'GET',\n cache: 'force-cache',\n next: { tags: ['olmo', 'redirect'] },\n headers: { 'front-token': process.env.NEXT_PUBLIC_OLMO_TOKEN },\n } as NextFetchRequestInit);\n\n const data = await response.json();\n\n const redirects = data.map((e: any) => ({\n source: e.source,\n destination: e.destination,\n permanent: e.permanent === 'true',\n }));\n\n if (redirects.length > 0) {\n const redirect = redirects.find((item: any) => item.source === pathNameWithTrailingSlash);\n\n if (!redirect) {\n return next(request, _next);\n }\n\n const newUrl = new URL(redirect.destination, process.env.NEXT_PUBLIC_BASE_URL).toString();\n return NextResponse.redirect(newUrl, { status: redirect.permanent ? 308 : 307 });\n }\n\n return next(request, _next);\n };\n};\n","import { NextResponse } from 'next/server';\nimport type { NextFetchEvent, NextRequest } from 'next/server';\nimport { getStageCookieName, readStageEnv, verifySession } from '../auth/stage.js';\nimport type { MiddlewareFactory } from './chain.js';\n\nconst LOGIN_PATH = '/olmo-stage-login/';\nconst NOINDEX = 'noindex, nofollow, noarchive';\n\nfunction withNoindex(res: NextResponse): NextResponse {\n res.headers.set('X-Robots-Tag', NOINDEX);\n return res;\n}\n\nexport const stagegatemiddleware: MiddlewareFactory = (next) => {\n return async (request: NextRequest, _next: NextFetchEvent) => {\n if (process.env.NEXT_PUBLIC_ENV !== 'stage') {\n return next(request, _next);\n }\n\n const { pathname, search } = request.nextUrl;\n\n if (pathname === LOGIN_PATH) {\n return withNoindex(NextResponse.next());\n }\n\n const env = readStageEnv();\n if (!env) {\n // Misconfigured stage — deny everything except the login page itself.\n const url = request.nextUrl.clone();\n url.pathname = LOGIN_PATH;\n url.search = '';\n return withNoindex(NextResponse.redirect(url, { status: 307 }));\n }\n\n const token = request.cookies.get(getStageCookieName())?.value;\n const session = await verifySession(token, env.secret);\n if (session) {\n const res = await next(request, _next);\n return withNoindex(res instanceof NextResponse ? res : NextResponse.next());\n }\n\n const url = request.nextUrl.clone();\n url.pathname = LOGIN_PATH;\n url.search = `?from=${encodeURIComponent(pathname + search)}`;\n return withNoindex(NextResponse.redirect(url, { status: 307 }));\n };\n};\n","// Internal helpers for the stage-environment auth gate.\n// Edge-runtime safe (uses Web Crypto, no Node APIs).\n\nconst COOKIE_NAME = 'olmo_stage_auth';\nconst DEFAULT_SESSION_DAYS = 7;\n\nexport type StagePayload = { u: string; exp: number };\n\nexport type StageEnv = {\n username: string;\n password: string;\n secret: string;\n sessionDays: number;\n};\n\nexport function readStageEnv(): StageEnv | null {\n const username = process.env.OLMO_STAGE_USERNAME;\n const password = process.env.OLMO_STAGE_PASSWORD;\n const secret = process.env.OLMO_STAGE_SECRET;\n if (!username || !password || !secret) return null;\n const days = Number(process.env.OLMO_STAGE_SESSION_DAYS);\n return {\n username,\n password,\n secret,\n sessionDays: Number.isFinite(days) && days > 0 ? days : DEFAULT_SESSION_DAYS,\n };\n}\n\nexport function getStageCookieName(): string {\n return COOKIE_NAME;\n}\n\nfunction toBase64Url(bytes: ArrayBuffer | Uint8Array): string {\n const arr = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n let str = '';\n for (let i = 0; i < arr.length; i++) str += String.fromCharCode(arr[i]);\n return btoa(str).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nfunction fromBase64Url(input: string): Uint8Array {\n const pad = input.length % 4 === 0 ? '' : '='.repeat(4 - (input.length % 4));\n const b64 = input.replace(/-/g, '+').replace(/_/g, '/') + pad;\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nasync function importKey(secret: string): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign', 'verify'],\n );\n}\n\nexport async function signSession(payload: StagePayload, secret: string): Promise<string> {\n const body = toBase64Url(new TextEncoder().encode(JSON.stringify(payload)));\n const key = await importKey(secret);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return `${body}.${toBase64Url(sig)}`;\n}\n\nexport async function verifySession(token: string | undefined, secret: string): Promise<StagePayload | null> {\n if (!token || typeof token !== 'string' || token.indexOf('.') === -1) return null;\n const [body, sig] = token.split('.');\n if (!body || !sig) return null;\n let key: CryptoKey;\n try {\n key = await importKey(secret);\n } catch {\n return null;\n }\n let valid = false;\n try {\n valid = await crypto.subtle.verify('HMAC', key, fromBase64Url(sig) as BufferSource, new TextEncoder().encode(body));\n } catch {\n return null;\n }\n if (!valid) return null;\n let payload: StagePayload;\n try {\n payload = JSON.parse(new TextDecoder().decode(fromBase64Url(body)));\n } catch {\n return null;\n }\n if (!payload || typeof payload.exp !== 'number' || payload.exp < Date.now()) return null;\n return payload;\n}\n\nexport function verifyCredentials(env: StageEnv, username: unknown, password: unknown): boolean {\n if (typeof username !== 'string' || typeof password !== 'string') return false;\n return username === env.username && password === env.password;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA6B;AAKtB,SAAS,MAAM,YAAiC,CAAC,GAAG,QAAQ,GAAmB;AACpF,QAAM,UAAU,UAAU,KAAK;AAC/B,MAAI,SAAS;AACX,UAAM,OAAO,MAAM,WAAW,QAAQ,CAAC;AACvC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,SAAO,MAAM,2BAAa,KAAK;AACjC;;;ACZA,IAAAA,iBAA4B;AAIrB,IAAM,mBAAsC,CAAC,SAAS;AAC3D,SAAO,OAAO,SAAsB,UAA0B;AAC5D,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,UAAM,SAAS,IAAI,gBAAgB,IAAI,MAAM;AAE7C,UAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,YAAQ,IAAI,kBAAkB,QAAQ,QAAQ,QAAQ;AACtD,YAAQ,IAAI,YAAY,MAAM;AAC9B,YAAQ,IAAI,gBAAgB,OAAO,IAAI,aAAa,EAAE,SAAS,CAAC;AAEhE,WAAO,KAAK,IAAI,2BAAY,QAAQ,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK;AAAA,EAC9D;AACF;;;AChBA,IAAAC,iBAA6B;AAMtB,IAAM,qBAAwC,CAAC,SAAS;AAC7D,SAAO,OAAO,SAAsB,UAA0B;AAC5D,QAAI,QAAQ,QAAQ,IAAI,KAAK,GAAG;AAC9B,aAAO,KAAK,SAAS,KAAK;AAAA,IAC5B;AAEA,QAAI,CAAC,QAAQ,IAAI,0BAA0B,CAAC,QAAQ,IAAI,uBAAuB,CAAC,QAAQ,IAAI,sBAAsB;AAChH,aAAO,KAAK,SAAS,KAAK;AAAA,IAC5B;AAEA,UAAM,4BAA4B,QAAQ,QAAQ;AAElD,UAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,IAAI,mBAAmB,iBAAiB;AAAA,MAC9E,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM,EAAE,MAAM,CAAC,QAAQ,UAAU,EAAE;AAAA,MACnC,SAAS,EAAE,eAAe,QAAQ,IAAI,uBAAuB;AAAA,IAC/D,CAAyB;AAEzB,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,UAAM,YAAY,KAAK,IAAI,CAAC,OAAY;AAAA,MACtC,QAAQ,EAAE;AAAA,MACV,aAAa,EAAE;AAAA,MACf,WAAW,EAAE,cAAc;AAAA,IAC7B,EAAE;AAEF,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,WAAW,UAAU,KAAK,CAAC,SAAc,KAAK,WAAW,yBAAyB;AAExF,UAAI,CAAC,UAAU;AACb,eAAO,KAAK,SAAS,KAAK;AAAA,MAC5B;AAEA,YAAM,SAAS,IAAI,IAAI,SAAS,aAAa,QAAQ,IAAI,oBAAoB,EAAE,SAAS;AACxF,aAAO,4BAAa,SAAS,QAAQ,EAAE,QAAQ,SAAS,YAAY,MAAM,IAAI,CAAC;AAAA,IACjF;AAEA,WAAO,KAAK,SAAS,KAAK;AAAA,EAC5B;AACF;;;AC9CA,IAAAC,iBAA6B;;;ACG7B,IAAM,cAAc;AACpB,IAAM,uBAAuB;AAWtB,SAAS,eAAgC;AAC9C,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAQ,QAAO;AAC9C,QAAM,OAAO,OAAO,QAAQ,IAAI,uBAAuB;AACvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI,OAAO;AAAA,EAC1D;AACF;AAEO,SAAS,qBAA6B;AAC3C,SAAO;AACT;AASA,SAAS,cAAc,OAA2B;AAChD,QAAM,MAAM,MAAM,SAAS,MAAM,IAAI,KAAK,IAAI,OAAO,IAAK,MAAM,SAAS,CAAE;AAC3E,QAAM,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,IAAI;AAC1D,QAAM,MAAM,KAAK,GAAG;AACpB,QAAM,MAAM,IAAI,WAAW,IAAI,MAAM;AACrC,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,KAAI,CAAC,IAAI,IAAI,WAAW,CAAC;AAC9D,SAAO;AACT;AAEA,eAAe,UAAU,QAAoC;AAC3D,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,IAAI,YAAY,EAAE,OAAO,MAAM;AAAA,IAC/B,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,IAChC;AAAA,IACA,CAAC,QAAQ,QAAQ;AAAA,EACnB;AACF;AASA,eAAsB,cAAc,OAA2B,QAA8C;AAC3G,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,GAAG,MAAM,GAAI,QAAO;AAC7E,QAAM,CAAC,MAAM,GAAG,IAAI,MAAM,MAAM,GAAG;AACnC,MAAI,CAAC,QAAQ,CAAC,IAAK,QAAO;AAC1B,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,UAAU,MAAM;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,QAAQ;AACZ,MAAI;AACF,YAAQ,MAAM,OAAO,OAAO,OAAO,QAAQ,KAAK,cAAc,GAAG,GAAmB,IAAI,YAAY,EAAE,OAAO,IAAI,CAAC;AAAA,EACpH,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACJ,MAAI;AACF,cAAU,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,cAAc,IAAI,CAAC,CAAC;AAAA,EACpE,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,CAAC,WAAW,OAAO,QAAQ,QAAQ,YAAY,QAAQ,MAAM,KAAK,IAAI,EAAG,QAAO;AACpF,SAAO;AACT;;;ADtFA,IAAM,aAAa;AACnB,IAAM,UAAU;AAEhB,SAAS,YAAY,KAAiC;AACpD,MAAI,QAAQ,IAAI,gBAAgB,OAAO;AACvC,SAAO;AACT;AAEO,IAAM,sBAAyC,CAAC,SAAS;AAC9D,SAAO,OAAO,SAAsB,UAA0B;AAC5D,QAAI,QAAQ,IAAI,oBAAoB,SAAS;AAC3C,aAAO,KAAK,SAAS,KAAK;AAAA,IAC5B;AAEA,UAAM,EAAE,UAAU,OAAO,IAAI,QAAQ;AAErC,QAAI,aAAa,YAAY;AAC3B,aAAO,YAAY,4BAAa,KAAK,CAAC;AAAA,IACxC;AAEA,UAAM,MAAM,aAAa;AACzB,QAAI,CAAC,KAAK;AAER,YAAMC,OAAM,QAAQ,QAAQ,MAAM;AAClC,MAAAA,KAAI,WAAW;AACf,MAAAA,KAAI,SAAS;AACb,aAAO,YAAY,4BAAa,SAASA,MAAK,EAAE,QAAQ,IAAI,CAAC,CAAC;AAAA,IAChE;AAEA,UAAM,QAAQ,QAAQ,QAAQ,IAAI,mBAAmB,CAAC,GAAG;AACzD,UAAM,UAAU,MAAM,cAAc,OAAO,IAAI,MAAM;AACrD,QAAI,SAAS;AACX,YAAM,MAAM,MAAM,KAAK,SAAS,KAAK;AACrC,aAAO,YAAY,eAAe,8BAAe,MAAM,4BAAa,KAAK,CAAC;AAAA,IAC5E;AAEA,UAAM,MAAM,QAAQ,QAAQ,MAAM;AAClC,QAAI,WAAW;AACf,QAAI,SAAS,SAAS,mBAAmB,WAAW,MAAM,CAAC;AAC3D,WAAO,YAAY,4BAAa,SAAS,KAAK,EAAE,QAAQ,IAAI,CAAC,CAAC;AAAA,EAChE;AACF;","names":["import_server","import_server","import_server","url"]}
@@ -7,4 +7,6 @@ declare const headermiddleware: MiddlewareFactory;
7
7
 
8
8
  declare const redirectmiddleware: MiddlewareFactory;
9
9
 
10
- export { type MiddlewareFactory, chain, headermiddleware, redirectmiddleware };
10
+ declare const stagegatemiddleware: MiddlewareFactory;
11
+
12
+ export { type MiddlewareFactory, chain, headermiddleware, redirectmiddleware, stagegatemiddleware };
@@ -7,4 +7,6 @@ declare const headermiddleware: MiddlewareFactory;
7
7
 
8
8
  declare const redirectmiddleware: MiddlewareFactory;
9
9
 
10
- export { type MiddlewareFactory, chain, headermiddleware, redirectmiddleware };
10
+ declare const stagegatemiddleware: MiddlewareFactory;
11
+
12
+ export { type MiddlewareFactory, chain, headermiddleware, redirectmiddleware, stagegatemiddleware };
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  chain,
3
3
  headermiddleware,
4
- redirectmiddleware
5
- } from "../chunk-GQITFXCV.js";
4
+ redirectmiddleware,
5
+ stagegatemiddleware
6
+ } from "../chunk-UCR7WW3X.js";
6
7
  export {
7
8
  chain,
8
9
  headermiddleware,
9
- redirectmiddleware
10
+ redirectmiddleware,
11
+ stagegatemiddleware
10
12
  };
11
13
  //# sourceMappingURL=index.js.map