revert fb8e77bb68
Local Build and Deploy / deploy (push) Successful in 1m11s
Local Build and Deploy / deploy (push) Successful in 1m11s
revert style: clean up code with prettier and eslint
This commit is contained in:
1 parent
27de078f54
commit
e85e4d74ea
378 files changed
+20710
-22428
No files matched your search
@@ -13,40 +13,40 @@
|
||||
* The public URL prefix is configurable via the CMS setting
|
||||
* `soundtrack_base_url` — see site-settings.ts defaults.
|
||||
*/
|
||||
import { promises as fs } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { parseBuffer } from "music-metadata";
|
||||
import { promises as fs } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { parseBuffer } from 'music-metadata'
|
||||
|
||||
// ── Constants ──────────────────────────────────────────────────────
|
||||
|
||||
/** On-disk directory where MP3s live. Fixed (not configurable from UI to
|
||||
* avoid any path traversal risk). */
|
||||
export const SOUNDTRACK_DIR = path.join(process.cwd(), "public", "swf", "dcr", "hof_furni", "mp3");
|
||||
export const SOUNDTRACK_DIR = path.join(process.cwd(), 'public', 'swf', 'dcr', 'hof_furni', 'mp3')
|
||||
|
||||
/** Default public URL prefix (with trailing slash). Can be overridden via
|
||||
* the `soundtrack_base_url` CMS setting. */
|
||||
export const DEFAULT_SOUNDTRACK_BASE_URL = "/swf/dcr/hof_furni/mp3/";
|
||||
export const DEFAULT_SOUNDTRACK_BASE_URL = '/swf/dcr/hof_furni/mp3/'
|
||||
|
||||
/** 10 MB hard limit per upload. */
|
||||
export const MAX_SOUNDTRACK_SIZE = 10 * 1024 * 1024;
|
||||
export const MAX_SOUNDTRACK_SIZE = 10 * 1024 * 1024
|
||||
|
||||
// ── File paths ─────────────────────────────────────────────────────
|
||||
|
||||
/** Reject codes that would escape the sounds directory or use unsafe chars. */
|
||||
export function isSafeSoundtrackCode(code: string): boolean {
|
||||
return /^[a-zA-Z0-9_-]{1,32}$/.test(code);
|
||||
return /^[a-zA-Z0-9_-]{1,32}$/.test(code)
|
||||
}
|
||||
|
||||
export function getSoundtrackPath(code: string): string {
|
||||
if (!isSafeSoundtrackCode(code)) {
|
||||
throw new Error(`Unsafe soundtrack code: ${code}`);
|
||||
throw new Error(`Unsafe soundtrack code: ${code}`)
|
||||
}
|
||||
return path.join(SOUNDTRACK_DIR, `${code}.mp3`);
|
||||
return path.join(SOUNDTRACK_DIR, `${code}.mp3`)
|
||||
}
|
||||
|
||||
/** Ensure the sounds directory exists (mkdir -p). */
|
||||
export async function ensureSoundtrackDir(): Promise<void> {
|
||||
await fs.mkdir(SOUNDTRACK_DIR, { recursive: true });
|
||||
await fs.mkdir(SOUNDTRACK_DIR, { recursive: true })
|
||||
}
|
||||
|
||||
// ── Validation ─────────────────────────────────────────────────────
|
||||
@@ -62,18 +62,18 @@ export async function ensureSoundtrackDir(): Promise<void> {
|
||||
* files masquerading as .mp3 (e.g. renamed .exe).
|
||||
*/
|
||||
export function validateMp3Bytes(buf: Buffer): boolean {
|
||||
if (buf.length < 4) return false;
|
||||
if (buf.length < 4) return false
|
||||
|
||||
// ID3v2 tag header
|
||||
if (buf[0] === 0x49 && buf[1] === 0x44 && buf[2] === 0x33) return true;
|
||||
if (buf[0] === 0x49 && buf[1] === 0x44 && buf[2] === 0x33) return true
|
||||
|
||||
// MPEG sync: 0xFF followed by 0xFA/0xFB/0xFE/0xF3/0xF2
|
||||
if (buf[0] === 0xff) {
|
||||
const b = buf[1];
|
||||
if (b === 0xfa || b === 0xfb || b === 0xfe || b === 0xf3 || b === 0xf2) return true;
|
||||
const b = buf[1]
|
||||
if (b === 0xfa || b === 0xfb || b === 0xfe || b === 0xf3 || b === 0xf2) return true
|
||||
}
|
||||
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,12 +82,12 @@ export function validateMp3Bytes(buf: Buffer): boolean {
|
||||
*/
|
||||
export async function extractMp3Duration(buf: Buffer): Promise<number> {
|
||||
try {
|
||||
const meta = await parseBuffer(buf, { mimeType: "audio/mpeg" }, { duration: true });
|
||||
const seconds = meta.format.duration;
|
||||
if (typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return 0;
|
||||
return Math.round(seconds);
|
||||
const meta = await parseBuffer(buf, { mimeType: 'audio/mpeg' }, { duration: true })
|
||||
const seconds = meta.format.duration
|
||||
if (typeof seconds !== 'number' || !Number.isFinite(seconds) || seconds <= 0) return 0
|
||||
return Math.round(seconds)
|
||||
} catch {
|
||||
return 0;
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +98,8 @@ export async function extractMp3Duration(buf: Buffer): Promise<number> {
|
||||
* Creates the parent directory if missing.
|
||||
*/
|
||||
export async function writeSoundtrackFile(code: string, buf: Buffer): Promise<void> {
|
||||
await ensureSoundtrackDir();
|
||||
await fs.writeFile(getSoundtrackPath(code), buf);
|
||||
await ensureSoundtrackDir()
|
||||
await fs.writeFile(getSoundtrackPath(code), buf)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,15 +107,15 @@ export async function writeSoundtrackFile(code: string, buf: Buffer): Promise<vo
|
||||
*/
|
||||
export async function deleteSoundtrackFile(code: string): Promise<void> {
|
||||
try {
|
||||
await fs.unlink(getSoundtrackPath(code));
|
||||
await fs.unlink(getSoundtrackPath(code))
|
||||
} catch (err) {
|
||||
const errCode = (err as NodeJS.ErrnoException).code;
|
||||
if (errCode === "ENOENT") return;
|
||||
throw err;
|
||||
const errCode = (err as NodeJS.ErrnoException).code
|
||||
if (errCode === 'ENOENT') return
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export type { TraxChannel, TraxEvent } from "@/lib/trax-format";
|
||||
export type { TraxChannel, TraxEvent } from '@/lib/trax-format'
|
||||
// Re-export the Trax format parser for server-side use. The actual
|
||||
// implementation lives in `@/lib/trax-format` so it can be imported by
|
||||
// client components without pulling in Node-only deps from this file.
|
||||
@@ -124,4 +124,4 @@ export {
|
||||
parseTrackSamples,
|
||||
parseTraxChannels,
|
||||
TRAX_TICK_SECONDS,
|
||||
} from "@/lib/trax-format";
|
||||
} from '@/lib/trax-format'
|
||||
Reference in new issue
Block a user