infra/cdk/lib/config/edge-runtime.ts

import fs from 'node:fs'; import path from 'node:path'; import { Fn } from 'aws-cdk-lib';

export const EDGE_RUNTIME_HEADER_NAME = 'x-opn-runtime-config'; export const EDGE_ENV_SECRET_HEADER_NAME = 'x-opn-env-secret-id'; export const EDGE_REPO_SECRET_HEADER_NAME = 'x-opn-repo-secret-id'; export const EDGE_SECRETS_REGION_HEADER_NAME = 'x-opn-secrets-region'; export const EDGE_SECRETS_FALLBACK_REGION_HEADER_NAME = 'x-opn-secrets-fallback-region';

type EdgeRuntimeHeaderOptions = { runtimeHeaderName: string; entriesPerHeader?: number; };

type EdgeBundlePatchOptions = { bundlePath: string; runtimeHeaders: Record<string, string>; runtimeHeaderName: string; envSecretHeaderName: string; repoSecretHeaderName: string; secretsRegionHeaderName: string; secretsFallbackRegionHeaderName: string; };

export function buildEdgeRuntimeHeaders( env: Record<string, string>, { runtimeHeaderName, entriesPerHeader = 8 }: EdgeRuntimeHeaderOptions ): Record<string, string> { const entries = Object.entries(env); if (!entries.length) { return {}; }

const headers: Record<string, string> = {}; const chunkSize = Math.max(1, entriesPerHeader);

for (let start = 0; start < entries.length; start += chunkSize) { const chunkEntries = entries.slice(start, start + chunkSize); const templateParts: string[] = ['{']; const substitutions: Record<string, string> = {};

chunkEntries.forEach(([key, value], index) => {
  const placeholder = `v${index}`;
  templateParts.push(`"${key}":"\${${placeholder}}"`);
  if (index < chunkEntries.length - 1) {
    templateParts.push(',');
  }
  substitutions[placeholder] = value;
});

templateParts.push('}');
const jsonTemplate = templateParts.join('');
const json = Fn.sub(jsonTemplate, substitutions);
const encoded = Fn.base64(json);

const chunkIndex = Math.floor(start / chunkSize);
const headerName =
  chunkIndex === 0 && entries.length <= chunkSize ? runtimeHeaderName : `${runtimeHeaderName}-${chunkIndex + 1}`;

headers[headerName] = encoded;

}

return headers; }

