ronantakizawa/codereview-bench huggingface dataset:
Repository: withastro/astro
File: packages/astro/src/core/config/schemas/base.ts (TypeScript)

Code before:
				.boolean()
				.optional()
				.default(ASTRO_CONFIG_DEFAULTS.experimental.preserveScriptOrder),
			fonts: z.array(z.union([localFontFamilySchema, remoteFontFamilySchema])).optional(),
			csp: z
				.union([
					z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.csp),
					z.object({
						algorithm: cspAlgorithmSchema,
					}),
				])
				.optional()
				.default(ASTRO_CONFIG_DEFAULTS.experimental.csp),
		})
		.strict(
			`Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/experimental-flags/ for a list of all current experiments.`,
		)
		.default({}),
	legacy: z
		.object({
			collections: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.legacy.collections),
		})
		.default({}),
});

export type CspAlgorithm = z.infer<typeof cspAlgorithmSchema>;

export type AstroConfigType = z.infer<typeof AstroConfigSchema>;


Review comment (suggestion):
We usually don't export this kind of type from here. I think both `cspAlgorithmSchema` and `CspAlgorithm` should live in eg. `csp/config.ts`

Code after:
				.optional()
				.default(ASTRO_CONFIG_DEFAULTS.experimental.preserveScriptOrder),
			fonts: z.array(z.union([localFontFamilySchema, remoteFontFamilySchema])).optional(),
			csp: z
				.union([
					z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.csp),
					z.object({
						algorithm: cspAlgorithmSchema,
					}),
				])
				.optional()
				.default(ASTRO_CONFIG_DEFAULTS.experimental.csp),
		})
		.strict(
			`Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/experimental-flags/ for a list of all current experiments.`,
		)
		.default({}),
	legacy: z
		.object({
			collections: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.legacy.collections),
		})
		.default({}),
});

export type AstroConfigType = z.infer<typeof AstroConfigSchema>;
Repository: withastro/astro
File: packages/astro/src/core/encryption.ts (TypeScript)

Code before:

/**
 * Takes a base64 encoded string, decodes it and returns the decrypted text.
 */
export async function decryptString(key: CryptoKey, encoded: string) {
	const iv = decodeHex(encoded.slice(0, IV_LENGTH));
	const dataArray = decodeBase64(encoded.slice(IV_LENGTH));
	const decryptedBuffer = await crypto.subtle.decrypt(
		{
			name: ALGORITHM,
			iv,
		},
		key,
		dataArray,
	);
	const decryptedString = decoder.decode(decryptedBuffer);
	return decryptedString;
}

/**
 * Generates an SHA-256 digest of the given string.
 * @param {string} data The string to hash.
 * @param {'sha256' | 'sha512' | 'sha384'} algorithm The algorithm to use.
 */
export async function generateCspDigest(data: string, algorithm: CspAlgorithm): Promise<string> {
	let hashBuffer = await crypto.subtle.digest(algorithm, encoder.encode(data));

	const hash = encodeBase64(new Uint8Array(hashBuffer));

	switch (algorithm) {
		case 'SHA-256': {
			return `sha256-${hash}`;
		}
		case 'SHA-512': {
			return `sha512-${hash}`;
		}
		case 'SHA-384': {
			return `sha384-${hash}`;
		}
	}
}


Review comment (suggestion):
```suggestion
	const hashBuffer = await crypto.subtle.digest(algorithm, encoder.encode(data));
```

Code after:

/**
 * Takes a base64 encoded string, decodes it and returns the decrypted text.
 */
export async function decryptString(key: CryptoKey, encoded: string) {
	const iv = decodeHex(encoded.slice(0, IV_LENGTH));
	const dataArray = decodeBase64(encoded.slice(IV_LENGTH));
	const decryptedBuffer = await crypto.subtle.decrypt(
		{
			name: ALGORITHM,
			iv,
		},
		key,
		dataArray,
	);
	const decryptedString = decoder.decode(decryptedBuffer);
	return decryptedString;
}

/**
 * Generates an SHA-256 digest of the given string.
 * @param {string} data The string to hash.
 * @param {CspAlgorithm} algorithm The algorithm to use.
 */
export async function generateCspDigest(data: string, algorithm: CspAlgorithm): Promise<string> {
	const hashBuffer = await crypto.subtle.digest(algorithm, encoder.encode(data));

	const hash = encodeBase64(new Uint8Array(hashBuffer));

	switch (algorithm) {
		case 'SHA-256': {
			return `sha256-${hash}`;
		}
		case 'SHA-512': {
			return `sha512-${hash}`;
		}
		case 'SHA-384': {
			return `sha384-${hash}`;
		}
	}
}
Repository: withastro/astro
File: packages/astro/src/core/encryption.ts (TypeScript)

