corpus

Log | Files | Refs | README | LICENSE

commit b719cd5c618c34c5081095831f3f2a75e81d4098
parent c3ca613d0131185e4a661a388323cf5ce045e050
Author: mtmn <miro@haravara.org>
Date:   Mon, 13 Apr 2026 01:08:18 +0200

chore: run biome on src/ and test/

Diffstat:
Msrc/Client.js | 6+++---
Msrc/Db.js | 62+++++++++++++++++++++++++++++++-------------------------------
Msrc/Main.js | 4++--
Msrc/Main.purs | 40++++++++++++++++++++--------------------
Msrc/S3.js | 106++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mtest/Main.purs | 4++--
6 files changed, 115 insertions(+), 107 deletions(-)

diff --git a/src/Client.js b/src/Client.js @@ -1,8 +1,8 @@ export const extractParam = (key) => (search) => { - const params = new URLSearchParams(search); - return params.get(key); + const params = new URLSearchParams(search); + return params.get(key); }; export const formatRFC3339 = (instant) => { - return new Date(instant).toISOString(); + return new Date(instant).toISOString(); }; diff --git a/src/Db.js b/src/Db.js @@ -1,40 +1,40 @@ -import duckdb from 'duckdb'; +import duckdb from "duckdb"; export const connectImpl = (path) => (cb) => () => { - const db = new duckdb.Database(path, (err) => { - if (err) { - cb(err)(null)(); - } else { - try { - const conn = db.connect(); - cb(null)(conn)(); - } catch (e) { - cb(e)(null)(); - } - } - }); + const db = new duckdb.Database(path, (err) => { + if (err) { + cb(err)(null)(); + } else { + try { + const conn = db.connect(); + cb(null)(conn)(); + } catch (e) { + cb(e)(null)(); + } + } + }); }; export const runImpl = (conn) => (sql) => (params) => (cb) => () => { - conn.run(sql, ...params, (err) => { - cb(err)(); - }); + conn.run(sql, ...params, (err) => { + cb(err)(); + }); }; export const allImpl = (conn) => (sql) => (params) => (cb) => () => { - conn.all(sql, ...params, (err, rows) => { - if (rows) { - // DuckDB returns BIGINT as BigInt, which JSON.stringify doesn't support. - // We convert them to Numbers here. - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - for (const key in row) { - if (typeof row[key] === 'bigint') { - row[key] = Number(row[key]); - } - } - } - } - cb(err)(rows)(); - }); + conn.all(sql, ...params, (err, rows) => { + if (rows) { + // DuckDB returns BIGINT as BigInt, which JSON.stringify doesn't support. + // We convert them to Numbers here. + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + for (const key in row) { + if (typeof row[key] === "bigint") { + row[key] = Number(row[key]); + } + } + } + } + cb(err)(rows)(); + }); }; diff --git a/src/Main.js b/src/Main.js @@ -1,5 +1,5 @@ -import { config } from 'dotenv'; +import { config } from "dotenv"; export const dotenvConfig = () => { - config(); + config(); }; diff --git a/src/Main.purs b/src/Main.purs @@ -190,12 +190,12 @@ indexHtml = background: #50447f; color: #ffffff; } - + .container { max-width: 800px; margin: 0 auto; } - + h1 { color: #ffffff; margin-bottom: 20px; @@ -204,13 +204,13 @@ indexHtml = display: inline-block; padding-bottom: 5px; } - + ul { list-style: none; padding: 0; margin: 0 0 20px 0; } - + li { background: #521e40; border: 1px solid #50447f; @@ -222,28 +222,28 @@ indexHtml = align-items: center; box-shadow: 4px 4px 0px #50447f; } - + li.success { background: #521e40; border-color: #50447f; } - + .track-info { flex: 1; } - + .track-name { font-weight: bold; font-size: 16px; color: #ffffff; } - + .track-artist { font-size: 14px; color: #a0c0d0; margin-top: 1px; } - + .track-time { font-size: 12px; color: #9fbfe7; @@ -258,7 +258,7 @@ indexHtml = .album-link:hover { color: #ffffff; } - + .status { color: #b9d0aa; font-weight: bold; @@ -273,42 +273,42 @@ indexHtml = transition: transform 0.2s ease-in-out; cursor: pointer; } - + .track-cover.zoomed { transform: scale(5.0); z-index: 10; position: relative; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.5); } - + .loading { padding: 20px; color: #9fbfe7; text-align: center; } - + .error { padding: 20px; color: #eca28f; text-align: center; } - + .small { font-size: 12px; color: #9fbfe7; margin-top: 20px; } - + .small a { color: #a0c0d0; text-decoration: none; } - + .small a:hover { color: #ffffff; text-decoration: underline; } - + .refresh-btn { background: none; border: none; @@ -317,11 +317,11 @@ indexHtml = font-size: 12px; text-decoration: underline; } - + .refresh-btn:hover { color: #ffffff; } - + .playing-indicator { display: inline-block; width: 8px; @@ -331,7 +331,7 @@ indexHtml = margin-right: 8px; animation: pulse 2s infinite; } - + @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.3; } diff --git a/src/S3.js b/src/S3.js @@ -1,59 +1,67 @@ -import { S3Client, PutObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3"; +import { + S3Client, + PutObjectCommand, + HeadObjectCommand, +} from "@aws-sdk/client-s3"; -const getClient = () => new S3Client({ - region: process.env.S3_REGION || "us-east-1", - endpoint: process.env.AWS_ENDPOINT_URL, - forcePathStyle: process.env.AWS_S3_ADDRESSING_STYLE === "path", - credentials: { - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY - } -}); +const getClient = () => + new S3Client({ + region: process.env.S3_REGION || "us-east-1", + endpoint: process.env.AWS_ENDPOINT_URL, + forcePathStyle: process.env.AWS_S3_ADDRESSING_STYLE === "path", + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + }, + }); -export const uploadToS3Impl = (key) => (body) => (contentType) => (cb) => () => { - const client = getClient(); - const command = new PutObjectCommand({ - Bucket: process.env.S3_BUCKET, - Key: key, - Body: body, - ContentType: contentType - }); +export const uploadToS3Impl = + (key) => (body) => (contentType) => (cb) => () => { + const client = getClient(); + const command = new PutObjectCommand({ + Bucket: process.env.S3_BUCKET, + Key: key, + Body: body, + ContentType: contentType, + }); - client.send(command) - .then(() => { - cb(null)(); - }) - .catch((err) => { - console.error(`S3: Upload failed for ${key}`, err); - cb(err)(); - }); -}; + client + .send(command) + .then(() => { + cb(null)(); + }) + .catch((err) => { + console.error(`S3: Upload failed for ${key}`, err); + cb(err)(); + }); + }; export const existsInS3Impl = (key) => (cb) => () => { - const client = getClient(); - const command = new HeadObjectCommand({ - Bucket: process.env.S3_BUCKET, - Key: key - }); + const client = getClient(); + const command = new HeadObjectCommand({ + Bucket: process.env.S3_BUCKET, + Key: key, + }); - client.send(command) - .then(() => cb(true)()) - .catch((err) => { - if (err.name === "NotFound" || err.$metadata?.httpStatusCode === 404) { - cb(false)(); - } else { - console.error(`S3: exists check failed for ${key}`, err); - cb(false)(); - } - }); + client + .send(command) + .then(() => cb(true)()) + .catch((err) => { + if (err.name === "NotFound" || err.$metadata?.httpStatusCode === 404) { + cb(false)(); + } else { + console.error(`S3: exists check failed for ${key}`, err); + cb(false)(); + } + }); }; export const getS3UrlImpl = (key) => { - const endpoint = process.env.AWS_ENDPOINT_URL || ""; - const bucket = process.env.S3_BUCKET || ""; - if (process.env.AWS_S3_ADDRESSING_STYLE === "path") { - return `${endpoint}/${bucket}/${key}`; - } else { - return `${endpoint.replace("://", `://${bucket}.`)}/${key}`; - } + const endpoint = process.env.AWS_ENDPOINT_URL || ""; + const bucket = process.env.S3_BUCKET || ""; + if (process.env.AWS_S3_ADDRESSING_STYLE === "path") { + return `${endpoint}/${bucket}/${key}`; + } else { + return `${endpoint.replace("://", `://${bucket}.`)}/${key}`; + } }; diff --git a/test/Main.purs b/test/Main.purs @@ -22,7 +22,7 @@ main :: Effect Unit main = do Process.setEnv "AWS_ENDPOINT_URL" "https://s3.example.com" Process.setEnv "S3_BUCKET" "my-bucket" - + runSpecAndExitProcess [consoleReporter] do describe "Scorpus Main Utils" do it "should build ListenBrainz URLs correctly" do @@ -149,7 +149,7 @@ main = do -- Test Filtering (as mentioned in architecture.md) listensFiltered <- getScrobbles conn 10 0 (Just { field: "genre", value: "Rock" }) length listensFiltered `shouldEqual` 1 - + listensEmpty <- getScrobbles conn 10 0 (Just { field: "genre", value: "Jazz" }) length listensEmpty `shouldEqual` 0