export function patchEdgeServerBundle({ bundlePath, runtimeHeaders, runtimeHeaderName, envSecretHeaderName, repoSecretHeaderName, secretsRegionHeaderName, secretsFallbackRegionHeaderName, }: EdgeBundlePatchOptions) { const indexPath = path.join(bundlePath, 'index.mjs'); const handlerPath = path.join(bundlePath, 'server-handler.mjs');

if (!fs.existsSync(handlerPath)) { if (!fs.existsSync(indexPath)) { throw new Error(Expected OpenNext server bundle at ${indexPath}); } fs.renameSync(indexPath, handlerPath); }

const runtimeHeaderNames = Object.keys(runtimeHeaders ?? {}); if (!runtimeHeaderNames.length) { throw new Error('Edge runtime configuration headers missing; ensure buildEdgeRuntimeHeaders ran first.'); } const runtimeHeaderLiteral = JSON.stringify(runtimeHeaderNames);

const wrapperSource = `import { Buffer } from 'node:buffer';

const RUNTIME_CONFIG_HEADERS = ${runtimeHeaderLiteral}; const RUNTIME_CONFIG_BASE_HEADER = '${runtimeHeaderName}'; const ENV_SECRET_HEADER = '${envSecretHeaderName}'; const REPO_SECRET_HEADER = '${repoSecretHeaderName}'; const SECRETS_REGION_HEADER = '${secretsRegionHeaderName}'; const SECRETS_FALLBACK_REGION_HEADER = '${secretsFallbackRegionHeaderName}'; let cachedHandlerPromise;

function readCustomHeader(origin, name) { const entries = origin?.customHeaders?.[name]; if (!entries || entries.length === 0) { return undefined; } return entries[0]?.value; }

function extractRuntimeConfig(event) { try { const record = event?.Records?.[0]; const request = record?.cf?.request; if (!request) { return undefined; } const origin = request.origin?.s3 ?? request.origin?.custom; const encodedChunks = []; for (const headerName of RUNTIME_CONFIG_HEADERS) { const value = readCustomHeader(origin, headerName); if (value) { encodedChunks.push(value); } } if (encodedChunks.length === 0) { const fallback = readCustomHeader(origin, RUNTIME_CONFIG_BASE_HEADER); if (fallback) { encodedChunks.push(fallback); } } if (encodedChunks.length === 0) { console.error('Lambda@Edge runtime config header missing'); return undefined; } const runtimeConfig = {}; for (const encoded of encodedChunks) { const json = Buffer.from(encoded, 'base64').toString('utf-8'); const parsed = JSON.parse(json); if (parsed && typeof parsed === 'object') { Object.assign(runtimeConfig, parsed); } }

const envSecretId = readCustomHeader(origin, ENV_SECRET_HEADER);
if (envSecretId) {
  runtimeConfig.SECRETS_MANAGER_ENV_SECRET_ID = envSecretId;
}

const repoSecretId = readCustomHeader(origin, REPO_SECRET_HEADER);
if (repoSecretId) {
  runtimeConfig.SECRETS_MANAGER_REPO_SECRET_ID = repoSecretId;
}

const primaryRegion = readCustomHeader(origin, SECRETS_REGION_HEADER);
if (primaryRegion) {
  runtimeConfig.AWS_SECRETS_MANAGER_PRIMARY_REGION = primaryRegion;
}

const fallbackRegion = readCustomHeader(origin, SECRETS_FALLBACK_REGION_HEADER);
if (fallbackRegion) {
  runtimeConfig.AWS_SECRETS_MANAGER_FALLBACK_REGION = fallbackRegion;
}

return runtimeConfig;

} catch (error) { console.error('Failed to parse Lambda@Edge runtime configuration', error); return undefined; } }

function applyRuntimeConfig(config) {
  if (!config) {
    return;
  }

  const configuredRegion = config.AWS_REGION;
  if (typeof configuredRegion === 'string' && configuredRegion.length > 0) {
    process.env.AWS_REGION = configuredRegion;
    process.env.AWS_DEFAULT_REGION = configuredRegion;
  }

  for (const [key, value] of Object.entries(config)) {
    if (typeof value !== 'string') continue;
    if (key === 'AWS_REGION' || key === 'AWS_DEFAULT_REGION') continue;
    if (process.env[key] === undefined) process.env[key] = value;
  }
}

async function loadHandler(event) { if (!cachedHandlerPromise) { const config = extractRuntimeConfig(event); if (!config) { throw new Error('Missing Lambda@Edge runtime configuration header'); } applyRuntimeConfig(config); cachedHandlerPromise = import('./server-handler.mjs').then((mod) => mod.handler); } return cachedHandlerPromise; }

export const handler = async (event, context, callback) => { if (!event?.Records?.[0]?.cf?.request) { if (event?.type === 'warmer') { return { type: 'warmer', serverId: 'edge' }; } }

const actualHandler = await loadHandler(event); return actualHandler(event, context, callback); }; `;

fs.writeFileSync(indexPath, wrapperSource, { encoding: 'utf-8' }); }

export function buildEdgeSecretHeaders(runtimeEnvironment: Record<string, string>): Record<string, string> { const headers: Record<string, string> = {};

const envSecretId = runtimeEnvironment['SECRETS_MANAGER_ENV_SECRET_ID']; if (envSecretId) { headers[EDGE_ENV_SECRET_HEADER_NAME] = envSecretId; }

const repoSecretId = runtimeEnvironment['SECRETS_MANAGER_REPO_SECRET_ID']; if (repoSecretId) { headers[EDGE_REPO_SECRET_HEADER_NAME] = repoSecretId; }

const primaryRegion = runtimeEnvironment['AWS_SECRETS_MANAGER_PRIMARY_REGION'] ?? runtimeEnvironment['AWS_REGION']; if (primaryRegion) { headers[EDGE_SECRETS_REGION_HEADER_NAME] = primaryRegion; }

const fallbackRegion = runtimeEnvironment['AWS_SECRETS_MANAGER_FALLBACK_REGION']; if (fallbackRegion && fallbackRegion !== primaryRegion) { headers[EDGE_SECRETS_FALLBACK_REGION_HEADER_NAME] = fallbackRegion; }

return headers; }