mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
♻️ refactor(utils): remove unused geo server utilities (#11243)
Clean up deprecated geo-related server code that is no longer used. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
@@ -1,116 +0,0 @@
|
||||
import { geolocation } from '@vercel/functions';
|
||||
import { getCountry } from 'countries-and-timezones';
|
||||
import { NextRequest } from 'next/server';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { parseDefaultThemeFromCountry } from '../geo';
|
||||
|
||||
vi.mock('@vercel/functions', () => ({
|
||||
geolocation: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('countries-and-timezones', () => ({
|
||||
getCountry: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('parseDefaultThemeFromCountry', () => {
|
||||
const mockRequest = (headers: Record<string, string> = {}) => {
|
||||
return {
|
||||
headers: {
|
||||
get: (key: string) => headers[key],
|
||||
},
|
||||
} as NextRequest;
|
||||
};
|
||||
|
||||
it('should return light theme when no country code is found', () => {
|
||||
vi.mocked(geolocation).mockReturnValue({});
|
||||
const request = mockRequest();
|
||||
expect(parseDefaultThemeFromCountry(request)).toBe('light');
|
||||
});
|
||||
|
||||
it('should return light theme when country has no timezone', () => {
|
||||
vi.mocked(geolocation).mockReturnValue({ country: 'US' });
|
||||
vi.mocked(getCountry).mockReturnValue({
|
||||
id: 'US',
|
||||
name: 'United States',
|
||||
timezones: [],
|
||||
});
|
||||
const request = mockRequest();
|
||||
expect(parseDefaultThemeFromCountry(request)).toBe('light');
|
||||
});
|
||||
|
||||
it('should return light theme when country has invalid timezone', () => {
|
||||
vi.mocked(geolocation).mockReturnValue({ country: 'US' });
|
||||
vi.mocked(getCountry).mockReturnValue({
|
||||
id: 'US',
|
||||
name: 'United States',
|
||||
// @ts-ignore
|
||||
timezones: ['America/Invalid'],
|
||||
});
|
||||
|
||||
const mockDate = new Date('2025-04-01T12:00:00');
|
||||
vi.setSystemTime(mockDate);
|
||||
|
||||
const request = mockRequest();
|
||||
expect(parseDefaultThemeFromCountry(request)).toBe('light');
|
||||
});
|
||||
|
||||
it('should return light theme during daytime hours', () => {
|
||||
vi.mocked(geolocation).mockReturnValue({ country: 'US' });
|
||||
vi.mocked(getCountry).mockReturnValue({
|
||||
id: 'US',
|
||||
name: 'United States',
|
||||
timezones: ['America/New_York'],
|
||||
});
|
||||
|
||||
// 设置UTC时间16:00,这样在纽约时区(EDT,UTC-4)就是12:00
|
||||
const mockDate = new Date('2025-04-01T16:00:00.000Z');
|
||||
vi.setSystemTime(mockDate);
|
||||
|
||||
const request = mockRequest();
|
||||
const result = parseDefaultThemeFromCountry(request);
|
||||
expect(result).toBe('light');
|
||||
});
|
||||
|
||||
it('should return dark theme during night hours', () => {
|
||||
vi.mocked(geolocation).mockReturnValue({ country: 'US' });
|
||||
vi.mocked(getCountry).mockReturnValue({
|
||||
id: 'US',
|
||||
name: 'United States',
|
||||
timezones: ['America/New_York'],
|
||||
});
|
||||
|
||||
// 设置UTC时间02:00,这样在纽约时区(EDT,UTC-4)就是22:00
|
||||
const mockDate = new Date('2025-04-01T02:00:00.000Z');
|
||||
vi.setSystemTime(mockDate);
|
||||
|
||||
const request = mockRequest();
|
||||
expect(parseDefaultThemeFromCountry(request)).toBe('dark');
|
||||
});
|
||||
|
||||
it('should try different header sources for country code', () => {
|
||||
vi.mocked(geolocation).mockReturnValue({});
|
||||
vi.mocked(getCountry).mockReturnValue({
|
||||
id: 'US',
|
||||
name: 'United States',
|
||||
timezones: ['America/New_York'],
|
||||
});
|
||||
|
||||
const headers = {
|
||||
'x-vercel-ip-country': 'US',
|
||||
'cf-ipcountry': 'CA',
|
||||
'x-zeabur-ip-country': 'UK',
|
||||
'x-country-code': 'FR',
|
||||
};
|
||||
|
||||
const request = mockRequest(headers);
|
||||
parseDefaultThemeFromCountry(request);
|
||||
|
||||
expect(getCountry).toHaveBeenCalledWith('US');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
});
|
||||
@@ -1,60 +0,0 @@
|
||||
import { geolocation } from '@vercel/functions';
|
||||
import { getCountry } from 'countries-and-timezones';
|
||||
import { NextRequest } from 'next/server';
|
||||
|
||||
const getLocalTime = (timeZone: string) => {
|
||||
return new Date().toLocaleString('en-US', {
|
||||
hour: 'numeric',
|
||||
hour12: false,
|
||||
timeZone,
|
||||
});
|
||||
};
|
||||
|
||||
const isValidTimeZone = (timeZone: string) => {
|
||||
try {
|
||||
getLocalTime(timeZone);
|
||||
return true; // If no exception is thrown, the timezone is valid
|
||||
} catch (e) {
|
||||
// If a RangeError is caught, the timezone is invalid
|
||||
if (e instanceof RangeError) {
|
||||
return false;
|
||||
}
|
||||
// If it's another error, better to re-throw it
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
export const parseDefaultThemeFromCountry = (request: NextRequest) => {
|
||||
// 1. Get country code from request headers
|
||||
const geo = geolocation(request);
|
||||
|
||||
const countryCode =
|
||||
geo?.country ||
|
||||
request.headers.get('x-vercel-ip-country') || // Vercel
|
||||
request.headers.get('cf-ipcountry') || // Cloudflare
|
||||
request.headers.get('x-zeabur-ip-country') || // Zeabur
|
||||
request.headers.get('x-country-code'); // Netlify
|
||||
|
||||
// If no country code is obtained, return light theme directly
|
||||
if (!countryCode) return 'light';
|
||||
|
||||
// 2. Get timezone information for the country
|
||||
const country = getCountry(countryCode);
|
||||
|
||||
// If country information is not found or the country has no timezone information, return light theme
|
||||
if (!country?.timezones?.length) return 'light';
|
||||
|
||||
const timeZone = country.timezones.find((tz) => isValidTimeZone(tz));
|
||||
if (!timeZone) return 'light';
|
||||
|
||||
// 3. Get the current time in the country's first timezone
|
||||
const localTime = getLocalTime(timeZone);
|
||||
|
||||
// 4. Parse the hour and determine the theme
|
||||
const localHour = parseInt(localTime);
|
||||
// console.log(
|
||||
// `[theme] Country: ${countryCode}, Timezone: ${country.timezones[0]}, LocalHour: ${localHour}`,
|
||||
// );
|
||||
|
||||
return localHour >= 6 && localHour < 18 ? 'light' : 'dark';
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
export * from './auth';
|
||||
export * from './correctOIDCUrl';
|
||||
export * from './geo';
|
||||
export * from './response';
|
||||
export * from './responsive';
|
||||
export * from './sse';
|
||||
|
||||
Reference in New Issue
Block a user