Repository: withastro/astro
File: packages/astro/src/manifest/virtual-module.ts (TypeScript)

Code before:
import type { Plugin } from 'vite';
import { CantUseManifestModule, ForbiddenManifestModule } from '../core/errors/errors-data.js';
import { AstroError } from '../core/errors/index.js';
import type { Logger } from '../core/logger/core.js';
import type { AstroSettings } from '../types/astro.js';
import type {
	AstroConfig,
	ClientConfigSerialized,
	ServerConfigSerialized,
} from '../types/public/index.js';

const VIRTUAL_MODULES_IDS = {
	client: 'astro:manifest/client',
	server: 'astro:manifest/server',
};

const VIRTUAL_MODULES_IDS_SET = new Set(Object.values(VIRTUAL_MODULES_IDS));

function resolveVirtualModuleId<T extends string>(id: T): `\0${T}` {
	return `\0${id}`;
}

export default function virtualModulePlugin({
	settings,
	logger,
}: { settings: AstroSettings; logger: Logger }): Plugin {
	return {
		enforce: 'pre',
		name: 'astro-manifest-plugin',
		resolveId(id) {
			// Resolve the virtual module
			if (VIRTUAL_MODULES_IDS_SET.has(id)) {
				return resolveVirtualModuleId(id);
			}
		},
		load(id, opts) {
			// client
			if (id === resolveVirtualModuleId(VIRTUAL_MODULES_IDS.client)) {
				if (!settings.config.experimental.serializeManifest) {
					throw new AstroError({
						...CantUseManifestModule,
						message: CantUseManifestModule.message(VIRTUAL_MODULES_IDS.client),
					});
				}
				// There's nothing wrong about using `/client` on the server
				return `${serializeClientConfig(settings.config)};`;

Review comment (suggestion):
I think we could go with a simpler approach
```suggestion
const VIRTUAL_SERVER_ID = 'astro:manifest/server'
const RESOLVED_VIRTUAL_SERVER_ID = '\0' + VIRTUAL_SERVER_ID
const VIRTUAL_CLIENT_ID = 'astro:manifest/client'
const RESOLVED_VIRTUAL_CLIENT_ID = '\0' + VIRTUAL_CLIENT_ID
```

Code after:
import type { Plugin } from 'vite';
import { CantUseManifestModule } from '../core/errors/errors-data.js';
import { AstroError, AstroErrorData } from '../core/errors/index.js';
import type { Logger } from '../core/logger/core.js';
import type { AstroSettings } from '../types/astro.js';
import type {
	AstroConfig,
	ClientConfigSerialized,
	ServerConfigSerialized,
} from '../types/public/index.js';

const VIRTUAL_SERVER_ID = 'astro:manifest/server';
const RESOLVED_VIRTUAL_SERVER_ID = '\0' + VIRTUAL_SERVER_ID;
const VIRTUAL_CLIENT_ID = 'astro:manifest/client';
const RESOLVED_VIRTUAL_CLIENT_ID = '\0' + VIRTUAL_CLIENT_ID;

export default function virtualModulePlugin({
	settings,
	logger: _logger,
}: { settings: AstroSettings; logger: Logger }): Plugin {
	return {
		enforce: 'pre',
		name: 'astro-manifest-plugin',
		resolveId(id) {
			// Resolve the virtual module
			if (VIRTUAL_SERVER_ID === id) {
				return RESOLVED_VIRTUAL_SERVER_ID;
			} else if (VIRTUAL_CLIENT_ID === id) {
				return RESOLVED_VIRTUAL_CLIENT_ID;
			}
		},
		load(id, opts) {
			// client
			if (id === RESOLVED_VIRTUAL_CLIENT_ID) {
				if (!settings.config.experimental.serializeManifest) {
					throw new AstroError({
						...CantUseManifestModule,
						message: CantUseManifestModule.message(VIRTUAL_CLIENT_ID),
					});
				}
				// There's nothing wrong about using `/client` on the server
				return `${serializeClientConfig(settings.config)};`;
			}
			// server
			else if (id == RESOLVED_VIRTUAL_SERVER_ID) {
				if (!settings.config.experimental.serializeManifest) {