Code before:
	// iv is 12, hex brings it to 24
	return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer));
}

/**
 * Takes a base64 encoded string, decodes it and returns the decrypted text.
 */
export async function decryptString(key: CryptoKey, encoded: string) {
	const iv = decodeHex(encoded.slice(0, IV_LENGTH));
	const dataArray = decodeBase64(encoded.slice(IV_LENGTH));
	const decryptedBuffer = await crypto.subtle.decrypt(
		{
			name: ALGORITHM,
			iv,
		},
		key,
		dataArray,
	);
	const decryptedString = decoder.decode(decryptedBuffer);
	return decryptedString;
}

/**
 * Generates an SHA-256 digest of the given string.
 * @param {string} data The string to hash.
 * @param {'sha256' | 'sha512' | 'sha384'} algorithm The algorithm to use.
 */
export async function generateCspDigest(data: string, algorithm: CspAlgorithm): Promise<string> {
	let hashBuffer = await crypto.subtle.digest(algorithm, encoder.encode(data));

	const hash = encodeBase64(new Uint8Array(hashBuffer));

	switch (algorithm) {
		case 'SHA-256': {
			return `sha256-${hash}`;
		}
		case 'SHA-512': {
			return `sha512-${hash}`;
		}
		case 'SHA-384': {
			return `sha384-${hash}`;
		}
	}
}


Review comment (suggestion):
```suggestion
 * @param {CspAlgorithm} algorithm The algorithm to use.
```

Code after:
	// iv is 12, hex brings it to 24
	return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer));
}

/**
 * Takes a base64 encoded string, decodes it and returns the decrypted text.
 */
export async function decryptString(key: CryptoKey, encoded: string) {
	const iv = decodeHex(encoded.slice(0, IV_LENGTH));
	const dataArray = decodeBase64(encoded.slice(IV_LENGTH));
	const decryptedBuffer = await crypto.subtle.decrypt(
		{
			name: ALGORITHM,
			iv,
		},
		key,
		dataArray,
	);
	const decryptedString = decoder.decode(decryptedBuffer);
	return decryptedString;
}

/**
 * Generates an SHA-256 digest of the given string.
 * @param {string} data The string to hash.
 * @param {CspAlgorithm} algorithm The algorithm to use.
 */
export async function generateCspDigest(data: string, algorithm: CspAlgorithm): Promise<string> {
	const hashBuffer = await crypto.subtle.digest(algorithm, encoder.encode(data));

	const hash = encodeBase64(new Uint8Array(hashBuffer));

	switch (algorithm) {
		case 'SHA-256': {
			return `sha256-${hash}`;
		}
		case 'SHA-512': {
			return `sha512-${hash}`;
		}
		case 'SHA-384': {
			return `sha384-${hash}`;
		}
	}
}
Repository: withastro/astro
File: packages/astro/src/types/public/config.ts (TypeScript)

