Refactor redis config
This commit is contained in:
parent
175970252c
commit
645110fc36
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -63,6 +63,7 @@
|
|||||||
"ratelimiter",
|
"ratelimiter",
|
||||||
"Reala",
|
"Reala",
|
||||||
"recents",
|
"recents",
|
||||||
|
"rediss",
|
||||||
"replacestate",
|
"replacestate",
|
||||||
"skippable",
|
"skippable",
|
||||||
"sonner",
|
"sonner",
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { getNavSortControlFromString, getSortByFromString } from '@/photo/sort';
|
|||||||
import { parseChromaCutoff, parseStartingHue } from '@/photo/color/sort';
|
import { parseChromaCutoff, parseStartingHue } from '@/photo/color/sort';
|
||||||
import { parseSocialKeysFromString } from '@/social';
|
import { parseSocialKeysFromString } from '@/social';
|
||||||
import { dependencies } from '../../package.json';
|
import { dependencies } from '../../package.json';
|
||||||
|
import { normalizeRedisUrl } from '@/platforms/redis';
|
||||||
|
|
||||||
// HARD-CODED GLOBAL CONFIGURATION
|
// HARD-CODED GLOBAL CONFIGURATION
|
||||||
|
|
||||||
@ -165,29 +166,10 @@ export const POSTGRES_SSL_ENABLED =
|
|||||||
process.env.DISABLE_POSTGRES_SSL === '1' ? false : true;
|
process.env.DISABLE_POSTGRES_SSL === '1' ? false : true;
|
||||||
|
|
||||||
// STORAGE: REDIS
|
// STORAGE: REDIS
|
||||||
|
export const REDIS_URL = normalizeRedisUrl(
|
||||||
/**
|
process.env.KV_URL ||
|
||||||
* Normalizes a Redis URL for use with @upstash/redis.
|
|
||||||
*
|
|
||||||
* The SDK requires an HTTPS REST URL, but some providers (e.g. Vercel KV)
|
|
||||||
* supply a native `rediss://` protocol URL. This converts `rediss://` to
|
|
||||||
* `https://` by extracting the hostname, so either format works.
|
|
||||||
*/
|
|
||||||
const normalizeRedisRestUrl = (url: string | undefined): string | undefined => {
|
|
||||||
if (!url || !url.startsWith('rediss://')) return url;
|
|
||||||
try {
|
|
||||||
return `https://${new URL(url).hostname}`;
|
|
||||||
} catch {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Priority: REST API first (native https://, preferred by @upstash/redis),
|
|
||||||
// then rediss:// KV_URL (auto-normalized), then custom fallbacks.
|
|
||||||
export const REDIS_URL = normalizeRedisRestUrl(
|
|
||||||
process.env.KV_REST_API_URL ||
|
process.env.KV_REST_API_URL ||
|
||||||
process.env.EXIF_KV_REST_API_URL ||
|
process.env.EXIF_KV_REST_API_URL ||
|
||||||
process.env.KV_URL ||
|
|
||||||
process.env.UPSTASH_REDIS_REST_URL,
|
process.env.UPSTASH_REDIS_REST_URL,
|
||||||
);
|
);
|
||||||
export const REDIS_TOKEN = (
|
export const REDIS_TOKEN = (
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Ratelimit } from '@upstash/ratelimit';
|
import { Ratelimit } from '@upstash/ratelimit';
|
||||||
import { redis } from './redis';
|
import { getRedis } from './redis';
|
||||||
|
|
||||||
export const checkRateLimitAndThrow = async ({
|
export const checkRateLimitAndThrow = async ({
|
||||||
identifier,
|
identifier,
|
||||||
@ -10,6 +10,7 @@ export const checkRateLimitAndThrow = async ({
|
|||||||
tokens?: number
|
tokens?: number
|
||||||
duration?: Parameters<typeof Ratelimit.slidingWindow>[1]
|
duration?: Parameters<typeof Ratelimit.slidingWindow>[1]
|
||||||
}) => {
|
}) => {
|
||||||
|
const redis = getRedis();
|
||||||
if (redis) {
|
if (redis) {
|
||||||
const limiter = new Ratelimit({
|
const limiter = new Ratelimit({
|
||||||
redis,
|
redis,
|
||||||
|
|||||||
@ -1,16 +1,47 @@
|
|||||||
import { REDIS_URL, REDIS_TOKEN } from '@/app/config';
|
|
||||||
import { Redis } from '@upstash/redis';
|
import { Redis } from '@upstash/redis';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a Redis URL for use with @upstash/redis:
|
||||||
|
* SDK requires an HTTPS REST URL, but some providers (e.g. Vercel KV)
|
||||||
|
* supply native `rediss://` protocol URL. This converts `rediss://` to
|
||||||
|
* `https://` by extracting hostname, so either format works.
|
||||||
|
*/
|
||||||
|
export const normalizeRedisUrl = (
|
||||||
|
url?: string,
|
||||||
|
): string | undefined => {
|
||||||
|
if (!url || !url.startsWith('rediss://')) return url;
|
||||||
|
try {
|
||||||
|
return `https://${new URL(url).hostname}`;
|
||||||
|
} catch {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const KEY_TEST = 'test';
|
const KEY_TEST = 'test';
|
||||||
|
|
||||||
export const redis = REDIS_URL && REDIS_TOKEN
|
let _redis: Redis | undefined | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazily builds the client so `config` can import `normalizeRedisRestUrl`
|
||||||
|
* from this module first.
|
||||||
|
*/
|
||||||
|
export const getRedis = (): Redis | undefined => {
|
||||||
|
if (_redis === null) {
|
||||||
|
const { REDIS_URL, REDIS_TOKEN } =
|
||||||
|
require('@/app/config') as typeof import('@/app/config');
|
||||||
|
_redis = REDIS_URL && REDIS_TOKEN
|
||||||
? new Redis({ url: REDIS_URL, token: REDIS_TOKEN })
|
? new Redis({ url: REDIS_URL, token: REDIS_TOKEN })
|
||||||
: undefined;
|
: undefined;
|
||||||
|
}
|
||||||
|
return _redis;
|
||||||
|
};
|
||||||
|
|
||||||
export const warmRedisConnection = () => {
|
export const warmRedisConnection = () => {
|
||||||
|
const redis = getRedis();
|
||||||
if (redis) { redis.get(KEY_TEST); }
|
if (redis) { redis.get(KEY_TEST); }
|
||||||
};
|
};
|
||||||
|
|
||||||
export const testRedisConnection = () => redis
|
export const testRedisConnection = () => {
|
||||||
? redis.get(KEY_TEST)
|
const redis = getRedis();
|
||||||
: Promise.reject(false);
|
return redis ? redis.get(KEY_TEST) : Promise.reject(false);
|
||||||
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user