Skip to content

Commit 2c78c17

Browse files
committed
refactor: config and new rate limit vars
1 parent 85d2abc commit 2c78c17

9 files changed

Lines changed: 38 additions & 18 deletions

File tree

AGENTS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ In-memory `Map`. Key = SHA-256(normalized query params). TTL = `CACHE_TTL` env (
6868
| `LRCLIB_API_BASE` | `https://lrclib.net/api` | |
6969
| `ADMIN_KEY` || Required for admin cache endpoints |
7070
| `CACHE_TTL` | `86400` | Seconds |
71+
| `RATE_LIMIT_MAX` | `15` | Max requests per window; set both to `0` to disable |
72+
| `RATE_LIMIT_DURATION` | `60000` | Window duration in ms |
7173
| `NODE_ENV` || `production` disables pino-pretty |
7274

7375
## Key files

src/fetcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ const DEFAULT_PLAIN_SEQUENCE = [
1717
]
1818
const FAST_MODE_SEQUENCE = ['lrclib', 'simpmusic']
1919

20-
if (config.geniusToken) DEFAULT_PLAIN_SEQUENCE.push('genius')
21-
if (config.mxmEnabled) {
20+
if (config.genius.token) DEFAULT_PLAIN_SEQUENCE.push('genius')
21+
if (config.mxm.enabled) {
2222
DEFAULT_PLAIN_SEQUENCE.push('mxm')
2323
FAST_MODE_SEQUENCE.push('mxm')
2424
}

src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ const app = new Elysia()
4747
.use(cors())
4848
.use(
4949
rateLimit({
50-
max: 15,
51-
duration: 60_000,
50+
max: config.rateLimit.max,
51+
duration: config.rateLimit.duration,
52+
skip: config.rateLimit.enabled ? undefined : () => true,
5253
errorResponse: new Response(
5354
JSON.stringify({
5455
error: { message: 'Too many requests', timestamp: timestamp() },

src/lib/cache.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function loadFromCache(key: string): unknown | null {
4545
}
4646

4747
export function saveToCache(key: string, result: unknown): void {
48-
store.set(key, { expiry: Date.now() / 1000 + config.cacheTtl, result })
48+
store.set(key, { expiry: Date.now() / 1000 + config.cache.ttl, result })
4949
}
5050

5151
export function clearCache(): { removed: number } {
@@ -57,7 +57,7 @@ export function clearCache(): { removed: number } {
5757
export function cacheStats() {
5858
return {
5959
cache_keys: store.size,
60-
ttl_seconds: config.cacheTtl,
60+
ttl_seconds: config.cache.ttl,
6161
version: CACHE_VERSION,
6262
}
6363
}

src/lib/config.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
11
export const config = {
22
port: Number(process.env.PORT ?? 4000),
33
logLevel: (process.env.LOG_LEVEL ?? 'INFO').toUpperCase(),
4-
adminKey: process.env.ADMIN_KEY ?? '',
5-
geniusToken: process.env.GENIUS_TOKEN ?? '',
6-
lrclibApiBase: process.env.LRCLIB_API_BASE ?? 'https://lrclib.net/api',
7-
cacheTtl: Number(process.env.CACHE_TTL ?? 86400),
8-
mxmEnabled: (process.env.MXM_ENABLED ?? 'true').toLowerCase() !== 'false',
4+
admin: {
5+
key: process.env.ADMIN_KEY ?? '',
6+
},
7+
genius: {
8+
token: process.env.GENIUS_TOKEN ?? '',
9+
},
10+
lrclib: {
11+
apiBase: process.env.LRCLIB_API_BASE ?? 'https://lrclib.net/api',
12+
},
13+
cache: {
14+
ttl: Number(process.env.CACHE_TTL ?? 86400),
15+
},
16+
mxm: {
17+
enabled: (process.env.MXM_ENABLED ?? 'true').toLowerCase() !== 'false',
18+
},
19+
rateLimit: {
20+
max: Number(process.env.RATE_LIMIT_MAX ?? 15),
21+
duration: Number(process.env.RATE_LIMIT_DURATION ?? 60_000),
22+
get enabled() {
23+
return this.max !== 0 || this.duration !== 0
24+
},
25+
},
926
}

src/routes/cache.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import { CacheStats } from '../lib/schemas'
1111
const logger = getLogger('cache')
1212

1313
function checkAdmin(request: Request, queryKey?: string): boolean {
14-
if (!config.adminKey) return false
14+
if (!config.admin.key) return false
1515
const provided = queryKey ?? request.headers.get('x-admin-key') ?? ''
1616
if (!provided) return false
1717
try {
18-
const a = Buffer.from(config.adminKey.padEnd(64).slice(0, 64))
18+
const a = Buffer.from(config.admin.key.padEnd(64).slice(0, 64))
1919
const b = Buffer.from(provided.padEnd(64).slice(0, 64))
20-
return timingSafeEqual(a, b) && provided === config.adminKey
20+
return timingSafeEqual(a, b) && provided === config.admin.key
2121
} catch {
2222
return false
2323
}

src/sources/genius.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ export const geniusFetcher = defineFetcher({
1717
source: 'genius',
1818
displayName: 'Genius',
1919
async run(artist, song, _timestamps, signal): Promise<LyricResult | null> {
20-
if (!config.geniusToken) {
20+
if (!config.genius.token) {
2121
logger.info('Genius token not configured — skipping')
2222
return null
2323
}
2424

2525
const searchRes = await httpGet(
2626
`https://api.genius.com/search?q=${encodeURIComponent(`${song} ${artist}`)}`,
27-
{ headers: { Authorization: `Bearer ${config.geniusToken}` }, signal },
27+
{ headers: { Authorization: `Bearer ${config.genius.token}` }, signal },
2828
)
2929
if (!searchRes.ok) return null
3030

src/sources/lrclib.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ async function lrclibGet(
3232
track: Record<string, unknown>,
3333
signal?: AbortSignal,
3434
): Promise<Record<string, unknown> | null> {
35-
const url = new URL(`${config.lrclibApiBase}/get`)
35+
const url = new URL(`${config.lrclib.apiBase}/get`)
3636
if (track.trackName) url.searchParams.set('track_name', String(track.trackName))
3737
if (track.artistName) url.searchParams.set('artist_name', String(track.artistName))
3838
if (track.albumName) url.searchParams.set('album_name', String(track.albumName))

src/sources/mxm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ export const mxmFetcher = defineFetcher({
195195
source: 'mxm',
196196
displayName: 'Musixmatch',
197197
async run(artist, song, timestamps, signal): Promise<LyricResult | null> {
198-
if (!config.mxmEnabled) return null
198+
if (!config.mxm.enabled) return null
199199

200200
const state = await getToken(signal)
201201

0 commit comments

Comments
 (0)