Code before:
					 * @name experimental.csp.algorithm
					 * @type {"SHA-256" | "SHA-384" | "SHA-512"}
					 * @default `'SHA-256'`
					 * @version 5.5.x
					 * @description
					 *
					 * The hashing algorithm to use for the CSP.
					 *
					 * The default value is `'SHA-256'`.
					 *
					 */
					algorithm?: CspAlgorithm;

					/**
					 * @name experimental.csp.styleHashes
					 * @type {string[]}
					 * @default `[]`
					 * @version 5.5.x
					 * @description
					 *
					 * A list of style hashes to include in all pages. These hashes are added to the `style-src` policy.
					 *
					 * The default value is `[]`.
					 *
					 */
					styleHashes?: string[];

					/**
					 * @name experimental.csp.scriptHashes
					 * @type {string[]}
					 * @default `[]`
					 * @version 5.5.x
					 * @description
					 *
					 * A list of script hashes to include in all pages. These hashes are added to the `script-src` policy.
					 *
					 * The default value is `[]`.
					 *
					 */
					scriptHashes?: string[];
			  };

		/**
		 * @name experimental.preserveScriptOrder
		 * @type {boolean}
		 * @default `false`
		 * @version 5.5
		 * @description
		 *
		 * When enabled, `<script>` and `<style>` tags are rendered in the same order as they are defined.
		 *

Review comment (suggestion):
If you want, that could be enforced at the type level, eg.
```ts
styleHashes?: `${'sha256' | '...'}-${string}`[];
```

Code after:
					 * @name experimental.csp.algorithm
					 * @type {"SHA-256" | "SHA-384" | "SHA-512"}
					 * @default `'SHA-256'`
					 * @version 5.5.x
					 * @description
					 *
					 * The hashing algorithm to use for the CSP.
					 *
					 * The default value is `'SHA-256'`.
					 *
					 */
					algorithm?: CspAlgorithm;

					/**
					 * @name experimental.csp.styleHashes
					 * @type {string[]}
					 * @default `[]`
					 * @version 5.5.x
					 * @description
					 *
					 * A list of style hashes to include in all pages. These hashes are added to the `style-src` policy.
					 *
					 * The default value is `[]`.
					 *
					 */
					styleHashes?: `${CspAlgorithmValue}${string}`[];

					/**
					 * @name experimental.csp.scriptHashes
					 * @type {string[]}
					 * @default `[]`
					 * @version 5.5.x
					 * @description
					 *
					 * A list of script hashes to include in all pages. These hashes are added to the `script-src` policy.
					 *
					 * The default value is `[]`.
					 *
					 */
					scriptHashes?: `${CspAlgorithmValue}${string}`[];
			  };

		/**
		 * @name experimental.preserveScriptOrder
		 * @type {boolean}
		 * @default `false`
		 * @version 5.5
		 * @description
		 *
		 * When enabled, `<script>` and `<style>` tags are rendered in the same order as they are defined.
		 *
Repository: withastro/astro
File: packages/astro/src/core/csp/common.ts (TypeScript)

Code before:
		return 'SHA-256';
	}
	return config.experimental.csp.algorithm;
}

/**
 * Use this function when after you checked that CSP is enabled, or it throws an error.
 * @param config
 */
export function getScriptHashes(config: AstroConfig): string[] {
	if (!config.experimental?.csp) {
		throw new Error('CSP is not enabled');
	}
	if (config.experimental?.csp === true) {
		return [];
	} else {
		return config.experimental.csp.scriptHashes ?? [];
	}
}

/**
 * Use this function when after you checked that CSP is enabled, or it throws an error.
 * @param config
 */
export function getStyleHashes(config: AstroConfig): string[] {
	if (!config.experimental?.csp) {
		throw new Error('CSP is not enabled');
	}
	if (config.experimental?.csp === true) {
		return [];
	} else {
		return config.experimental.csp.styleHashes ?? [];
	}
}

