Repository: withastro/astro
File: packages/integrations/cloudflare/src/utils/handler.ts (TypeScript)

Code before:
import { env as globalEnv } from 'cloudflare:workers';
import { sessionKVBindingName } from 'virtual:astro-cloudflare:config';
import type {
	Response as CfResponse,
	ExecutionContext,
	ExportedHandlerFetchHandler,
} from '@cloudflare/workers-types';
import { createApp } from 'astro/app/entrypoint';
import { setGetEnv } from 'astro/env/setup';
import { createGetEnv } from '../utils/env.js';

export type Env = {
	[key: string]: unknown;
	ASSETS: { fetch: (req: Request | string) => Promise<CfResponse> };
};

setGetEnv(createGetEnv(globalEnv as Env));

export interface Runtime {
	cfContext: ExecutionContext;
	runtime: {
		get env(): never;
		get cf(): never;
		get caches(): never;
		get ctx(): never;
	};
}

declare global {
	// This is not a real global, but is injected using Vite define to allow us to specify the Images binding name in the config.
	var __ASTRO_IMAGES_BINDING_NAME: string;
}

export async function handle(
	request: Parameters<ExportedHandlerFetchHandler>[0],
	env: Env,
	context: ExecutionContext,
): Promise<CfResponse> {
	const app = createApp(import.meta.env.DEV);
	const { pathname } = new URL(request.url);

	if (env[sessionKVBindingName]) {
		const sessionConfigOptions = app.manifest.sessionConfig?.options ?? {};
		Object.assign(sessionConfigOptions, {
			binding: env[sessionKVBindingName],
		});
	}

	// static assets fallback, in case default _routes.json is not used
	if (app.manifest.assets.has(pathname)) {
		return env.ASSETS.fetch(request.url.replace(/\.html$/, ''));

Review comment (suggestion):
I'd remove `runtime` from the types entirely, so users don't get autocomplete

Code after:
import { env as globalEnv } from 'cloudflare:workers';
import { sessionKVBindingName } from 'virtual:astro-cloudflare:config';
import type {
	Response as CfResponse,
	ExecutionContext,
	ExportedHandlerFetchHandler,
} from '@cloudflare/workers-types';
import { createApp } from 'astro/app/entrypoint';
import { setGetEnv } from 'astro/env/setup';
import { createGetEnv } from '../utils/env.js';

export type Env = {
	[key: string]: unknown;
	ASSETS: { fetch: (req: Request | string) => Promise<CfResponse> };
};

setGetEnv(createGetEnv(globalEnv as Env));

export interface Runtime {
	cfContext: ExecutionContext;
}

declare global {
	// This is not a real global, but is injected using Vite define to allow us to specify the Images binding name in the config.
	var __ASTRO_IMAGES_BINDING_NAME: string;
}

export async function handle(
	request: Parameters<ExportedHandlerFetchHandler>[0],
	env: Env,
	context: ExecutionContext,
): Promise<CfResponse> {
	const app = createApp(import.meta.env.DEV);
	const { pathname } = new URL(request.url);

	if (env[sessionKVBindingName]) {
		const sessionConfigOptions = app.manifest.sessionConfig?.options ?? {};
		Object.assign(sessionConfigOptions, {
			binding: env[sessionKVBindingName],
		});
	}

	// static assets fallback, in case default _routes.json is not used
	if (app.manifest.assets.has(pathname)) {
		return env.ASSETS.fetch(request.url.replace(/\.html$/, ''));
	}

	const routeData = app.match(request as Request & Parameters<ExportedHandlerFetchHandler>[0]);
	if (!routeData) {
		// https://developers.cloudflare.com/pages/functions/api-reference/#envassetsfetch
		const asset = await env.ASSETS.fetch(