Repository: withastro/astro
File: packages/create-astro/src/messages.ts (TypeScript)

Code before:
			exec('whoami', { encoding: 'utf-8' }, (_3, whoami) => {
				if (whoami.trim()) {
					return resolve(whoami.split(' ')[0].trim());
				}
				return resolve('astronaut');
			});
		});
	});

export const getVersion = (
	packageManager: string,
	packageName: string,
	packageTag = 'latest',
	fallback = '',
) =>
	new Promise<string>(async (resolve) => {
		let registry = await getRegistry(packageManager);
		const { version } = await fetch(`${registry}/${packageName}/${packageTag}`, {
			redirect: 'follow',
			signal: AbortSignal.timeout(10_000),
		})
			.then((res) => res.json())
			.catch(() => {
				// biome-ignore lint/suspicious/noConsole: logging a warning
				console.warn(
					`Unable to fetch latest ${packageName} version from the npm registry. Using fallback version.`,
				);
				return { version: fallback };
			});
		return resolve(version);
	});

export const log = (message: string) => stdout.write(message + '\n');
export const banner = () => {
	const prefix = `astro`;
	const suffix = `Launch sequence initiated.`;
	log(`${label(prefix, color.bgGreen, color.black)}  ${suffix}`);
};

export const bannerAbort = () =>
	log(`\n${label('astro', color.bgRed)} ${color.bold('Launch sequence aborted.')}`);

export const info = async (prefix: string, text: string) => {
	await sleep(100);
	if (stdout.columns < 80) {
		log(`${' '.repeat(5)} ${color.cyan('◼')}  ${color.cyan(prefix)}`);
		log(`${' '.repeat(9)}${color.dim(text)}`);
	} else {
		log(`${' '.repeat(5)} ${color.cyan('◼')}  ${color.cyan(prefix)} ${color.dim(text)}`);
	}
};

Review comment (suggestion):
Instead of writing fallback version it'd write the version, bit similar to how context is good in errors
```suggestion
					`Unable to fetch latest ${packageName} version from the npm registry. Using ${fallback} instead.`,
```

(note though that fallback can be empty, not sure what that would do in the logic, though!)

Code after:
			exec('whoami', { encoding: 'utf-8' }, (_3, whoami) => {
				if (whoami.trim()) {
					return resolve(whoami.split(' ')[0].trim());
				}
				return resolve('astronaut');
			});
		});
	});

export const getVersion = (
	packageManager: string,
	packageName: string,
	packageTag = 'latest',
	fallback = '',
) =>
	new Promise<string>(async (resolve) => {
		let registry = await getRegistry(packageManager);
		const { version } = await fetch(`${registry}/${packageName}/${packageTag}`, {
			redirect: 'follow',
			signal: AbortSignal.timeout(10_000),
		})
			.then((res) => res.json())
			.catch(() => {
				const fallbackName = fallback || `'latest'`;
				console.warn(
					`Unable to fetch latest ${packageName} version from the npm registry. Using ${fallbackName} instead.`,
				);
				return { version: fallback };
			});
		return resolve(version);
	});

export const log = (message: string) => stdout.write(message + '\n');
export const banner = () => {
	const prefix = `astro`;
	const suffix = `Launch sequence initiated.`;
	log(`${label(prefix, color.bgGreen, color.black)}  ${suffix}`);
};

export const bannerAbort = () =>
	log(`\n${label('astro', color.bgRed)} ${color.bold('Launch sequence aborted.')}`);

export const info = async (prefix: string, text: string) => {
	await sleep(100);
	if (stdout.columns < 80) {
		log(`${' '.repeat(5)} ${color.cyan('◼')}  ${color.cyan(prefix)}`);
		log(`${' '.repeat(9)}${color.dim(text)}`);
	} else {
		log(`${' '.repeat(5)} ${color.cyan('◼')}  ${color.cyan(prefix)} ${color.dim(text)}`);
	}
};