fix: romaji index routes moved after app init + kuromoji in root package.json

- app.get/delete for /api/romaji-index were placed before const app = express()
  causing ReferenceError on startup — moved into the ROUTES section
- kuromoji moved from backend/package.json to root package.json so Docker
  picks it up during the existing npm install step
- Fixed dicPath resolution to use path.dirname(require.resolve(...))

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-05-17 21:26:46 +02:00
1 parent aa239f8e6a
commit 5bcb8b09a8
2 files changed
+45 -41

No files matched your search

+42 -41
View File
@@ -26,7 +26,8 @@ const { downloadTrack, downloadAlbumTracks } = require('./lib/downloader');
let _tokenizer = null;
try {
const kuromoji = require('kuromoji');
kuromoji.builder({ dicPath: path.join(require.resolve('kuromoji'), '../../dict') })
const dicPath = path.join(path.dirname(require.resolve('kuromoji')), '..', 'dict');
kuromoji.builder({ dicPath })
.build((err, t) => {
if (err) console.warn('⚠️ kuromoji failed to load:', err.message);
else { _tokenizer = t; console.log('✅ kuromoji tokenizer ready'); }
@@ -113,46 +114,6 @@ async function _fetchNdSongs(ndUrl, user, pass) {
return songs;
}
// GET /api/romaji-index?ndUrl=...&user=...&pass=...
app.get('/api/romaji-index', async (req, res) => {
const { ndUrl, user, pass } = req.query;
if (!ndUrl || !user || !pass) return res.status(400).json({ error: 'missing params' });
if (!_tokenizer) return res.status(503).json({ error: 'tokenizer not ready — try again in a few seconds' });
const key = `${ndUrl}|${user}`;
const cached = _romajiCache.get(key);
if (cached && Date.now() - cached.ts < ROMAJI_TTL) return res.json(cached.index);
try {
const songs = await _fetchNdSongs(ndUrl, user, pass);
const index = songs
.filter(s => JP_RE.test(s.title) || JP_RE.test(s.artist) || JP_RE.test(s.album))
.map(s => ({
id: s.id,
r: [_toRomaji(s.title), _toRomaji(s.artist), _toRomaji(s.album)].join(' '),
title: s.title,
artist: s.artist || '',
album: s.album || '',
coverArt: s.coverArt || '',
duration: s.duration || 0,
albumId: s.albumId || '',
artistId: s.artistId || '',
}));
_romajiCache.set(key, { ts: Date.now(), index });
console.log(`✅ Romaji index built: ${index.length} JP songs (${songs.length} total)`);
res.json(index);
} catch (e) {
console.error('Romaji index error:', e);
res.status(500).json({ error: e.message });
}
});
// DELETE /api/romaji-index — force rebuild on next request
app.delete('/api/romaji-index', (req, res) => {
_romajiCache.clear();
res.json({ ok: true });
});
// ─── INIT ─────────────────────────────────────────────────────────────────────
const app = express();
app.use((req, res, next) => {
@@ -204,6 +165,46 @@ function parseSpotifyUrl(url) {
// ─── ROUTES ──────────────────────────────────────────────────────────────────
// GET /api/romaji-index?ndUrl=...&user=...&pass=...
app.get('/api/romaji-index', async (req, res) => {
const { ndUrl, user, pass } = req.query;
if (!ndUrl || !user || !pass) return res.status(400).json({ error: 'missing params' });
if (!_tokenizer) return res.status(503).json({ error: 'tokenizer not ready — try again in a few seconds' });
const key = `${ndUrl}|${user}`;
const cached = _romajiCache.get(key);
if (cached && Date.now() - cached.ts < ROMAJI_TTL) return res.json(cached.index);
try {
const songs = await _fetchNdSongs(ndUrl, user, pass);
const index = songs
.filter(s => JP_RE.test(s.title) || JP_RE.test(s.artist) || JP_RE.test(s.album))
.map(s => ({
id: s.id,
r: [_toRomaji(s.title), _toRomaji(s.artist), _toRomaji(s.album)].join(' '),
title: s.title,
artist: s.artist || '',
album: s.album || '',
coverArt: s.coverArt || '',
duration: s.duration || 0,
albumId: s.albumId || '',
artistId: s.artistId || '',
}));
_romajiCache.set(key, { ts: Date.now(), index });
console.log(`✅ Romaji index built: ${index.length} JP songs (${songs.length} total)`);
res.json(index);
} catch (e) {
console.error('Romaji index error:', e);
res.status(500).json({ error: e.message });
}
});
// DELETE /api/romaji-index — force rebuild on next request
app.delete('/api/romaji-index', (req, res) => {
_romajiCache.clear();
res.json({ ok: true });
});
app.post('/api/spotify/track-artwork', async (req, res) => {
const tracks = req.body.tracks || [];
if (!tracks.length) return res.json({ results: [] });
+3
View File
@@ -7,6 +7,9 @@
"preview": "vite preview",
"icons": "node scripts/gen-icons.mjs"
},
"dependencies": {
"kuromoji": "^0.1.2"
},
"devDependencies": {
"sharp": "^0.34.5",
"vite": "^5.4.0"