export async function trackStyleHashes(
	internals: BuildInternals,
	settings: AstroSettings,
	algorithm: CspAlgorithm,
): Promise<string[]> {
	const clientStyleHashes: string[] = [];
	for (const [_, page] of internals.pagesByViteID.entries()) {
		for (const style of page.styles) {
			if (style.sheet.type === 'inline') {
				clientStyleHashes.push(await generateCspDigest(style.sheet.content, algorithm));
			}
		}
	}

	for (const clientAsset in internals.clientChunksAndAssets) {
		const contents = readFileSync(

Review comment (suggestion):
This pattern is not really convenient. For a future PR, might be worth investigating making `shouldTrackCsp()` a type guard using `is`

Code after:
		return [];
	} else {
		return csp.scriptHashes ?? [];
	}
}

export function getStyleHashes(csp: EnabledCsp): string[] {
	if (csp === true) {
		return [];
	} else {
		return csp.styleHashes ?? [];
	}
}

export async function trackStyleHashes(
	internals: BuildInternals,
	settings: AstroSettings,
	algorithm: CspAlgorithm,
): Promise<string[]> {
	const clientStyleHashes: string[] = [];
	for (const [_, page] of internals.pagesByViteID.entries()) {
		for (const style of page.styles) {
			if (style.sheet.type === 'inline') {
				clientStyleHashes.push(await generateCspDigest(style.sheet.content, algorithm));
			}
		}
	}

	for (const clientAsset in internals.clientChunksAndAssets) {
		const contents = readFileSync(
			fileURLToPath(new URL(clientAsset, settings.config.build.client)),
			'utf-8',
		);
		if (clientAsset.endsWith('.css') || clientAsset.endsWith('.css')) {
			clientStyleHashes.push(await generateCspDigest(contents, algorithm));
		}
	}

	if (settings.renderers.length > 0) {
		clientStyleHashes.push(await generateCspDigest(ISLAND_STYLES, algorithm));
	}

	return clientStyleHashes;
}

export async function trackScriptHashes(
	internals: BuildInternals,
	settings: AstroSettings,
	algorithm: CspAlgorithm,
): Promise<string[]> {
	const clientScriptHashes: string[] = [];
Repository: withastro/astro
File: packages/astro/src/core/render-context.ts (TypeScript)

Code before:
			get currentLocale() {
				return renderContext.computeCurrentLocale();
			},
			params,
			get preferredLocale() {
				return renderContext.computePreferredLocale();
			},
			get preferredLocaleList() {
				return renderContext.computePreferredLocaleList();
			},
			locals,
			redirect,
			rewrite,
			request: this.request,
			response,
			site: pipeline.site,
			getActionResult: createGetActionResult(locals),
			get callAction() {
				return callAction;
			},
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {

Review comment (suggestion):
```suggestion
				if (!pipeline.manifest.csp) {
```

Code after:
			get currentLocale() {
				return renderContext.computeCurrentLocale();
			},
			params,
			get preferredLocale() {
				return renderContext.computePreferredLocale();
			},
			get preferredLocaleList() {
				return renderContext.computePreferredLocaleList();
			},
			locals,
			redirect,
			rewrite,
			request: this.request,
			response,
			site: pipeline.site,
			getActionResult: createGetActionResult(locals),
			get callAction() {
				return callAction;
			},
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {
Repository: withastro/astro
File: packages/astro/src/core/render-context.ts (TypeScript)

Code before:
			get preferredLocaleList() {
				return renderContext.computePreferredLocaleList();
			},
			locals,
			redirect,
			rewrite,
			request: this.request,
			response,
			site: pipeline.site,
			getActionResult: createGetActionResult(locals),
			get callAction() {
				return callAction;
			},
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptHashes.push(hash);
			},
		};
	}

Review comment (suggestion):
```suggestion
				if (!pipeline.manifest.csp) {
```

Code after:
			get preferredLocaleList() {
				return renderContext.computePreferredLocaleList();
			},
			locals,
			redirect,
			rewrite,
			request: this.request,
			response,
			site: pipeline.site,
			getActionResult: createGetActionResult(locals),
			get callAction() {
				return callAction;
			},
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptHashes.push(hash);
			},
		};
	}
Repository: withastro/astro
File: packages/astro/src/core/render-context.ts (TypeScript)

Code before:
			request: this.request,
			response,
			site: pipeline.site,
			getActionResult: createGetActionResult(locals),
			get callAction() {
				return callAction;
			},
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptHashes.push(hash);
			},
		};
	}

	getClientAddress() {
		const { pipeline, request, routeData, clientAddress } = this;

		if (routeData.prerender) {
			throw new AstroError({

Review comment (suggestion):
```suggestion
				if (!pipeline.manifest.csp) {
```

Code after:
			request: this.request,
			response,
			site: pipeline.site,
			getActionResult: createGetActionResult(locals),
			get callAction() {
				return callAction;
			},
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptHashes.push(hash);
			},
		};
	}

	getClientAddress() {
		const { pipeline, request, routeData, clientAddress } = this;

		if (routeData.prerender) {
			throw new AstroError({
Repository: withastro/astro
File: packages/astro/src/core/render-context.ts (TypeScript)

Code before:
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptHashes.push(hash);
			},
		};
	}

	getClientAddress() {
		const { pipeline, request, routeData, clientAddress } = this;

		if (routeData.prerender) {
			throw new AstroError({
				...AstroErrorData.PrerenderClientAddressNotAvailable,
				message: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component),
			});
		}

		if (clientAddress) {
			return clientAddress;

Review comment (suggestion):
```suggestion
				if (!pipeline.manifest.csp) {
```

Code after:
			url,
			get originPathname() {
				return getOriginPathname(renderContext.request);
			},
			insertDirective(payload) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.directives.push(payload);
			},

			insertScriptResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptResources.push(resource);
			},
			insertStyleResource(resource) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}

				renderContext.result?.styleResources.push(resource);
			},
			insertStyleHash(hash) {
				if (!pipeline.manifest.csp) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.styleHashes.push(hash);
			},
			insertScriptHash(hash) {
				if (!!pipeline.manifest.csp === false) {
					throw new AstroError(CspNotEnabled);
				}
				renderContext.result?.scriptHashes.push(hash);
			},
		};
	}

	getClientAddress() {
		const { pipeline, request, routeData, clientAddress } = this;

		if (routeData.prerender) {
			throw new AstroError({
				...AstroErrorData.PrerenderClientAddressNotAvailable,
				message: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component),
			});
		}

		if (clientAddress) {
			return clientAddress;