WIP. A little custom music server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

handle different pcs

+50 -38
+1
backend/package.json
··· 16 16 "drizzle-kit": "^0.31.8", 17 17 "jest-image-snapshot": "^6.5.1", 18 18 "oxlint": "^1.35.0", 19 + "vite-tsconfig-paths": "^6.0.3", 19 20 "vitest": "^4.0.16" 20 21 }, 21 22 "peerDependencies": {
+16 -7
backend/src/m4a/service.test.ts
··· 2 2 import { BunContext } from "@effect/platform-bun"; 3 3 import { M4aService } from "./service"; 4 4 import { expect, it } from "vitest"; 5 + import os from "node:os"; 5 6 6 7 const layers = Layer.merge(BunContext.layer, M4aService.Default); 7 8 ··· 10 11 it(label, () => Effect.runPromise(effect())); 11 12 }; 12 13 14 + const m4aFilePathMac = "/Users/johnb/boombox-test-data/15 Downtown.m4a"; 15 + const nonM4aFilePathMac = "/Users/johnb/boombox-test-data/01 - hover.mp3"; 16 + 17 + const m4aFilePathArch = 18 + "/home/johnb/media/music/music/Foster The People - Torches X (Deluxe) (2021) [M4A]/15 Downtown.m4a"; 19 + const nonM4aFilePathArch = "/home/johnb/boombox-test-data/01 - hover.mp3"; 20 + 21 + const m4aFilePath = os.platform() === "darwin" ? m4aFilePathMac : m4aFilePathArch; 22 + const nonM4aFilePath = os.platform() === "darwin" ? nonM4aFilePathMac : nonM4aFilePathArch; 13 23 14 24 test("readMetadata should throw an error if the file is not an m4a", () => 15 25 Effect.gen(function* () { 16 26 const m4aService = yield* M4aService; 17 - const input = "/Users/johnb/boombox-test-data/01 - hover.mp3"; 27 + const input = nonM4aFilePath; 18 28 const actual = yield* Effect.exit(m4aService.readMetadata(input)); 19 29 expect(Exit.isFailure(actual)).toBe(true); 20 30 }).pipe(Effect.provide(layers))); 21 31 22 - test("readMetadata should NOT throw an error on a valid m4a file", () =>Effect.gen(function* () { 23 - const m4aService = yield* M4aService; 24 - const input = "/Users/johnb/boombox-test-data/15 Downtown.m4a"; 32 + test("readMetadata should NOT throw an error on a valid m4a file", () => 33 + Effect.gen(function* () { 34 + const m4aService = yield* M4aService; 35 + const input = m4aFilePath; 25 36 const actual = yield* Effect.exit(m4aService.readMetadata(input)); 26 37 expect(Exit.isSuccess(actual)).toBe(true); 27 38 }).pipe(Effect.provide(layers))); ··· 29 40 test("readMetadata should return album, artist and title", () => 30 41 Effect.gen(function* () { 31 42 const m4aService = yield* M4aService; 32 - const input = "/Users/johnb/boombox-test-data/15 Downtown.m4a"; 43 + const input = m4aFilePath; 33 44 const actual = yield* m4aService.readMetadata(input); 34 45 expect(actual.album).toBe("Torches X"); 35 46 expect(actual.artists).toContain("Foster The People"); 36 47 expect(actual.title).toBe("Downtown"); 37 48 expect(actual.trackNumber).toBe(15); 38 49 }).pipe(Effect.provide(layers))); 39 - 40 -
+33 -31
bun.lock
··· 1 1 { 2 2 "lockfileVersion": 1, 3 - "configVersion": 0, 4 3 "workspaces": { 5 4 "": { 6 5 "name": "boombox", ··· 12 11 "name": "@boombox/backend", 13 12 "dependencies": { 14 13 "@boombox/shared": "workspace:*", 15 - "@effect/cluster": "latest", 16 - "@effect/experimental": "latest", 17 - "@effect/language-service": "latest", 18 - "@effect/opentelemetry": "latest", 19 - "@effect/platform": "latest", 20 - "@effect/platform-bun": "latest", 21 - "@effect/sql": "latest", 22 - "@effect/sql-drizzle": "latest", 23 - "@effect/sql-sqlite-bun": "latest", 24 - "@elysiajs/eden": "latest", 25 - "@elysiajs/openapi": "latest", 26 - "@opentelemetry/exporter-trace-otlp-http": "latest", 27 - "@opentelemetry/sdk-metrics": "latest", 28 - "@opentelemetry/sdk-trace-base": "latest", 29 - "@opentelemetry/sdk-trace-node": "latest", 30 - "@opentelemetry/sdk-trace-web": "latest", 31 - "drizzle-orm": "latest", 32 - "effect": "latest", 33 - "elysia": "latest", 34 - "ulid": "latest", 35 - "zod": "latest", 14 + "@effect/cluster": "^0.56.0", 15 + "@effect/experimental": "^0.58.0", 16 + "@effect/language-service": "^0.62.5", 17 + "@effect/opentelemetry": "^0.60.0", 18 + "@effect/platform": "^0.94.0", 19 + "@effect/platform-bun": "^0.87.0", 20 + "@effect/sql": "^0.49.0", 21 + "@effect/sql-drizzle": "^0.48.0", 22 + "@effect/sql-sqlite-bun": "^0.50.0", 23 + "@elysiajs/eden": "^1.4.6", 24 + "@elysiajs/openapi": "^1.4.13", 25 + "@opentelemetry/exporter-trace-otlp-http": "^0.208.0", 26 + "@opentelemetry/sdk-metrics": "^2.2.0", 27 + "@opentelemetry/sdk-trace-base": "^2.2.0", 28 + "@opentelemetry/sdk-trace-node": "^2.2.0", 29 + "@opentelemetry/sdk-trace-web": "^2.2.0", 30 + "drizzle-orm": "^0.45.1", 31 + "effect": "^3.19.13", 32 + "elysia": "^1.4.19", 33 + "ulid": "^3.0.2", 34 + "zod": "^4.2.1", 36 35 }, 37 36 "devDependencies": { 38 - "@effect/vitest": "latest", 39 - "@types/bun": "latest", 40 - "@vitest/coverage-v8": "latest", 41 - "drizzle-kit": "latest", 42 - "jest-image-snapshot": "latest", 43 - "oxlint": "latest", 44 - "vitest": "latest", 37 + "@effect/vitest": "^0.27.0", 38 + "@types/bun": "^1.3.5", 39 + "@vitest/coverage-v8": "4.0.16", 40 + "drizzle-kit": "^0.31.8", 41 + "jest-image-snapshot": "^6.5.1", 42 + "oxlint": "^1.35.0", 43 + "vite-tsconfig-paths": "^6.0.3", 44 + "vitest": "^4.0.16", 45 45 }, 46 46 "peerDependencies": { 47 - "typescript": "latest", 47 + "typescript": "^5.9.3", 48 48 }, 49 49 }, 50 50 "shared": { ··· 1554 1554 1555 1555 "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], 1556 1556 1557 - "vite-tsconfig-paths": ["vite-tsconfig-paths@5.1.4", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w=="], 1557 + "vite-tsconfig-paths": ["vite-tsconfig-paths@6.0.3", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-7bL7FPX/DSviaZGYUKowWF1AiDVWjMjxNbE8lyaVGDezkedWqfGhlnQ4BZXre0ZN5P4kAgIJfAlgFDVyjrCIyg=="], 1558 1558 1559 1559 "vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], 1560 1560 ··· 1705 1705 "recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], 1706 1706 1707 1707 "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], 1708 + 1709 + "web-tanstack/vite-tsconfig-paths": ["vite-tsconfig-paths@5.1.4", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w=="], 1708 1710 1709 1711 "web-tanstack/vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="], 1710 1712