import { Session } from 'express-session';
declare const loginTemplate = "\n\n
\n \n \n {{siteName}}\n \n \n \n \n \n \n \n \n";
declare const setupTemplate = "\n\n \n \n \n {{pageTitle}}\n \n \n \n \n \n \n \n \n \n
\n\n
\n \n {{setupMethod1}}
\n \n {{setupMethod2}}\n
\n\n
\n {{footerText}}\n
\n
\n \n";
declare const stylesContent = ":root {\n --background: #ffffff;\n --foreground: #000000;\n --muted: #fafafa;\n --muted-foreground: #737373;\n --border: #e5e5e5;\n --input: #e5e5e5;\n --primary: #000000;\n --primary-foreground: #ffffff;\n --radius: 0.5rem;\n --code-bg: #171717;\n --code-fg: #ffffff;\n \n --error: #dc2626;\n --error-foreground: #fef2f2;\n --error-border: #fee2e2;\n --error-shadow: rgb(220 38 38 / 100%);\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #000000;\n --foreground: #ffffff;\n --muted: #171717;\n --muted-foreground: #a3a3a3;\n --border: #262626;\n --input: #262626;\n --primary: #ffffff;\n --primary-foreground: #000000;\n --code-bg: #171717;\n --code-fg: #ffffff;\n \n --error: #fca5a5;\n --error-foreground: #450a0a;\n --error-border: #7f1d1d;\n --error-shadow: rgb(252 165 165 / 100%);\n }\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n background: var(--background);\n color: var(--foreground);\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem;\n line-height: 1.5;\n}\n\n.container {\n width: 100%;\n max-width: 400px;\n padding: 2.5rem;\n background: var(--background);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n}\n\n.header {\n text-align: center;\n margin-bottom: 2rem;\n}\n\n.title {\n font-size: 1.5rem;\n font-weight: 600;\n margin-bottom: 0.5rem;\n}\n\n.description {\n color: var(--muted-foreground);\n font-size: 0.875rem;\n}\n\n.alert {\n padding: 1rem;\n border: 1px solid var(--border);\n border-radius: var(--radius);\n margin: 1.5rem 0;\n font-size: 0.875rem;\n}\n\n.alert p {\n margin-bottom: 0.5rem;\n}\n\n.alert p:last-child {\n margin-bottom: 0;\n}\n\n.code {\n background: var(--code-bg);\n color: var(--code-fg);\n padding: 1rem;\n border-radius: var(--radius);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 0.875rem;\n line-height: 1.5;\n overflow-x: auto;\n margin: 1rem 0;\n}\n\n.code-comment {\n color: var(--muted-foreground);\n margin-bottom: 0.5rem;\n}\n\n.code-line {\n display: block;\n min-height: 1rem;\n}\n\n.code-indent {\n display: inline-block;\n width: 1rem;\n}\n\n.text-center {\n text-align: center;\n font-size: 0.875rem;\n color: var(--muted-foreground);\n margin-top: 1.5rem;\n}\n\n/* Form specific styles */\nform {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.input-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.input-label {\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.input {\n padding: 0.75rem 1rem;\n background: var(--background);\n border: 1px solid var(--input);\n border-radius: var(--radius);\n font-size: 0.875rem;\n color: var(--foreground);\n transition: border-color 0.2s;\n}\n\n.input:focus {\n outline: none;\n border-color: var(--primary);\n box-shadow: 0 0 0 1px var(--primary);\n}\n\n.button {\n padding: 0.75rem 1rem;\n background: var(--primary);\n color: var(--primary-foreground);\n border: none;\n border-radius: var(--radius);\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: opacity 0.2s;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n}\n\n.button:hover {\n opacity: 0.9;\n}\n\n.button-arrow {\n display: inline-block;\n transition: transform 0.2s ease;\n margin-left: 2px;\n}\n\n.button:hover .button-arrow {\n transform: translateX(4px);\n}\n\n@media (max-width: 640px) {\n .container {\n padding: 1.5rem;\n }\n}\n\n.error-message {\n background: var(--error-foreground);\n border: 1px solid var(--error-border);\n color: var(--error);\n padding: 0.75rem 1rem;\n border-radius: var(--radius);\n margin-bottom: 1rem;\n font-size: 0.875rem;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.input-error {\n border-color: var(--error);\n}\n\n.input-error:focus {\n border-color: var(--error);\n box-shadow: 0 0 0 1px var(--error-shadow);\n}";
declare module "express-serve-static-core" {
interface Request {
session?: Session & {
returnTo?: string;
[key: string]: any;
};
}
}
declare module "express-session" {
interface SessionData {
returnTo?: string;
}
}
interface StagingOptions {
/** Whether the protection is enabled. Default: true. Can be set via STAGING_ENABLED env var */
enabled?: boolean;
/** The password required to access protected routes. Can be set via STAGING_PASSWORD env var */
password?: string;
/** Duration in milliseconds for how long the auth cookie remains valid. Default: 7 days. Can be set via STAGING_COOKIE_MAX_AGE env var (in days) */
cookieMaxAge?: number;
/** Secret used to sign the JWT token. Default: randomly generated. Can be set via STAGING_JWT_SECRET env var */
jwtSecret?: string | "unset";
/** Path for the login endpoint. Default: '/protected'. Can be set via STAGING_LOGIN_PATH env var */
loginPath?: string;
/** Name displayed on the login page. Default: 'Protected Page'. Can be set via STAGING_SITE_NAME env var */
siteName?: string;
/** Routes that should be protected. Default: all routes except loginPath. Can be set via STAGING_PROTECTED_ROUTES env var as comma-separated paths */
protectedRoutes?: string[];
/** Routes that should never be protected. Default: []. Can be set via STAGING_PUBLIC_ROUTES env var as comma-separated paths */
publicRoutes?: string[];
/** URL to redirect to after successful login. Default: the original requested URL. Can be set via STAGING_REDIRECT_URL env var */
redirectUrl?: string;
}
declare const DEFAULT_OPTIONS: {
readonly enabled: true;
readonly cookieMaxAge: number;
readonly loginPath: string;
readonly siteName: string;
readonly protectedRoutes: string[];
readonly publicRoutes: string[];
readonly redirectUrl: "/";
readonly jwtSecret: string;
};
declare const mergeOptions: (defaultOptions: Partial, envOptions: Partial, userOptions: Partial) => Required;
declare const getEnvValue: (key: string) => string | undefined;
declare const getEnvArray: (key: string) => string[];
declare const getEnvNumber: (key: string) => number | undefined;
declare const getEnvBoolean: (key: string) => boolean | undefined;
declare const mergeWithEnv: (defaults: typeof DEFAULT_OPTIONS) => StagingOptions;
interface SessionData {
returnTo?: string;
[key: string]: any;
}
interface StagingContext {
url: string;
method: string;
password?: string;
cookies: Record;
originalUrl?: string;
session?: SessionData;
}
interface CookieOptions {
maxAge?: number;
path?: string;
httpOnly?: boolean;
secure?: boolean;
sameSite?: "lax" | "strict" | "none";
}
interface StagingCallbacks {
sendHtml: (html: string, statusCode: number) => ResponseType;
sendCss: (css: string) => ResponseType;
redirect: (url: string) => ResponseType | Promise;
setCookie: (name: string, value: string, options: CookieOptions) => ResponseType;
clearCookie: (name: string) => ResponseType;
setSessionValue?: (key: string, value: string) => ResponseType;
clearSessionValue?: (key: string) => ResponseType;
next: () => ResponseType;
}
interface StagingProcessOptions {
context: StagingContext;
options: Required;
staticPrefix: string;
cssRoute: string;
callbacks: StagingCallbacks;
}
interface SetupTemplateVariables {
pageTitle: string;
title: string;
description: string;
alertText: string;
setupMethod1Label: string;
setupMethod1: string;
setupMethod2Label: string;
setupMethod2: string;
footerText: string;
cssPath: string;
}
declare function handleStagingProcess({ context, options, staticPrefix, cssRoute, callbacks, }: StagingProcessOptions): Promise;
declare const normalizePath: (path: string) => string;
declare const createRegexFromPattern: (pattern: string) => RegExp;
declare const isRouteMatch: (path: string, patterns: string[]) => boolean;
declare const isProtectedRoute: (path: string, options: Required) => boolean;
declare const normalizeRoute: (route: string) => string;
export { type CookieOptions, DEFAULT_OPTIONS, type SessionData, type SetupTemplateVariables, type StagingCallbacks, type StagingContext, type StagingOptions, type StagingProcessOptions, createRegexFromPattern, getEnvArray, getEnvBoolean, getEnvNumber, getEnvValue, handleStagingProcess, isProtectedRoute, isRouteMatch, loginTemplate, mergeOptions, mergeWithEnv, normalizePath, normalizeRoute, setupTemplate, stylesContent };