{ "name": "multi-scrobbler", "version": "0.14.2", "type": "module", "description": "scrobble plays from multiple sources to multiple clients", "scripts": { "schema": "npm run -s schema:docs && npm run -s schema:app", "schema:docs": "node src/backend/utils/SchemaDocsStaticUtils.ts", "schema:app": "node src/backend/utils/SchemaAppStaticUtils.ts", "circular": "madge --circular --extensions ts src/index.ts", "test": "npm run -s test:backend", "test:backend": "mocha --reporter spec", "dev": "node src/backend/index.ts", "start": "NODE_ENV=production node src/backend/index.ts", "build:frontend": "vite build", "build:backend": "tsc -p src/backend && npm run -s schema:app", "build": "npm run -s build:backend && npm run -s build:frontend && npm run -s docs:build", "build:parallel": "concurrently --kill-others-on-fail --names backend,frontend,docs \"npm run -s build:backend\" \"npm run -s build:frontend\" \"npm run docs:build\"", "docs:install": "cd docsite && npm install --no-audit", "docs:start": "cd docsite && npm start", "docs:build": "npm run -s schema:docs && cd docsite && npm run build", "docs:netlify": "npm run -s docs:install && npm run -s docs:build", "postinstall": "patch-package", "install:parallel": "concurrently --kill-others-on-fail --names app,docs \"npm ci --no-audit\" \"npm run docs:install\"", "cliff": "git-cliff --unreleased", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "atproto:lex:tealfm": "npm exec -- lex-cli pull -c src/backend/common/vendor/teal/lex.config.ts && npm exec -- lex-cli generate -c src/backend/common/vendor/teal/lex.config.ts", "frontend:analyze": "npx esbuild src/client/index-next.tsx --bundle --platform=node --metafile=meta.json --outfile=/dev/null" }, "exports": { ".": { "types": "./src/backend/common/infrastructure/typings/lastfm-node-client.d.ts", "import": "./src/backend/index.js" } }, "engines": { "node": ">=24.14.0", "npm": "^11.12.1" }, "repository": { "type": "git", "url": "git+https://github.com/FoxxMD/multi-scrobbler.git" }, "author": "", "license": "MIT", "bugs": { "url": "https://github.com/FoxxMD/multi-scrobbler/issues" }, "private": true, "homepage": ".", "dependencies": { "@astronautlabs/mdns": "^1.0.7", "@atcute/bluesky": "^4.0.5", "@atcute/client": "^5.1.0", "@atcute/identity": "^2.0.0", "@atcute/identity-resolver": "^2.0.0", "@atcute/lexicons": "^2.0.0", "@atcute/password-session": "^1.0.0", "@atcute/repo": "^1.0.0", "@donedeal0/superdiff": "^1.1.1", "@ewanc26/tid": "^1.0.2", "@foxxmd/chromecast-client": "^1.0.4", "@foxxmd/get-version": "^0.0.3", "@foxxmd/logging": "^0.2.6", "@foxxmd/redact-string": "^0.1.2", "@foxxmd/regex-buddy-core": "^0.1.2", "@foxxmd/string-sameness": "^0.4.0", "@jellyfin/sdk": "^0.11.0", "@kenyip/backoff-strategies": "^1.0.4", "@keyv/valkey": "^1.0.8", "@lukehagar/plexjs": "^0.39.0", "@pierre/diffs": "^1.2.4", "@rocksky/sdk": "^0.2.2", "@supercharge/promise-pool": "^3.0.0", "@svrooij/sonos": "^2.5.0", "@xhayper/discord-rpc": "1.3.0", "abort-controller-x": "^0.5.0", "address": "^1.2.2", "ajv": "^8.18.0", "ajv-formats": "^3.0.1", "avahi-browse": "^1.1.4", "better-sse": "^0.8.0", "body-parser": "^2.2.2", "cacheable": "^2.5.0", "castv2": "^0.1.10", "clone": "^2.1.2", "common-tags": "^1.8.2", "compare-versions": "^4.1.2", "concat-stream": "^2.0.0", "cors": "^2.8.5", "dayjs": "^1.10.4", "dbus-ts": "^0.0.7", "discord.js": "^14.26.0", "dotenv": "^10.0.0", "drizzle-orm": "^1.0.0-rc.2-c5a84d1", "express": "^5.2.1", "express-session": "^1.19.0", "fast-equals": "^6.0.0", "fixed-size-list": "^0.3.0", "flat-cache": "^6.1.13", "formidable": "^3.5", "glob": "^11.1.0", "google-auth-library": "^9.15.0", "gotify": "^1.1.0", "http-cookie-agent": "^7.0.1", "icecast-metadata-stats": "^0.1.12", "iso-websocket": "^0.3.0", "iti": "^0.7.0", "json-diff-ts": "^5.0.0-alpha.2", "json5": "^2.2.3", "jsondiffpatch": "^0.7.3", "keyv": "^5.6.0", "kodi-api": "^0.2.1", "lastfm-ts-api": "^2.6.0", "merge-error-cause": "^5.0.2", "mopidy": "^1.3.0", "mpc-js": "^2.1.1", "musicbrainz-api": "^0.27.0", "nanoid": "^3.3.1", "neotraverse": "^0.6.18", "node-musickit-api": "^3.1.0-next.5", "node-object-hash": "^3.1.1", "normalize-url": "^8.0.1", "ntfy": "^1.15.2", "p-event": "^4.2.0", "p-map": "^7.0.4", "p-retry": "^7.1.1", "passport": "^0.6.0", "passport-deezer": "^0.2.0", "patch-package": "^8.0.1", "prom-client": "^15.1.3", "qs": "^6.15.2", "react-use-timeout": "^1.0.0", "round-robin-js": "^3.0.10", "serialize-error": "^13.0.1", "spotify-web-api-node": "^5.0.2", "sqlite-up": "^0.5.0", "superagent": "^8.0.9", "toad-scheduler": "^3.0.0", "tough-cookie": "^5.1.2", "typeson": "^9.0.4", "typeson-registry": "^11.1.1", "undici": "7.24.6", "vite-express": "^0.22.1", "vlc-client": "^1.1.1", "xml2js": "0.6.2", "youtubei.js": "^15.0.1" }, "devDependencies": { "@atcute/lex-cli": "^3.1.0", "@chakra-ui/react": "^3.36.0", "@chromatic-com/storybook": "^5.1.2", "@dbus-types/notifications": "^0.0.5", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", "@eslint/js": "^10.0.1", "@faker-js/faker": "^9.0.1", "@flamefrontend/sse-runtime-react": "^0.7.0", "@fortawesome/fontawesome-svg-core": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "^0.2.6", "@gr2m/net-interceptor": "^1.0.0", "@lukemorales/query-key-factory": "^1.3.4", "@mui/material": "^9.1.1", "@react-hook/resize-observer": "^2.0.2", "@react-hook/window-size": "^3.1.1", "@react-nano/use-event-source": "^0.16.0", "@reduxjs/toolkit": "^2.11.2", "@rolldown/plugin-babel": "^0.2.3", "@storybook/addon-a11y": "^10.4.3", "@storybook/addon-docs": "^10.4.3", "@storybook/react-vite": "^10.4.3", "@tailwindcss/vite": "^4.2.2", "@tanstack/react-query": "^5.101.0", "@tanstack/react-query-devtools": "^5.101.0", "@tanstack/react-virtual": "^3.14.3", "@tsconfig/node18": "^1.0.1", "@types/chai": "^4.3.0", "@types/chai-as-promised": "^7.1.5", "@types/clone": "^2.1.2", "@types/common-tags": "^1.8.1", "@types/concat-stream": "^2.0.0", "@types/cors": "^2.8.17", "@types/express": "^5.0.6", "@types/express-serve-static-core": "^5.1.1", "@types/express-session": "^1.18.2", "@types/formidable": "^3.4.5", "@types/jest": "^27.5.2", "@types/jscodeshift": "^0.11.6", "@types/mocha": "^9.1.0", "@types/node": "^24.12.2", "@types/object-hash": "^3.0.0", "@types/passport": "^1.0.12", "@types/qs": "^6.15.1", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "@types/react-window": "^1.8.5", "@types/sinon": "^21.0.0", "@types/spotify-web-api-node": "^5.0.7", "@types/superagent": "^8.1.9", "@types/xml2js": "^0.4.11", "@vitejs/plugin-react": "^6.0.2", "@welldone-software/why-did-you-render": "^10.0.1", "ansi-to-react": "^6.2.6", "autoprefixer": "^10.4.27", "babel-plugin-react-compiler": "^1.0.0", "chai": "^4.3.6", "chai-as-promised": "^8.0.2", "clsx": "^2.1.1", "drizzle-kit": "^1.0.0-rc.2-c5a84d1", "eslint": "^10.6.0", "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-boundaries": "^7.0.2", "eslint-plugin-import-x": "^4.17.1", "eslint-plugin-mocha": "^11.3.0", "eslint-plugin-prefer-arrow-functions": "^3.2.4", "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-storybook": "^10.3.6", "eslint-plugin-unicorn": "^72.0.0", "eslint-plugin-unused-imports": "^4.4.1", "git-cliff": "^2.12.0", "globals": "^17.7.0", "ky": "^2.0.2", "mocha": "^10.3.0", "mockdate": "^3.0.5", "msw": "^2.14.6", "msw-storybook-addon": "^2.0.7", "next-themes": "^0.4.6", "nodemon": "^3.0.3", "playwright": "^1.58.2", "react": "^19.2.6", "react-dom": "^19.2.6", "react-error-boundary": "^6.1.1", "react-icons": "^5.6.0", "react-redux": "^9.2.0", "react-router-dom": "^7.15.0", "react-virtuoso": "^4.18.7", "sass": "^1.99.0", "shiki": "^4.0.2", "sinon": "^21.0.2", "storybook": "^10.4.3", "storybook-addon-remix-react-router": "^6.1.0", "tailwindcss": "^4.2.2", "tinyexec": "^1.1.1", "ts-essentials": "^10.2.0", "ts-json-schema-generator": "^2.3.0", "typescript": "^6.0.3", "typescript-eslint": "^8.59.3", "usehooks-ts": "^3.1.1", "vite": "^8.0.12", "with-local-tmp-dir": "^7.0.1" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "overrides": { "spotify-web-api-node": { "superagent": "$superagent" }, "musicbrainz-api": { "rate-limit-threshold": "0.2.1" } }, "msw": { "workerDirectory": [ "public" ] } }