{"_id":"gerdur-core","_rev":"30-5abce5f61cc06fcb48dcc29f717ce583","name":"gerdur-core","dist-tags":{"probe":"0.0.0-probe","latest":"2.20.0"},"versions":{"0.0.0-probe":{"name":"gerdur-core","version":"0.0.0-probe","license":"MIT","_id":"gerdur-core@0.0.0-probe","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"dist":{"shasum":"4aaa518c85003fa83a6363e38969173fe821f086","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-0.0.0-probe.tgz","fileCount":2,"integrity":"sha512-BjlzpcJ5vn/mljG80jkYpi4vt/zk9ivwLpmWdtH7go3YLn69evZx3vgEXFxfz6UULMEew1zDiugLWRVX20z3bQ==","signatures":[{"sig":"MEUCIQD+J5WH23LrBJEIcqr+icMkfcKDL4oZkGGN5Eb5cGhN/wIge4NAMzE7kBIsmhiKF3h7qm1nTg3DMjboERz59ThmMgY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":190},"private":false,"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"_npmVersion":"12.0.2","description":"name-availability probe","directories":{},"_nodeVersion":"26.7.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_0.0.0-probe_1788063040434_0.6687045485951995","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"gerdur-core","version":"1.0.0","author":{"name":"Christian Kling"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@1.0.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"04df9ee88db3e2ac2983c7b7ec6d88ba4508750a","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-1.0.0.tgz","fileCount":79,"integrity":"sha512-GILzziLbqMwLdXC0CQhtDer4YdEtNZwy5AZN5QnDdsuIzpXoLStoQmNrnFSzhQ+lMsoiijR3b3nsCvCTp3OAlw==","signatures":[{"sig":"MEYCIQDd66ceNr+9XlMCdO1lnJ8tPkLdOPSyqg+fADHFq4AkvAIhANEXXkD1nx/qm04S1g0jPASFwcZBQi3Q4gp6ApSFHgwJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":144514},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"357e8a47965bdfcec6afb97edbfac047404947ea","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_1.0.0_1788063524802_0.19383202665320298","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"gerdur-core","version":"1.0.1","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@1.0.1","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"0fd49d71c9f06b1eeb82af759eeb8c8f3222af24","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-1.0.1.tgz","fileCount":79,"integrity":"sha512-Lhh/JnLLE4w0GO0baGVHl4ZOMU0GtrxdPoRYZz0YuljglMCpbgnK1WsDSqXs8PG7csoAlO/Nluy82Wr9UE6ioA==","signatures":[{"sig":"MEUCIQCnhCQ1TQNT3e3r2gqYVr6lp3tmio8JknrWF9jFa8fgZAIgPPfDwphn1qgnrQQnsqnDMgBmVgkgPmOB7wSNILICwfE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":144406},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"0970d0b2809ddb785079054138f633ef4f70fe81","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_1.0.1_1788063798637_0.7051028913727533","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"gerdur-core","version":"1.0.2","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@1.0.2","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"6e58983945ff9e46c89d01aca2556b1e73d99b72","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-1.0.2.tgz","fileCount":81,"integrity":"sha512-vevbZzPW9tcjlcCHLb49nWtBh7ZjDca0U/CHvGgWwW2Mcct9aPN4gVtTIrdzcUXbKGXC7/BWDDZLofn/mx84cQ==","signatures":[{"sig":"MEUCIQDMAoYatD2B7cBSBPvojITVgvHFNcR4vNNG1rSxjlI8RQIgK5gQRntF1+iagJ3LQ0eSIWG/sZxb38rVLSPbaBRYLmk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":161017},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"e5f03fddfabfc7e9261c7dbec81cdac324537c14","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_1.0.2_1788067970316_0.28969853630639997","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"gerdur-core","version":"1.0.3","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@1.0.3","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"30fb525865f48e6735c75a8e6b2f8b9d6bbe1850","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-1.0.3.tgz","fileCount":81,"integrity":"sha512-YaZdzQzOgWIlCD0smfgYkD7y2URpcdSBgd+xeb02Z6L3KUB7FJ+APuBfcLJfGsY/TpdcPKVGo8c1Rea3EZNFUQ==","signatures":[{"sig":"MEQCIEWrjdv3CCweH3XWdj0/Jvu6bpnQhS9MALMH7YyEmQoLAiBpMEFvYHgFgX9PtJ2uqG0+AIn90fPVeo/TE8a9KK54Rw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":162352},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"dddd99f8e09697c1701d421850ea719f8b55577c","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_1.0.3_1788068548657_0.8531168908383489","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"gerdur-core","version":"1.0.4","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@1.0.4","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"a8d98bd3f7e4ebb717a5d074bea3300d59a769f1","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-1.0.4.tgz","fileCount":81,"integrity":"sha512-+15WV8TRayjF30qbQaK57CxCaOMw/Cj2ecuKAVMl4ECKOr5nemeNIALG9oPDGDOfdjjBP5LCFrzfiXGNGEAUNw==","signatures":[{"sig":"MEUCIEKm8PBTem/QXB9oSgkXlsGHS+75hDJmDtOx+YECFTH+AiEAsBFxjQoG9a/p17kuYdEANtT+ninsoUIrBC4DPbAdtIc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":169854},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"8a59d3636a729785fcd6517862e133553aa76b2d","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_1.0.4_1788129904097_0.4689799218003432","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"gerdur-core","version":"2.0.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.0.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"693246786dd7f1e88381f44a8119e9a8204bc94d","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.0.0.tgz","fileCount":89,"integrity":"sha512-F6LAE5TsvFkU9Qamy32mFKlQbmr7o/apRtHM7vNXolZ97zKc+XWKKwgoOyhsyz/LPL7DOq3SyNG8a+tqeRHtKg==","signatures":[{"sig":"MEYCIQC37fBxvrviaUUD0zyvsRiEMrDY6hC8Zbga5O3z4AVvFwIhAIICMQ0a++n8F2KeCWJCf4fZBEhYL8FuO51axiZcwxg0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":202904},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"6d60891072f25a58b842e3de37ca199426cbffd2","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.0.0_1788132366429_0.47138357628458194","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"gerdur-core","version":"2.1.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.1.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"b87f90d03245818d84f77affd5a386f787fc305d","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.1.0.tgz","fileCount":91,"integrity":"sha512-jWHIT9mCrBOSIV13EJyUSyEX5NB1fnp/cqy8Z/3BcgFYZFpIdz4Wztf5UV8N6TowJCLXvsTn8wDmw/0miJS25g==","signatures":[{"sig":"MEUCIQDiNs4z6DYyeEfQ3Jcq+C1gsSLGCtENnkqd6SRL8e++cgIgbsOiUZSw1oWO/1E7ZcgDF+yiwQbesd4uZ4KUt5//rKQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":218914},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"7a95e97ecbb39591472e4a9f5ecfec2311edbe47","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.1.0_1788137927559_0.9856405390938099","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"gerdur-core","version":"2.2.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.2.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"f335d1d930aa25f011cc856d993323843676cb6d","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.2.0.tgz","fileCount":95,"integrity":"sha512-0THulIKrjamGlwXzVx5yE//WJ8PCHToQqu+g02E5yLzvCTLJhIwcGC+PuevXvPdJIm7NbKTcce0v7RENzKKLDw==","signatures":[{"sig":"MEYCIQDGP0ZiWGg+swdIhoO9f6AzaMxHtwFGXNgOW3TvMx1g+AIhAL1WqQ+IVjIN3PwGI3C9lokxNHscqYqkXtTz191ajkDo","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":233776},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"9e67551b173834e86d70e82cc1997ee075de225e","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.2.0_1788139925283_0.6336311989691725","host":"s3://npm-registry-packages-npm-production"}},"2.3.0":{"name":"gerdur-core","version":"2.3.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.3.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"0936d128ac2dabd88972ab5573e6a6589bb7c467","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.3.0.tgz","fileCount":97,"integrity":"sha512-Rp+Iji4QmjAicJlt8PdpS/Q766L/vMrKkuQpCQ2IcyAZl4bJbOzpQ/WrqM1inab/3h2KkIBaYwmMKFGWQ4UbZA==","signatures":[{"sig":"MEUCIFFldgzFT4fVaDOJmUlPK8PqAcXzwX5s7mBzMzjU9x2iAiEAn9oEwfFUN0vHAahmH7O54/n3E/BtFL7oZGr42nX2Oxo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":241980},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"ce575cc36a020719c9391207d94adbfcfcadd408","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.3.0_1788141167402_0.5788926640859036","host":"s3://npm-registry-packages-npm-production"}},"2.4.0":{"name":"gerdur-core","version":"2.4.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.4.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"3e33b5dc120af1970bf7f48de932267b891dd816","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.4.0.tgz","fileCount":99,"integrity":"sha512-CWalnvfqbFXkOt6b5RftJcrVmYMqKJf1mtdC1KtQcXX5gzOPBPjLQtSUDwFkvErxQUyWW8CLWM1CGBKs0ZtlUg==","signatures":[{"sig":"MEYCIQCv/D1XHEUAefcZnBAekQElCPG5uRoZIG3ea4gyfOSSRQIhAKVvkH1Zaxy9k4RcR0Gl3ZnQleJx07FbE93ZvMjxFKMS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":249841},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"dbaefbec651139e44d370a4a5f664bc53b404d52","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.4.0_1788142048439_0.9704090553797704","host":"s3://npm-registry-packages-npm-production"}},"2.5.0":{"name":"gerdur-core","version":"2.5.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.5.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"6b308d36c9cca74c1513b669cabe50ac8c3fbcfa","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.5.0.tgz","fileCount":101,"integrity":"sha512-HzbJzVfbVym6PG2QTpZ6XGY47Q3whahDNcEtwZzmT/fVCByYIijSz3FzyyzvCefn/8R2Yfd1dSkQ90t7IZqU/Q==","signatures":[{"sig":"MEYCIQCCT2rG6+sV7217W67cdDm1jLoczJ0Zrx4u93RCVcyAgwIhAKIAXAJ7N7lFD4UHq+/g+Y5bl7K1VAImc1gOmkAIuseu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":262751},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"f5bde0c5e9665318aa933ea0ad471668a046c0c7","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.5.0_1788142450510_0.520438172183505","host":"s3://npm-registry-packages-npm-production"}},"2.6.0":{"name":"gerdur-core","version":"2.6.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.6.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"cc82301cf2ab7af426ddb7506e78d4e88457aeef","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.6.0.tgz","fileCount":103,"integrity":"sha512-9lskGcwdnP9+xLl6gqXtUf/ILBQgo7qPRPsmRMD3GfVn2tzRh77VDNuJ5FMuTJqpiyt3El4cNRiOw+tfJAKwBg==","signatures":[{"sig":"MEYCIQCMZamaygXXZ4nW6LvkXm0/ZdV0YRyzGp5OCvQ8MxKzPAIhAM0YsprLtSoYwscJsY6XBx1XMalfsceW3NNAt5jirk2a","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":272415},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"3d49f619b21c92793272e3a40c7b0bcc86f7b253","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.6.0_1788144155853_0.717294121947003","host":"s3://npm-registry-packages-npm-production"}},"2.7.0":{"name":"gerdur-core","version":"2.7.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.7.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"de66a3455258408c669b42b762278141bc540282","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.7.0.tgz","fileCount":105,"integrity":"sha512-CFLLq4U59BeXcgw3YpdK+PIeQHXL5euT7p9xURbafLPqMxUenqNOlhplmjSt63CA6q2W1SI3IenBQmPtE1k7Lw==","signatures":[{"sig":"MEYCIQDuRadbjOMyCJDO9YVjpwDz/fLnOLD/CLoScN/V7V/aKgIhAOZjGLBpXIxLiEHsiKp+DYCjSBjrhCweLwvrE27iIUhH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":286976},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"c29ff90b392edce8e47aca1eea41e3e0b22974a9","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.7.0_1788158618353_0.9071425687065098","host":"s3://npm-registry-packages-npm-production"}},"2.8.0":{"name":"gerdur-core","version":"2.8.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.8.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"6493c7803be0425cef710f7b4f5d89f43d0c3efa","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.8.0.tgz","fileCount":105,"integrity":"sha512-tLaHGIqUjABLr8VGGwd7+467grkm0lfE01AEB6M22rB3qGfnbassL3NoRY1/NvNRx91iSkpGnm153dxlnO/5/w==","signatures":[{"sig":"MEQCIDWeQjczKsn5ftoOrlwxEPUEPro+IMFK4tBM+PJuKIkoAiAQrqWSKW8AxhoJOv+duUMGFhncM7KRA64xlBFvYTidJw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":295198},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"a74a1c7f96ea4eb14bd223ed68ec0f81acf282a2","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.8.0_1788159068026_0.30446572605242594","host":"s3://npm-registry-packages-npm-production"}},"2.9.0":{"name":"gerdur-core","version":"2.9.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.9.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"8dd43fba5ae63ff96221826ca25948fee61fcf1f","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.9.0.tgz","fileCount":107,"integrity":"sha512-uSKJhkxmHVl+uGBh1F/2o0L6AEZ0cHlMDl/V3MlJdguILEXsrGVuShxjJ4LVPdIek74s1A5OiODHI/L1vC8syw==","signatures":[{"sig":"MEUCICOJClSDova0KH+w2ygARvTqeeMCC33aqoepjIxDKzKZAiEArTGMPZ1NFCgW6nitqSXLRF9BeC349EmKNN+cgKXFxig=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":300958},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"ec506195693d55f00f3834cfc2c078f5d5e28d7b","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.9.0_1788159456673_0.8601346331148008","host":"s3://npm-registry-packages-npm-production"}},"2.10.0":{"name":"gerdur-core","version":"2.10.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.10.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"a7f69532ac0d2172206d87e372eb4c4c4261bbdf","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.10.0.tgz","fileCount":109,"integrity":"sha512-S+4FzQsL8j1j04LncM+nwnXc4r2xqEmYdI8JmYjGVIsdnb4q7P63IgKIkvb/1kJTxBgjnpncWEQ2AWcWpXFKSg==","signatures":[{"sig":"MEYCIQDyg5mYui0W+umaHllwpkCPpgRAibKiXHtXbOzxpfnqHAIhAJsnBGB+hK64ozrDxRmNSa2HfHEKlsKHIeELdxfqBZhe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":307187},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"53d0d41e22b67da8b52aec9cd9b0e5ab551b61c4","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.10.0_1788160441099_0.7024325950456989","host":"s3://npm-registry-packages-npm-production"}},"2.11.0":{"name":"gerdur-core","version":"2.11.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.11.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"b8a03c04b08432e47cd83577d06ecb37087ed715","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.11.0.tgz","fileCount":109,"integrity":"sha512-/YNuLtTu44h0JoR4bcj+BKt7r4qMIxRHiUI7HBZ75W7GICNXN6VPy7Z89vc+LprQ38OwEL42tm8yhxivdFArgQ==","signatures":[{"sig":"MEUCIDFAVAW2q8aMgiy+z1t2T8Mcsnz7N4HFCYYCZOlco9UxAiEA0l8wkBIr7AIZoLdEMKUSXdiAsxYs8hD5bXsywzonZ9Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":310100},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"c3b9a0c8541484e94ccfe2dbcad5f2f426941e71","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.11.0_1788161702029_0.8455991697228415","host":"s3://npm-registry-packages-npm-production"}},"2.12.0":{"name":"gerdur-core","version":"2.12.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.12.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"2d6684c2d307a78a123b95057680c929279e8fbf","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.12.0.tgz","fileCount":117,"integrity":"sha512-aoFPKLV8p8Sba/eQBZfhS5aRViQkevDUAFmN5fGIF50OBxCTG5gdxGHsyVfK8+xmNYnAIJltyBgjL5ZJKTtADw==","signatures":[{"sig":"MEUCICOdS8azBHcrwTu5tMTZLyJMcZzYL57mSg/Xc0u33bzjAiEA/o0dSoc3IdRaHlEE5PFmteQrokcbN3hPh8mbK7ix59Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":329754},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"ea7c33d89c7b79bb30cb941d4660808a070152d5","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.12.0_1788163888853_0.13189917117316274","host":"s3://npm-registry-packages-npm-production"}},"2.13.0":{"name":"gerdur-core","version":"2.13.0","author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.13.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"bbf82213fcee290593f34929df6fbd2ade3729ca","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.13.0.tgz","fileCount":117,"integrity":"sha512-ndZkA9EfRafp68IcmDpMUAmwP8eSOXW1QhZ8vv6QeRMdoPCGrQhCr2qvQu3RLY/0v0/EeisjfOez3fsTKy//CA==","signatures":[{"sig":"MEUCIQDB0kegF098vbzvTCalWetVGj2+KADqdFAeXUTMdDFVDgIgPPSwr5Su0fTNxF6m8LqGpUOiX7//POfJF98TKtVcddQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":333874},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"0971005289ed1fcf8699f1df2adde46231f6c476","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Core module for gerdur.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.13.0_1788164484988_0.8275090678666939","host":"s3://npm-registry-packages-npm-production"}},"2.13.1":{"name":"gerdur-core","version":"2.13.1","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"SEE LICENSE IN LICENSE","_id":"gerdur-core@2.13.1","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"b54fe2171445ae2aa9ef146b762371e34ef9fe4d","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.13.1.tgz","fileCount":117,"integrity":"sha512-Zc5zu0aLl+SvYcUkLKzwjW/VjJMWQhRV3LO1/JPtfi2NtyYIKOGDXY2rRkkT+u7xr/vKKTfFO/+ltwhUpYuiwg==","signatures":[{"sig":"MEQCIFOXboqr22p6YDU+THxVwh7WDDZ3Ta6ljRkjnlgyCLYTAiBkIOHzDSTYbbs+bo+hd1XcgINfTHlc4cZ8UQjfqUrIbA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":346015},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"7580490b00b853c4a53583133200d6d490a3562c","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.13.1_1788166499629_0.07467209088039017","host":"s3://npm-registry-packages-npm-production"}},"2.13.2":{"name":"gerdur-core","version":"2.13.2","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.13.2","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"e5d908cb14c990b5a2f6076a8fa355de5ac342be","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.13.2.tgz","fileCount":117,"integrity":"sha512-cY5CXSh/+8LB2iOVTjs1uIhYdHltf1+trpbqdZX10xEBOmRz9n87G4u5EJtDRjgvLxppJsZNaAeE90Tsh6WvCg==","signatures":[{"sig":"MEQCIEpEW7BiI7ngQX40VYLMh/aJLNpS8qVIHMuuCcCaE0jNAiAm+KPbuotP0OWTkCgdufgbS82rwe4XrfG/dHyaK2xRww==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":347227},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"df0f157999a14536cb771f1c3b9cdbf51ec0f747","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.13.2_1788167249144_0.8119337797478798","host":"s3://npm-registry-packages-npm-production"}},"2.13.3":{"name":"gerdur-core","version":"2.13.3","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.13.3","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"d0968f0f0d3b00aeeee7f7bf2b2142aaf3c2433d","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.13.3.tgz","fileCount":118,"integrity":"sha512-fX3PAP6KoGsP1IBNVwuOY0OMB2bnZuf/xqQTQWUkHr3GGZNc02pecwW0yjTb7AK130iPe5X9Qxvb2cOYSDn48g==","signatures":[{"sig":"MEUCIE30k1/22gPLMMEiXYBi6Zx6LCizRsdHxwQPEEHd0Um1AiEA81uHn1WllmubMyuNYynTStZrKqYk3v07HWSct+ak7l0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":358821},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"2fbd474486463b4bdb7c2fdef2c048bf3a7f0942","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.13.3_1788168969816_0.8399057249215716","host":"s3://npm-registry-packages-npm-production"}},"2.14.0":{"name":"gerdur-core","version":"2.14.0","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.14.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"ece8d1fb1a63f5efbb96a4c7981f91eee8da3cf8","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.14.0.tgz","fileCount":120,"integrity":"sha512-MWUnJvt/6VvcoGYmFi1dl7Df4wt9B5aNjB5kj7gGDFlxE6ZsjWxhmFi4jSy437Qap2BsOiET78Baazh3R7/aeA==","signatures":[{"sig":"MEUCIGgGkebCdjZSPtum7NPPj7NnpWDqlCce0JLR2yG5QqjgAiEAs2I0akPmEoLqskkxeBXO9N8DJ3nkeabtnSBdHTZhQww=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":371182},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"516fff628ca868cd6b9e8337ac899769e39846a0","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.14.0_1788170745755_0.13030692892805806","host":"s3://npm-registry-packages-npm-production"}},"2.15.0":{"name":"gerdur-core","version":"2.15.0","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.15.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"0934681f5ab54f373cb0925ef12d1466f4a88390","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.15.0.tgz","fileCount":124,"integrity":"sha512-AxVAlccD8q8Cf6W0trObux1xBthc5JuHtrtqXJXUI0HIUtutrrzhv7bugJsXXDRPfqXnSecKUGydxnHS1qQaMg==","signatures":[{"sig":"MEYCIQDLSn30Jh4c/lDOMg7rdKAw/iHMIob3AEAOX5kvAXAODQIhAJ9d2phbHlG1/3eWtJwCEDfx8QeOUh6KPsd/Emn6zvRc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":394500},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"3011cd845c7a50f481227f9aace57fca29e55e08","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.15.0_1788172746533_0.3310731498345032","host":"s3://npm-registry-packages-npm-production"}},"2.16.0":{"name":"gerdur-core","version":"2.16.0","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.16.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"32f38c6b14d1a6650f2907825141ae618032a961","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.16.0.tgz","fileCount":128,"integrity":"sha512-xXdccB2EUlg9fH1wLJwSY5vXE2zltmvarB0tUYJA6eRvuKkBx2w3iAcSKUhM2jOmBWxUhLF0yu74CqnYr5o/Tw==","signatures":[{"sig":"MEUCIQCNsAujxP9dzXx61S9XF7Lf9VhYmaczdGbW0QGyfONfjQIgaN5N/scUg3Gtq42AQ4iKWLJsJmh5KlMyz9oKvkeROfY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":410922},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"e1d67c1701d768f23d3c50650ad1fd93ff7ddc64","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.16.0_1788190999904_0.5530659688343029","host":"s3://npm-registry-packages-npm-production"}},"2.17.0":{"name":"gerdur-core","version":"2.17.0","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.17.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"4cc6d486c9de13781c93080e4ec05e6428f68249","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.17.0.tgz","fileCount":130,"integrity":"sha512-63iwyEr6HLAHqw3supEXExM5PveThz/EkXB9bugxkIpN30ILl7AkNn0fcwcWOPSGzwnRDQyxD6uZBQ7fpEmcUg==","signatures":[{"sig":"MEUCIAM+utfGX42d+I8CSI2tllbyyE6zlWTthb/FZTAXMvAxAiEAr2qpfX26gH2AXv9QMpwC26buAz5p/8+8bTEcTi0CvLA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":421372},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"1124073e99cc50cda1a739c123f34b356629af61","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.7.0","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.17.0_1788192012438_0.4879212155881252","host":"s3://npm-registry-packages-npm-production"}},"2.18.0":{"name":"gerdur-core","version":"2.18.0","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.18.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"991cabc8c22c7c6956f542eaaefda443ff83c707","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.18.0.tgz","fileCount":132,"integrity":"sha512-uv8/A9CjaoU/L+zaDboOxOn1Ull2T9JB9hHckqr1087yfmPYftFsgbKfnzYIQPrObX5uCCjre19bHKI2fA7qHA==","signatures":[{"sig":"MEYCIQDqv7hFuvwPzIe/FBzce5w/+S94vjnVqW3tKxeayZXysAIhAPiNqaaCJ/ageOmwK8yEmk9Nk5DIbBdNlL+ztYZROCUl","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":434499},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"bcdea613e4067ba460449c07faea3531661938ec","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.8.1","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.18.0_1788272884560_0.8894070682546242","host":"s3://npm-registry-packages-npm-production"}},"2.19.0":{"name":"gerdur-core","version":"2.19.0","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"author":{"name":"Christian"},"license":"MIT","_id":"gerdur-core@2.19.0","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"ava":{"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true,"extensions":["ts"]},"dist":{"shasum":"44f5686980a31762878ed40c5823d84daffa55c9","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.19.0.tgz","fileCount":132,"integrity":"sha512-TPx0kJKtHAjILV7tWBVuz7xe4Nxd2t+ALI7i0hqM6FEHBMLQI0lNBcsD0aT8CSgMPSiPdMg8TIabctWv7hCMrw==","signatures":[{"sig":"MEYCIQDONqPilMf0LgF3g7kyx8BvCKLbM1bNhV2DryOA4m6SowIhAORaOKU4nX3dQ1SZ6136uFtJEd/GoOBCw+uFWpCY4JtK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":440647},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=12"},"gitHead":"f821a322ae352a6b6715521f74f2aabc1a9a2ab0","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","test":"ava","build":"tsc","prebuild":"npm run lint","prepublishOnly":"npm run lint && tsc"},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"repository":{"url":"git+https://github.com/soulwax/gerdur-core.git","type":"git"},"_npmVersion":"12.0.2","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","directories":{},"_nodeVersion":"26.8.1","dependencies":{"delay":"^5.0.0","p-queue":"^6.6.2","spotify-uri":"^2.2.0","node-html-parser":"^5.3.3","browser-id3-writer":"^4.4.0","spotify-web-api-node":"^5.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ava":"^4.1.0","eslint":"^8.11.0","ts-node":"^10.7.0","prettier":"^2.6.0","typescript":"^4.6.3","@types/node":"^17.0.23","eslint-plugin-prettier":"^4.0.0","@typescript-eslint/parser":"^5.16.0","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0"},"_npmOperationalInternal":{"tmp":"tmp/gerdur-core_2.19.0_1788273585185_0.36826938688897015","host":"s3://npm-registry-packages-npm-production"}},"2.20.0":{"name":"gerdur-core","version":"2.20.0","description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"lint":"node ./node_modules/eslint/bin/eslint.js --config .eslintrc.js --resolve-plugins-relative-to . .","prepublishOnly":"npm run lint && tsc","prebuild":"npm run lint","build":"tsc","test":"ava"},"engines":{"node":">=12"},"repository":{"type":"git","url":"git+https://github.com/soulwax/gerdur-core.git"},"homepage":"https://github.com/soulwax/gerdur-core#readme","bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"publishConfig":{"access":"public"},"author":{"name":"Christian"},"license":"MIT","dependencies":{"browser-id3-writer":"^4.4.0","delay":"^5.0.0","node-html-parser":"^5.3.3","p-queue":"^6.6.2","spotify-uri":"^2.2.0","spotify-web-api-node":"^5.0.2"},"devDependencies":{"@types/node":"^17.0.23","@types/spotify-web-api-node":"^5.0.3","@typescript-eslint/eslint-plugin":"^5.16.0","@typescript-eslint/parser":"^5.16.0","ava":"^4.1.0","eslint":"^8.11.0","eslint-plugin-prettier":"^4.0.0","prettier":"^2.6.0","ts-node":"^10.7.0","typescript":"^4.6.3"},"ava":{"extensions":["ts"],"files":["!dist","!__tests__/helpers.ts"],"require":["ts-node/register/transpile-only"],"timeout":"2m","verbose":true},"gitHead":"849d5669c5596de6421152d18906d3451c7a750e","_id":"gerdur-core@2.20.0","_nodeVersion":"26.8.1","_npmVersion":"12.0.2","dist":{"integrity":"sha512-3W4IERW7cWYi9cAqEEQ5vchjRlivHk+JRJD9UdttxxnRHzo+PkCSA6dtGILAm4Lrsb93v4XAGEsxhYVDIzUTaA==","shasum":"2bd68e3ba1633be8734c22eb5647c762ec246f00","tarball":"https://registry.npmjs.org/gerdur-core/-/gerdur-core-2.20.0.tgz","fileCount":132,"unpackedSize":441709,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGKU5SsDP3hKJcwHFPcLrmdajqCIg10GGs9ZfvAN2hzQAiEA7wqyOmDF+83+575oipRPeDCLonQqU3wfxsaYvDRSKJo="}]},"_npmUser":{"name":"soulwax","email":"soulwax-95@protonmail.com"},"directories":{},"maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/gerdur-core_2.20.0_1788278397644_0.9848001972500322"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-30T04:10:40.254Z","modified":"2026-09-01T15:59:58.002Z","0.0.0-probe":"2026-08-30T04:10:40.611Z","1.0.0":"2026-08-30T04:18:44.944Z","1.0.1":"2026-08-30T04:23:18.763Z","1.0.2":"2026-08-30T05:32:50.472Z","1.0.3":"2026-08-30T05:42:28.787Z","1.0.4":"2026-08-30T22:45:04.235Z","2.0.0":"2026-08-30T23:26:06.554Z","2.1.0":"2026-08-31T00:58:47.676Z","2.2.0":"2026-08-31T01:32:05.424Z","2.3.0":"2026-08-31T01:52:47.529Z","2.4.0":"2026-08-31T02:07:28.600Z","2.5.0":"2026-08-31T02:14:10.675Z","2.6.0":"2026-08-31T02:42:35.988Z","2.7.0":"2026-08-31T06:43:38.485Z","2.8.0":"2026-08-31T06:51:08.198Z","2.9.0":"2026-08-31T06:57:36.820Z","2.10.0":"2026-08-31T07:14:01.230Z","2.11.0":"2026-08-31T07:35:02.239Z","2.12.0":"2026-08-31T08:11:28.994Z","2.13.0":"2026-08-31T08:21:25.140Z","2.13.1":"2026-08-31T08:54:59.783Z","2.13.2":"2026-08-31T09:07:29.262Z","2.13.3":"2026-08-31T09:36:09.993Z","2.14.0":"2026-08-31T10:05:45.909Z","2.15.0":"2026-08-31T10:39:06.776Z","2.16.0":"2026-08-31T15:43:20.066Z","2.17.0":"2026-08-31T16:00:12.587Z","2.18.0":"2026-09-01T14:28:04.729Z","2.19.0":"2026-09-01T14:39:45.343Z","2.20.0":"2026-09-01T15:59:57.825Z"},"bugs":{"url":"https://github.com/soulwax/gerdur-core/issues"},"author":{"name":"Christian"},"license":"MIT","homepage":"https://github.com/soulwax/gerdur-core#readme","keywords":["deezer","deezer-api","spotify","tidal","isrc","music","metadata","id3","flac","lyrics","lrc","musicbrainz","cover-art","decrypt","blowfish"],"repository":{"type":"git","url":"git+https://github.com/soulwax/gerdur-core.git"},"description":"Deezer API client, cross-service URL resolution, Blowfish track decryption and MP3/FLAC metadata tagging — the engine behind the gerdur CLI.","maintainers":[{"name":"soulwax","email":"soulwax-95@protonmail.com"}],"readme":"# gerdur-core\n\n> Deezer API client, cross-service URL resolution, Blowfish track decryption and\n> MP3/FLAC metadata tagging — the engine behind the [`gerdur`](https://www.npmjs.com/package/gerdur) CLI.\n\n[![npm](https://img.shields.io/npm/v/gerdur-core.svg)](https://www.npmjs.com/package/gerdur-core)\n[![npm downloads](https://img.shields.io/npm/dm/gerdur-core.svg)](https://www.npmjs.com/package/gerdur-core)\n[![node](https://img.shields.io/node/v/gerdur-core.svg)](https://www.npmjs.com/package/gerdur-core)\n\n`gerdur-core` is a small, dependency-light TypeScript library that does the parts\nof a music downloader that are fiddly to get right:\n\n- **Talks to Deezer** — the internal gateway (`gw-light.php` / `gateway.php`), the\n  public REST API (`api.deezer.com`) and the media API (`media.deezer.com`), with\n  bounded retries, token refresh and per-account sessions.\n- **Resolves any link** — Deezer, Spotify, Tidal and YouTube URLs, plus ISRC and\n  UPC codes, all mapped to a downloadable Deezer track.\n- **Decrypts the stream** — Blowfish-CBC \"stripe\" decryption, buffered or as a\n  Node `Transform` (constant memory, resumable).\n- **Writes real tags** — ID3v2.3 for MP3, Vorbis comments for FLAC: cover art,\n  full credits, ReplayGain, BPM, ISRC, release dates, plain and time-synced\n  lyrics (`.lrc`).\n- **Enriches, optionally** — higher-resolution cover art and canonical\n  release/label data from MusicBrainz and the Cover Art Archive.\n\nIt has **no CLI and does no disk I/O** — every function returns data or a\n`Buffer`/stream. The [`gerdur`](https://www.npmjs.com/package/gerdur) package is\nthe CLI and the file-writing layer on top.\n\n> **Coming from `@soulwax/d-fi-core`?** `gerdur-core` is its continuation — a\n> near drop-in rename plus one `addTrackTags` change. See\n> **[MIGRATING.md](MIGRATING.md)**.\n\n---\n\n## Contents\n\n- [Install](#install)\n- [Quick start](#quick-start)\n- [Core concepts](#core-concepts)\n- [Guide](#guide)\n  - [Authenticate](#authenticate)\n  - [Look up tracks, albums, playlists, artists](#look-up-tracks-albums-playlists-artists)\n  - [Resolve a share URL (Deezer / Spotify / Tidal / YouTube)](#resolve-a-share-url)\n  - [Resolve an ISRC or UPC](#resolve-an-isrc-or-upc)\n  - [Search](#search)\n  - [Browse and discover](#browse-and-discover)\n  - [Flow, radios and a user's library](#flow-radios-and-a-users-library)\n  - [Your own library](#your-own-library)\n  - [Changing the account (write operations)](#changing-the-account-write-operations)\n  - [Podcasts](#podcasts)\n  - [Preview clips](#preview-clips)\n  - [Resolve a download URL](#resolve-a-download-url)\n  - [Download a track (buffer)](#download-a-track-buffer)\n  - [Download a track (stream, constant memory, resume)](#download-a-track-stream)\n  - [Decrypt](#decrypt)\n  - [Tag MP3 / FLAC](#tag-mp3--flac)\n  - [Enrichment (MusicBrainz + Cover Art Archive)](#enrichment)\n  - [Use multiple accounts](#use-multiple-accounts)\n  - [Running this on a server](#running-this-on-a-server)\n  - [HTTP helpers](#http-helpers)\n- [Errors](#errors)\n- [Types](#types)\n- [API reference](#api-reference)\n- [Migrating from @soulwax/d-fi-core](#migrating)\n- [The name](#the-name)\n- [Legal](#legal)\n\n---\n\n## Install\n\n```bash\nnpm i gerdur-core\n```\n\n```bash\nyarn add gerdur-core\n```\n\n```bash\npnpm add gerdur-core\n```\n\n- **Node** ≥ 12. Ships CommonJS (`dist/`) with bundled `.d.ts`.\n- **Cheap to import** — ~43 ms. The Spotify SDK and the HTML parser load only if\n  you actually resolve a Spotify/YouTube link, so a Deezer-only run (or a cold\n  start) never pays for them.\n- **Types subpath**: the hand-written Deezer response types are also published at\n  `gerdur-core/types`, so downstream packages can `import type {trackType} from\n  'gerdur-core/types'` without a second dependency.\n- You need a Deezer **`arl`** cookie for anything account-scoped (downloads,\n  `getUser`, lyrics, the internal search). Public REST endpoints (charts, public\n  search, ISRC/UPC lookups, previews) work with no auth.\n\n## Quick start\n\nDownload one track, tag it, and write it to disk:\n\n```ts\nimport {writeFileSync} from 'fs';\nimport {initDeezerApi, getTrackInfo, downloadTrackBuffer, addTrackTags} from 'gerdur-core';\n\nawait initDeezerApi(process.env.ARL!); // 192-char arl cookie\n\nconst track = await getTrackInfo('3135556'); // Daft Punk — Harder, Better, Faster, Stronger\nconst audio = await downloadTrackBuffer(track, 3); // 3 = 320 kbps MP3, downloaded + decrypted\nif (!audio) throw new Error('not available for this account / region');\n\nconst {buffer, model} = await addTrackTags(audio, track); // cover, credits, lyrics, ReplayGain…\nwriteFileSync(`${model.title}.mp3`, buffer);\nif (model.lyricsSynced) writeFileSync(`${model.title}.lrc`, model.lyricsSynced); // synced lyrics\n```\n\nThe same pipeline, one step at a time — resolve a URL, then run each track\nthrough it yourself:\n\n```ts\nimport {writeFileSync} from 'fs';\nimport {\n  initDeezerApi,\n  parseInfo,\n  resolveDownloadUrls,\n  refreshTrackTokens,\n  getBuffer,\n  decryptDownload,\n  addTrackTags,\n} from 'gerdur-core';\n\nawait initDeezerApi(process.env.ARL!);\n\nconst {tracks} = await parseInfo('https://www.deezer.com/album/302127');\nconst fresh = await refreshTrackTokens(tracks); // long lists: refresh expiring tokens first\nconst urls = await resolveDownloadUrls(fresh, ['FLAC', 'MP3_320', 'MP3_128']); // one request\n\nfor (const [i, track] of fresh.entries()) {\n  const url = urls[i];\n  if (!url) continue; // geo-blocked / unavailable\n  const body = await getBuffer(url.trackUrl);\n  const decrypted = url.isEncrypted ? decryptDownload(body, track.SNG_ID) : body;\n  const {buffer, model} = await addTrackTags(decrypted, track);\n  writeFileSync(`${model.trackNumber}. ${model.title}.${url.format === 'FLAC' ? 'flac' : 'mp3'}`, buffer);\n}\n```\n\n## Core concepts\n\n**`arl` cookie.** Deezer authenticates the mobile/gateway API with a single\n`arl` cookie (192 characters). `initDeezerApi(arl)` exchanges it for a session\ntoken. Get one from a logged-in browser: DevTools → Application → Cookies →\n`deezer.com` → `arl` (see the [FAQ](docs/faq.md)).\n\n**Sessions.** A [`Session`](#use-multiple-accounts) owns one account's state —\nthe `arl`, the HTTP client (session id / API token), the media `license_token`,\nthe resolved `country` and streaming rights, plus the retry loop and a response\ncache. The free functions (`getTrackInfo`, `searchMusic`, …) run against a\nprocess-wide **default** session that `initDeezerApi` configures. Call\n`createSession(arl)` for an isolated one.\n\n**Quality.** Numeric shorthand: **`1`** = MP3 128 kbps, **`3`** = MP3 320 kbps,\n**`9`** = FLAC (~1411 kbps). The batch resolver also takes format strings from\n[`DEEZER_FORMATS`](#resolve-a-download-url) (`FLAC`, `MP3_320`, `MP3_256`,\n`MP3_128`, `MP3_64`, `AAC_64`, `MP4_RA3/2/1`). What you actually get depends on\nthe account's plan and the track's licensing.\n\n**Track tokens.** Each track carries a `TRACK_TOKEN` that the media API needs; it\nlives ~1 hour. A token fetched at the start of a long download is stale by track\n40 and surfaces as an opaque CDN 403 — run the list through\n[`refreshTrackTokens`](#resolve-a-download-url) first.\n\n**Encryption.** Most CDN downloads are Blowfish-CBC \"stripe\"-obfuscated: the file\nis split into 2048-byte chunks and only every third one (0, 3, 6, …) is\nencrypted. `resolved.isEncrypted` (from the media API's `cipher` field) tells you\nwhether to [decrypt](#decrypt). Previews and podcast episodes are plain.\n\n**Retries.** Gateway calls run through a bounded loop — per-error-class attempt\ncaps plus a 30 s wall-clock deadline, full-jittered exponential backoff. A\npersistently failing endpoint throws a [`DeezerError`](#errors) instead of\nspinning. The policy is exported as `RETRY_POLICY`.\n\n---\n\n## Guide\n\n### Authenticate\n\n```ts\nimport {initDeezerApi, getUser} from 'gerdur-core';\n\nawait initDeezerApi(arl); // throws if arl length !== 192; returns the gateway SESSION id\n\ntry {\n  const me = await getUser();\n  console.log('Logged in as', me.BLOG_NAME, '· id', me.USER_ID, '· country', me.COUNTRY);\n} catch (err) {\n  console.error('arl invalid or expired:', (err as Error).message);\n}\n```\n\n`initDeezerApi` only pings for a session token. The `license_token`, `country`\nand streaming rights are fetched lazily on the first download (or eagerly with\n`createSession(arl)` + `await session.loadUserData()`).\n\n### Look up tracks, albums, playlists, artists\n\nAll take string ids and return the raw Deezer gateway objects. Every response is\nmemoised (LRU, 1000 entries / 60 min) and in-flight-coalesced.\n\n| Function | Returns |\n| :--- | :--- |\n| `getTrackInfo(id)` | `song.getData` — the track, with this session's `TRACK_TOKEN` |\n| `getLyrics(id)` | `song.getLyrics` — `LYRICS_TEXT` plus `LYRICS_SYNC_JSON` when synced |\n| `getAlbumInfo(id)` | `album.getData` |\n| `getAlbumTracks(id)` | every track on the album (`song.getListByAlbum`, `nb: -1`) |\n| `getPlaylistInfo(id)` | `playlist.getData` |\n| `getPlaylistTracks(id)` | every track, with `TRACK_POSITION` filled in |\n| `getArtistInfo(id)` | `artist.getData` |\n| `getDiscography(id, nb = 500)` | the artist's discography (`album.getDiscography`) |\n| `getProfile(userId)` | a public profile (`mobile.pageUser`, loved tracks) |\n| `getShowInfo(showId, nb?, start?)` | a podcast show + a page of `EPISODES` |\n| `getChannelList()` | Deezer's browse channels |\n| `getPlaylistChannel(page)` | a channel page (`app_page_get`) — e.g. `\"channels/dance\"` |\n| `getUser()` | the logged-in account's profile |\n| `getTrackInfoPublicApi(id)` / `getAlbumInfoPublicApi(id)` | the same entities from the **public** REST API (`isrc`, `bpm`, `contributors`) |\n\n```ts\nconst album = await getAlbumInfo('302127');\nconst {data: tracks} = await getAlbumTracks('302127');\nconsole.log(album.ALB_TITLE, '—', tracks.length, 'tracks');\n```\n\n### Resolve a share URL\n\n`parseInfo(url)` classifies a Deezer / Spotify / Tidal / YouTube URL, fetches it,\nand returns a uniform shape. Spotify/Tidal/YouTube entities are matched to their\nDeezer equivalents (ISRC for tracks, UPC for albums), so everything downstream is\na Deezer track.\n\n```ts\nimport {parseInfo, getUrlParts} from 'gerdur-core';\n\nconst {info, linktype, linkinfo, tracks} = await parseInfo(\n  'https://open.spotify.com/album/2noRn2Aes5aoNVsU6iWThc',\n);\n// info      → {type: 'spotify-album', id: '2noRn2Aes5aoNVsU6iWThc'}\n// linktype  → 'album' | 'playlist' | 'artist' | 'track'\n// linkinfo  → the album/playlist/artist object (empty for a single track)\n// tracks    → trackType[] ready for resolveDownloadUrls\n\nconst parts = await getUrlParts('https://deezer.com/track/3135556'); // just classify: {type, id}\n```\n\nSupported: Deezer `track` / `album` / `audiobook` / `playlist` / `artist` (+\n`page.link` short links), `spotify:` URIs and `open.spotify.com` links, Tidal\nlinks, and `youtube.com/watch` / `youtu.be` links. Spotify artist resolution is\ncapped at ~10 tracks by Spotify's anonymous token.\n\nThe lower-level converters are also exported:\n\n```ts\nimport {isrc2deezer, upc2deezer, spotify, tidal, youtube} from 'gerdur-core';\n\nconst track = await isrc2deezer('Get Lucky', 'USUM71311296'); // hydrated gw track\nconst [albumInfo, albumTracks] = await upc2deezer('Discovery', '0724384960650');\nawait spotify.setSpotifyAnonymousToken(); // needed before spotify.* calls\n```\n\n### Resolve an ISRC or UPC\n\nPublic REST, no auth. Returns public-API objects (not gw tracks — pass `.id` to\n`getTrackInfo` / `getAlbumTracks` to make them downloadable).\n\n```ts\nimport {getTrackByISRC, getAlbumByUPC, getTrackInfo} from 'gerdur-core';\n\nconst pub = await getTrackByISRC('USUM71311296'); // {id, title, bpm, gain, isrc, preview, …}\nconst track = await getTrackInfo(String(pub.id)); // now downloadable\n\nconst album = await getAlbumByUPC('0724384960650'); // {id, title, tracks: {data: [...]}}\n```\n\n### Search\n\n**Internal search** — `deezer.pageSearch`, needs a session. Richest results\n(top-result ranking, artist suggestions), and it returns per-type totals.\n\n```ts\nimport {searchMusic, searchFacets, suggest} from 'gerdur-core';\n\nconst result = await searchMusic('daft punk', ['TRACK', 'ALBUM', 'ARTIST'], 25);\nresult.TRACK.data.forEach((t) => console.log(t.SNG_TITLE, '—', t.ART_NAME));\n\nsearchFacets(result); // {track: 207, album: 99, artist: 17, …, order: ['TOP_RESULT','ARTIST','TRACK',…]}\n\nconst hints = await suggest('daf'); // fast \"as you type\" autocomplete, per-type\n```\n\n**Public REST search** — `api.deezer.com/search`, no auth. Clean objects with\n`isrc` / `preview` / `rank`, `order`, and `limit` / `index` paging.\n\n```ts\nimport {\n  searchPublicApi,\n  searchTracks,\n  searchAlbums,\n  searchArtists,\n  searchPlaylists,\n  buildAdvancedQuery,\n} from 'gerdur-core';\n\nconst {data} = await searchTracks('one more time', {order: 'RANKING', limit: 25});\n\n// advanced operators — reliable only on the track index\nconst q = buildAdvancedQuery({artist: 'daft punk', durMin: 200, bpmMax: 130});\n// => 'artist:\"daft punk\" dur_min:200 bpm_max:130'\nconst strict = await searchPublicApi(q, {strict: true, limit: 50});\n\nconst albums = await searchAlbums('discovery'); // plain string — operators are ignored here\n```\n\n| `searchPublicApi(query, options)` option | Type | Notes |\n| :--- | :--- | :--- |\n| `type` | `'track'` (default) `'album'` `'artist'` `'playlist'` `'user'` `'radio'` `'podcast'` | |\n| `order` | `RANKING`, `RATING_DESC`, `DURATION_DESC`, `TRACK_ASC`, … | |\n| `strict` | `boolean` | send `strict=on` — disables Deezer's fuzzy fallback |\n| `limit` / `index` | `number` | page size (Deezer caps near 100) / offset |\n\n`buildAdvancedQuery({query?, artist?, album?, track?, label?, durMin?, durMax?, bpmMin?, bpmMax?})`\nis a pure string builder — Deezer treats the operators as ranking hints, not hard\nfilters, and only honours them on **track** search.\n\n### Browse and discover\n\nPublic REST, no auth. Everything returns a `{data, total?, next?}` list unless\nnoted.\n\n| Function | Returns |\n| :--- | :--- |\n| `getGenres()` | Deezer's genre list (`id` `0` = \"All\") |\n| `getChart(genreId = 0, limit = 10)` | `{tracks, albums, artists, playlists, podcasts}` for a genre |\n| `getChartTracks(genreId = 0, limit = 100, index = 0)` | just the track chart, each with a `position` |\n| `getGenreArtists(genreId)` | artists filed under a genre |\n| `getEditorialList()` | Deezer's editorial sections |\n| `getEditorialReleases(id = 0, limit = 25, index = 0)` | new releases for a section |\n| `getEditorialSelection(id = 0)` | albums the editors are pushing |\n| `getEditorialCharts(id = 0)` | a section's charts (same 5-list shape as `getChart`) |\n| `getArtistTopTracks(artistId, limit = 50)` | an artist's most popular tracks |\n| `getRelatedArtists(artistId, limit = 20)` | similar artists |\n| `getArtistAlbums(artistId, limit = 50, index = 0)` | the artist's discography (public shape) |\n| `getArtistPlaylists(artistId, limit = 25)` | playlists featuring the artist |\n| `getArtistRadioTracks(artistId)` | a ready-made radio seeded from the artist |\n\n```ts\nimport {getGenres, getChart, getRelatedArtists} from 'gerdur-core';\n\nconst {data: genres} = await getGenres();\nconst rock = genres.find((g) => g.name === 'Rock')!;\nconst {tracks} = await getChart(rock.id, 20); // this week's rock chart\nconst similar = await getRelatedArtists(27); // artists like Daft Punk\n```\n\n### Flow, radios and a user's library\n\nPublic-profile data — pass a `userId` (`getUser().USER_ID`, a profile URL, or\n`parseInfo`). A **private** library is only visible to that user's own session.\n\n| Function | Returns |\n| :--- | :--- |\n| `getUserFlow(userId, limit = 40)` | **Flow** — the endless personalised mix, as tracks |\n| `getUserFavoriteTracks(userId, limit?, index?)` | loved tracks, newest first (each with `time_add`) |\n| `getUserFavoriteAlbums(userId, limit?, index?)` | favourite albums |\n| `getUserFavoriteArtists(userId, limit?, index?)` | favourite artists |\n| `getUserPlaylists(userId, limit?, index?)` | the user's own + followed playlists |\n| `getUserRadios(userId)` | radios the user favourited |\n| `getUserChartTracks(userId, limit?)` | the user's personal top tracks |\n| `getRadios()` | Deezer's curated radio list |\n| `getRadioTracks(radioId)` | a radio's current tracklist — a ready-to-play source |\n| `getRadioGenres()` | radios grouped by genre |\n\n```ts\nimport {getUser, getUserFlow, getUserFavoriteTracks, getRadioTracks} from 'gerdur-core';\n\nconst me = await getUser();\nconst {data: flow} = await getUserFlow(me.USER_ID);\nconst {data: loved} = await getUserFavoriteTracks(me.USER_ID);\nconst {data: eighties} = await getRadioTracks(38305); // \"The '80s\"\n```\n\n### Your own library\n\n`api/user.ts` above reads a **public** profile. These read what the *account*\ncan see — private playlists included — over the authenticated gateway, and\nreturn gateway shapes, so tracks come with a `TRACK_TOKEN` and are immediately\ndownloadable.\n\n| Function | Returns |\n| :--- | :--- |\n| `getMyPlaylists(userId?, nb?, start?)` | the account's own playlists, **including private ones** |\n| `getMyFavoriteTracks(userId?, nb?, start?)` | loved tracks, as downloadable gw tracks |\n| `getMyFavoriteTrackIds()` | every loved track id in one request — for diffing a local library |\n| `getMyFavoriteAlbums` / `getMyFavoriteArtists` | favourited albums / artists |\n| `getMyFavoritePlaylists` / `getMyFavoriteRadios` / `getMyFavoriteShows` | followed playlists / radios / shows |\n| `getTrackMix(sngId, nb?, start?)` | a \"more like this\" mix seeded from a track — **tokens already attached** |\n\n```ts\nimport {getMyPlaylists, getTrackMix, resolveDownloadUrls} from 'gerdur-core';\n\nconst {data: playlists} = await getMyPlaylists();       // yours, private included\nconst {data: mix} = await getTrackMix('3135556', 20);   // 20 tracks like this one\nconst urls = await resolveDownloadUrls(mix, [9, 3, 1]); // straight to download — no per-track lookup\n```\n\n`userId` defaults to the logged-in account. These are account-scoped, so they\nnever enter the shared cross-session cache.\n\n### Changing the account (write operations)\n\nEverything above reads. These change the logged-in account's library for real —\nthey are in their own module, wired into no download path, and only run when you\ncall them.\n\n| Function | Inverse |\n| :--- | :--- |\n| `addFavoriteTracks(ids)` | `removeFavoriteTracks(ids)` |\n| `addFavoriteAlbum(id)` | `removeFavoriteAlbum(id)` |\n| `addFavoriteArtist(id)` | `removeFavoriteArtist(id)` |\n| `followPlaylist(id)` | `unfollowPlaylist(id)` |\n| `addFavoriteShow(id)` | — none found |\n| `createPlaylist(title, opts?)` | **— none exists, see below** |\n| `addTracksToPlaylist(id, sngIds)` | `removeTracksFromPlaylist(id, sngIds)` |\n\n```ts\nimport {addFavoriteTracks, removeFavoriteTracks} from 'gerdur-core';\n\nawait addFavoriteTracks(['3135556']);     // love it\nawait removeFavoriteTracks(['3135556']);  // and back\n```\n\n> **`createPlaylist` is a one-way door.** Deezer's gateway exposes no delete —\n> a dozen spellings of `playlist.delete` all answer `GATEWAY_ERROR` — so a\n> playlist made here has to be removed from a Deezer client. It is also the one\n> function in this module that has not been exercised against a live account,\n> for exactly that reason.\n>\n> Method names and parameters were established by probing with incomplete\n> arguments (an existing method answers `MISSING_PARAMETER_*`), so the surface is\n> real; the round trips live in `__tests__/favorites.ts` behind\n> `GERDUR_ALLOW_WRITE_TESTS=1`.\n\nScrobbling (`log.listen`) is deliberately absent: it never answered the probe and\nit writes history that cannot be undone.\n\n### Podcasts\n\n```ts\nimport {getShowEpisodes, getEpisode} from 'gerdur-core';\n\nconst {data: episodes} = await getShowEpisodes('1265876', 25); // newest first\nconst ep = await getEpisode(episodes[0].EPISODE_ID);\n// ep.EPISODE_DIRECT_STREAM_URL — a plain MP3: no licence, no decryption\n```\n\n### Preview clips\n\nThe 30-second preview is a plain MP3 — **no licence, no `arl`, no encryption**.\nGood for \"audition before download\" and for CI that must not pull full tracks.\n\n```ts\nimport {getTrackPreview, downloadPreview} from 'gerdur-core';\n\nconst {url, duration} = (await getTrackPreview('3135556'))!; // {url, duration: 30}\nconst clip = await downloadPreview('3135556'); // Buffer (plain MP3), or null\n```\n\nAccepts a gw `track` object (reads its `MEDIA`, no extra request), a track id, or\na number.\n\n### Resolve a download URL\n\n```ts\nimport {getTrackDownloadUrl, resolveDownloadUrls, refreshTrackTokens, DEEZER_FORMATS} from 'gerdur-core';\n\n// one track\nconst one = await getTrackDownloadUrl(track, 9); // {trackUrl, isEncrypted, fileSize} | null\n\n// many tracks, ONE request — Deezer returns the best each is licensed for\nconst fresh = await refreshTrackTokens(tracks); // refresh tokens older than ~1h first\nconst urls = await resolveDownloadUrls(fresh, ['FLAC', 'MP3_320', 'MP3_128']);\n// urls[i] → {trackUrl, isEncrypted, fileSize, format, cipher} | null\n```\n\n- **`DEEZER_FORMATS`** (best → worst): `FLAC`, `MP3_320`, `MP3_256`, `MP3_128`,\n  `MP3_64`, `AAC_64`, `MP4_RA3`, `MP4_RA2`, `MP4_RA1`. `resolveDownloadUrls`\n  accepts either these strings or the `1 | 3 | 9` shorthand.\n- **`formatName(q)` / `toFormat(q)`** — normalise a number or string to the media\n  API's format string.\n- **`refreshTrackTokens(tracks, {graceSeconds = 300, session?})`** — one\n  `song.getListData` request refreshes every token that has expired or expires\n  within `graceSeconds`. Tracks with a valid token are returned untouched.\n- Falls back to the legacy `e-cdns-proxy-*.dzcdn.net` scheme when the media API\n  declines. Throws [`WrongLicense`](#errors) / [`GeoBlocked`](#errors) /\n  [`ExpiredTrackToken`](#errors).\n\n### Download a track (buffer)\n\n```ts\nimport {downloadTrackBuffer, addTrackTags} from 'gerdur-core';\n\nconst audio = await downloadTrackBuffer(track, 3); // get_url → fetch → decrypt, all in memory\nif (audio) {\n  const {buffer} = await addTrackTags(audio, track);\n  // buffer is a tagged MP3/FLAC — write it wherever\n}\n```\n\n`downloadTrackBuffer(track, quality, {onProgress?, session?})` → `Buffer | null`\n(`null` when the track+quality can't be resolved). No resume — use the stream API\nfor that.\n\n### Download a track (stream)\n\nConstant memory (~one 2048-byte stripe) regardless of file size or concurrency,\nwith progress and resume.\n\n```ts\nimport {pipeline} from 'stream/promises';\nimport {createWriteStream, statSync, existsSync} from 'fs';\nimport {streamTrackDownload} from 'gerdur-core';\n\nconst resumeFrom = existsSync('track.flac') ? statSync('track.flac').size : 0;\n\nconst {stream, size, startedAt, isEncrypted} = await streamTrackDownload(track, 9, {\n  resumeFrom, // rounded down to a 2048-byte boundary so stripe decryption stays aligned\n  onProgress: (received, total) => process.stdout.write(`\\r${((received / total) * 100) | 0}%`),\n});\n\nawait pipeline(stream, createWriteStream('track.flac', {flags: startedAt > 0 ? 'a' : 'w'}));\n```\n\nLower-level pieces:\n\n- **`getStream(url, {rangeStart?})`** → `{stream, headers, status, url}` — a raw,\n  content-decoded (gzip/br/deflate) response stream.\n- **`createDecryptStream(sngId, startChunk?)`** → a Node `Transform` for your own\n  `pipeline`. `startChunk` = `resumeFromByte / 2048`.\n- **`TrackDecryptStream(sngId, startChunk?)`** — the imperative engine\n  (`.write(buf) → Buffer`, `.final() → Buffer`) behind that `Transform`.\n\n> Streaming the **tag write** (rewriting a FLAC metadata block with no full-file\n> buffer) is not implemented yet — buffer the stream and call `addTrackTags`, or\n> tag the finished file afterwards.\n\n### Decrypt\n\n```ts\nimport {decryptDownload} from 'gerdur-core';\n\nconst plain = resolved.isEncrypted ? decryptDownload(body, track.SNG_ID) : body;\n```\n\n`decryptDownload(buffer, sngId)` decrypts a fully-downloaded body. Format-\npreserving: an encrypted MP3 stays an MP3. The per-track key is\n`md5(sngId)[i] ^ md5(sngId)[i+16] ^ \"g4el58wc0zvf9na1\"[i]`.\n\n`getSongFileName(track, quality)` builds the obfuscated filename for the legacy\nCDN path — you rarely need it directly.\n\n### Tag MP3 / FLAC\n\n`addTrackTags(buffer, track, options?)` sniffs `fLaC` vs MP3, gathers everything\nDeezer has for the track (album info, credits, lyrics, cover, artist photo,\nBPM — all coalesced, so tagging a whole album hits each endpoint once), writes\nthe tags, and returns `{buffer, model}`.\n\n```ts\nconst {buffer, model} = await addTrackTags(audio, track, {\n  coverSize: 1200, // 56–1800 px, default 1000\n});\n\nmodel.title;         // \"Harder, Better, Faster, Stronger\"\nmodel.isrc;          // \"GBDUW0000059\"\nmodel.bpm;           // 123\nmodel.replayGainTrackGain; // \"-9.24 dB\"\nmodel.lyricsSynced;  // an LRC document — write it as a .lrc sidecar\nmodel.contributors;  // normalised producers / engineers / performers / …\n```\n\n| `AddTrackTagsOptions` | Default | |\n| :--- | :--- | :--- |\n| `coverSize` | `1000` | embedded cover width, 56–1800 px |\n| `cover` / `artistImage` | — | pre-fetched image `Buffer` (`null` = skip); avoids a download |\n| `album` / `lyrics` / `publicTrack` | — | pre-fetched payloads — pass once per album to skip refetching |\n| `embedCover` / `embedArtistImage` | `true` | |\n| `writeLyrics` / `embedSyncedLyrics` | `true` | synced LRC goes to FLAC Vorbis only (no ID3v2.3 `SYLT`) |\n| `lyricsFallback` | `true` | scrape Musixmatch when Deezer has no lyrics — 2 requests per such track. Latches off automatically after 3 consecutive transport failures (see below) |\n| `richCredits` | `true` | hydrate credits + BPM for album/playlist tracks that omit them |\n| `deezerIds` / `includeRank` | `true` | write `DEEZER_*_ID` / popularity rank |\n\n**On a server, tag as a stream instead.** `addTrackTags` must materialise the\nwhole file, which is what caps concurrency. `createTagStream` produces\nbyte-identical output without ever holding the audio — both containers keep\ntheir metadata at the front, so only the header is buffered (a few KB for MP3;\nthe source's own metadata region for FLAC):\n\n```ts\nimport {pipeline} from 'stream/promises';\nimport {streamTrackDownload, resolveTagModel, createTagStream} from 'gerdur-core';\n\nconst model = await resolveTagModel(track);          // the fetches, no audio\nconst {stream} = await streamTrackDownload(track, 9);\nawait pipeline(stream, createTagStream(model), createWriteStream('track.flac'));\n```\n\n| 40 MB tracks, concurrent | `addTrackTags` | `createTagStream` |\n| :--- | ---: | ---: |\n| 4 | +239 MB | **+0 MB** |\n| 16 | +965 MB, 986 ms | **+0 MB, 150 ms** |\n\n`resolveTagModel(track, options?)` does exactly what `addTrackTags` does minus\nthe writing — same fetches, same coalescing, same `AddTrackTagsOptions`.\n\n**The Musixmatch fallback looks after itself.** Where Musixmatch blocks you — it\n403s from many networks and most datacentres — those scrapes cost a round trip\neach and return nothing: 2021 ms on a 14-track album, 70% of tagging time. After\nthree consecutive *transport* failures it stops being attempted for the rest of\nthe process, taking that album to 653 ms. A track simply not being on Musixmatch\ndoesn't count toward the latch, so it can't disable itself where it actually\nworks, and any success resets it.\n\n```ts\nimport {configureMusixmatch, musixmatchStatus} from 'gerdur-core';\n\nmusixmatchStatus();                          // {available, consecutiveFailures, maxFailures}\nconfigureMusixmatch({maxFailures: 5});       // more patient\nconfigureMusixmatch({enabled: false});       // never scrape at all\n```\n\nBuilding blocks, if you want the model without writing tags:\n\n- **`getRichAlbum(albId)`** → merged gw + public album metadata (`RichAlbum`).\n- **`buildTagModel(input)`** → the canonical `TrackTagModel` (see [Types](#types)).\n- **`normalizeContributors(SNG_CONTRIBUTORS)`** → cleans Deezer's messy\n  contributor keys into `{mainArtists, featuring, composers, producers,\n  engineers, …}`.\n- **`toLrc(syncJson, meta)`** → render `LYRICS_SYNC_JSON` as an LRC string.\n- **`downloadAlbumCover(track, size)` / `downloadArtistImage(track)`** →\n  image `Buffer`s. `MAX_COVER_SIZE` = 1800.\n\n### Enrichment\n\nOptional, **read-only**, off by default, and **never wired into `addTrackTags`**.\nFills gaps Deezer leaves — canonical release/label data and cover art larger than\nDeezer's 1800 px ceiling.\n\n```ts\nimport {configureMusicBrainz, getCoverArtByISRC, lookupRecordingByISRC} from 'gerdur-core';\n\nconfigureMusicBrainz({userAgent: 'my-app/1.0 ( me@example.com )'}); // required — MB wants a real UA\n\n// one call: ISRC → MusicBrainz recording → best Cover Art Archive front cover\nconst coverUrl = await getCoverArtByISRC(track.ISRC, {minSize: 1200}); // string | null\nif (coverUrl) {\n  const cover = await getBuffer(coverUrl);\n  await addTrackTags(audio, track, {cover}); // hand it your own cover\n}\n\n// or the pieces\nconst rec = await lookupRecordingByISRC(track.ISRC); // MBRecording | null\nrec?.isrcs;    // every ISRC MB has for this recording\nrec?.releases; // each with releaseGroupMbid, primaryType, status, label, catalogNumber\n```\n\n| Function | |\n| :--- | :--- |\n| `configureMusicBrainz({userAgent?, minIntervalMs?})` | set the UA and rate limit (default 1100 ms); call once at startup |\n| `lookupRecordingByISRC(isrc)` | canonical `MBRecording` (title, artist credits, length, ISRCs, releases) or `null` |\n| `getMusicBrainzRecording(mbid)` / `getMusicBrainzRelease(mbid, inc?)` | direct MBID lookups; release adds label / catalogue number / barcode |\n| `getCoverArt(mbid, entity = 'release-group')` | Cover Art Archive images (`front` / `approved` / `thumbnails`), or `null` |\n| `getBestCoverArtUrl(mbid, {entity?, minSize = 1200})` | one URL — approved front cover ≥ `minSize` px, else full-res |\n| `getRecordingCoverArt(recording, {minSize?, maxTries = 4})` | walks a recording's release-groups canonical-first (Official → Album → earliest) |\n| `getCoverArtByISRC(isrc, {minSize?, maxTries?})` | the whole chain — **use this**, not `getBestCoverArtUrl` on `releases[0]` |\n| `PoliteJsonClient` | the serialised, rate-limited, `503`/`429`-retrying, `404`→`null` JSON client both use — exported for your own polite clients |\n\nA persistent MusicBrainz `503` (\"server busy\") surfaces as `HttpStatusError`\nafter 3 backed-off retries — catch it and fall back to Deezer's data.\n\n### Use multiple accounts\n\nThe free functions share one default session. For concurrent accounts, hold\nisolated `Session` objects — each with its own `arl`, tokens, `license_token`\nand response cache.\n\n```ts\nimport {createSession} from 'gerdur-core';\n\nconst a = await createSession(arlOne);\nconst b = await createSession(arlTwo);\n\nawait a.loadUserData();\nconsole.log(a.country, a.canStreamLossless, a.licenseToken);\n\nconst track = await a.getTrackInfo('3135556'); // TRACK_TOKEN is a's\nconst audio = await a.getTrackBuffer(track, 9); // resolved + decrypted as account a\n```\n\n`Session` methods: `getUser`, `getTrackInfo`, `getLyrics`, `getAlbumInfo`,\n`getAlbumTracks`, `getPlaylistInfo`, `getPlaylistTracks`, `getArtistInfo`,\n`getDiscography`, `getProfile`, `searchMusic`, `getTrackDownloadUrl`,\n`resolveDownloadUrls`, `refreshTrackTokens`, `streamTrack`, `getTrackBuffer`,\nplus lifecycle (`init`, `refreshApiToken`, `loadUserData`, `invalidateUserData`)\nand the raw channels (`gw`, `gwLight`, `gwGet`).\n\n`defaultSession()` returns the shared one; `setDefaultSession(s)` swaps it (used\nin tests). The free `getTrackDownloadUrl` / `resolveDownloadUrls` /\n`streamTrackDownload` / `refreshTrackTokens` all take an optional `session`.\n\n**Caching across sessions.** Most gw payloads embed a per-account `TRACK_TOKEN`,\nso each `Session` has its own response cache. Five methods carry nothing\naccount-scoped — `album.getData`, `artist.getData`, `song.getLyrics`,\n`album.getDiscography`, `playlist.getData` — and those go to a **process-wide\ncache partitioned by country**, so one copy serves every session and a\nconcurrent burst collapses into one request. Measured with 500 sessions reading\nthe same album: **500 gateway requests → 1**, and 1.8 MB of duplicated payload →\none copy. Track lists (`song.getData`, `playlist.getSongs`, `song.getListByAlbum`,\n`episode.getData`, …) are never shared.\n\n```ts\nimport {configureCache, cacheStats, clearSharedCaches} from 'gerdur-core';\n\nconfigureCache({shared: {maxSize: 20_000, ttl: 30 * 60_000}}); // once, at startup\ncacheStats(); // {shared: {size, maxSize, hits, misses, inFlight}} — for /metrics\n```\n\n### Running this on a server\n\n- **Stream, don't buffer — including the tags.** `downloadTrackBuffer` /\n  `getTrackBuffer` hold the whole file, and `addTrackTags` holds it again (the\n  tag writers allocate a second copy). Use `streamTrackDownload` +\n  `resolveTagModel` + `createTagStream` for an end-to-end constant-memory path:\n  measured at 16 concurrent 40 MB tracks, **965 MB → ~0 MB**, and 6.5x faster.\n- **Decryption runs on the event loop.** Blowfish costs ~33 ms per 8 MiB\n  (~243 MiB/s), so heavy concurrent traffic will compete with everything else in\n  the process. Put the decrypt in a worker if you saturate a core.\n- **Size the shared cache** to your catalogue with `configureCache`, and export\n  `cacheStats()` so you can see the hit rate.\n- **Tagging is where the quota goes**, not downloading. A 14-track album costs\n  ~54 requests to tag and 2 to fetch. `{richCredits: false, lyricsFallback: false}`\n  takes that to **7 — 81% fewer against Deezer's quota** — at the cost of full\n  credits, BPM and non-Deezer lyrics. Pre-feed `{album, lyrics, cover}` for\n  anything you already hold.\n- **Evict idle sessions yourself.** `createSession` has no lifecycle — a session\n  per user, kept forever, keeps its cache forever.\n- `httpAgent` / `httpsAgent` are process-global (`maxSockets: 64`) and shared\n  between API calls and CDN downloads.\n\n### HTTP helpers\n\nThe zero-dependency HTTP client (`get`/`post`/`head`, redirects, gzip/br/deflate,\nkeep-alive) is used internally and exported for reuse:\n\n```ts\nimport {getJson, getText, getBuffer, getStream, httpAgent, httpsAgent, HttpClient} from 'gerdur-core';\n\nconst data = await getJson<{id: number}>('https://api.deezer.com/track/3135556');\nconst bytes = await getBuffer(coverUrl);\nconst {stream} = await getStream(bigFileUrl, {rangeStart: 1024});\n\nconst client = new HttpClient({baseURL: 'https://api.deezer.com', timeout: 15000});\n```\n\n`httpAgent` / `httpsAgent` are shared keep-alive agents — pass them to your own\n`http` calls to reuse connections.\n\n---\n\n## Errors\n\nGateway and media-API failures throw a **`DeezerError`** (`extends Error`):\n\n| Field | |\n| :--- | :--- |\n| `code` | Deezer's numeric code, when it sent one (e.g. `4`, `800`) |\n| `keys` | gateway error keys, e.g. `['VALID_TOKEN_REQUIRED']`, `['DATA_ERROR']` |\n| `retryable` | whether a retry could plausibly help |\n| `payload` | the raw error object |\n\nThe download path also throws these typed errors:\n\n| Error | Meaning | Recovery |\n| :--- | :--- | :--- |\n| `GeoBlocked` | not licensed in the account's country | try another account / region |\n| `WrongLicense` | the account's plan can't stream that format | request a lower quality |\n| `ExpiredTrackToken` | the `TRACK_TOKEN` aged out (~1 h) | re-fetch the track (`getTrackInfo`) or `refreshTrackTokens`, then retry |\n| `HttpStatusError` | a non-2xx HTTP response (`statusCode`, `headers`, `body`) | inspect `statusCode` |\n\n`RETRY_POLICY` (exported) is the bounded-retry config: `code4Attempts`,\n`authReinits`, `tokenRefreshes`, `baseMs`, `maxDelayMs`, `deadlineMs`.\n\n## Types\n\nResponse types are hand-written and shipped both from the main entry and the\n`gerdur-core/types` subpath:\n\n```ts\nimport type {trackType, albumType, playlistTracksType, lyricsType} from 'gerdur-core/types';\nimport type {\n  TrackTagModel, // canonical tag model from addTrackTags / buildTagModel\n  RichAlbum,\n  ResolvedUrl, // {trackUrl, isEncrypted, fileSize, format, cipher}\n  TrackStream, // {stream, size, startedAt, isEncrypted}\n  StreamTrackOptions,\n  SessionUserData, // {licenseToken, country, canStreamLossless, canStreamHq, offerId?}\n  DeezerFormat,\n  AddTrackTagsOptions,\n  MBRecording,\n  MBRelease,\n  CoverArt,\n} from 'gerdur-core';\n```\n\n`TrackTagModel` is the normalised view every tag writer consumes — `title`,\n`artists` / `mainArtists` / `featuredArtists`, `composers` / `producers` /\n`engineers` / `performers`, `trackNumber` / `discNumber` / totals, `isrc` /\n`barcode` / `bpm` / `durationMs`, `genres` / `label` / `releaseType`, `date` /\n`originalDate`, `copyright` / `producerLine`, `replayGainTrackGain`, `explicit`,\n`lyrics` / `lyricsSynced`, `ids.*` and `rank`.\n\n## API reference\n\n<details>\n<summary><b>Auth &amp; sessions</b></summary>\n\n`initDeezerApi(arl)` · `createSession(arl?)` · `defaultSession()` ·\n`setDefaultSession(s)` · `Session` · `RETRY_POLICY` · `DEFAULT_ARL`\n</details>\n\n<details>\n<summary><b>Lookups</b></summary>\n\n`getTrackInfo` · `getLyrics` · `getAlbumInfo` · `getAlbumTracks` ·\n`getPlaylistInfo` · `getPlaylistTracks` · `getArtistInfo` · `getDiscography` ·\n`getProfile` · `getUser` · `getShowInfo` · `getChannelList` ·\n`getPlaylistChannel` · `getTrackInfoPublicApi` · `getAlbumInfoPublicApi`\n</details>\n\n<details>\n<summary><b>URL &amp; code resolution</b></summary>\n\n`parseInfo` · `getUrlParts` · `isrc2deezer` · `upc2deezer` ·\n`getTrackByISRC` · `getAlbumByUPC` · `spotify.*` · `tidal.*` · `youtube.*`\n</details>\n\n<details>\n<summary><b>Search</b></summary>\n\n`searchMusic` · `searchAlternative` · `suggest` · `searchFacets` ·\n`searchPublicApi` · `searchTracks` · `searchAlbums` · `searchArtists` ·\n`searchPlaylists` · `buildAdvancedQuery`\n</details>\n\n<details>\n<summary><b>Browse &amp; discovery</b></summary>\n\n`getGenres` · `getGenreArtists` · `getChart` · `getChartTracks` ·\n`getEditorialList` · `getEditorialReleases` · `getEditorialSelection` ·\n`getEditorialCharts` · `getArtistTopTracks` · `getRelatedArtists` ·\n`getArtistAlbums` · `getArtistPlaylists` · `getArtistRadioTracks`\n</details>\n\n<details>\n<summary><b>Flow, radios, library</b></summary>\n\n`getUserFlow` · `getUserFavoriteTracks` · `getUserFavoriteAlbums` ·\n`getUserFavoriteArtists` · `getUserPlaylists` · `getUserRadios` ·\n`getUserChartTracks` · `getRadios` · `getRadioTracks` · `getRadioGenres` ·\n`getMyPlaylists` · `getMyFavoriteTracks` · `getMyFavoriteTrackIds` ·\n`getMyFavoriteAlbums` · `getMyFavoriteArtists` · `getMyFavoritePlaylists` ·\n`getMyFavoriteRadios` · `getMyFavoriteShows` · `getTrackMix` ·\n`addFavoriteTracks` · `removeFavoriteTracks` · `addFavoriteAlbum` ·\n`removeFavoriteAlbum` · `addFavoriteArtist` · `removeFavoriteArtist` ·\n`followPlaylist` · `unfollowPlaylist` · `addFavoriteShow` · `createPlaylist` ·\n`addTracksToPlaylist` · `removeTracksFromPlaylist` · `configureMusixmatch` ·\n`musixmatchStatus`\n</details>\n\n<details>\n<summary><b>Podcasts &amp; previews</b></summary>\n\n`getEpisode` · `getShowEpisodes` · `getTrackPreview` · `downloadPreview`\n</details>\n\n<details>\n<summary><b>Download, decrypt, stream</b></summary>\n\n`getTrackDownloadUrl` · `resolveDownloadUrls` · `refreshTrackTokens` ·\n`downloadTrackBuffer` · `streamTrackDownload` · `getStream` ·\n`createDecryptStream` · `TrackDecryptStream` · `decryptDownload` ·\n`getSongFileName` · `DEEZER_FORMATS` · `formatName` · `toFormat`\n</details>\n\n<details>\n<summary><b>Tagging</b></summary>\n\n`addTrackTags` · `resolveTagModel` · `createTagStream` · `probeAudioOffset` ·\n`buildTagModel` · `getRichAlbum` · `normalizeContributors` ·\n`toLrc` · `downloadAlbumCover` · `downloadArtistImage` · `MAX_COVER_SIZE`\n</details>\n\n<details>\n<summary><b>Enrichment</b></summary>\n\n`configureMusicBrainz` · `lookupRecordingByISRC` · `getMusicBrainzRecording` ·\n`getMusicBrainzRelease` · `getCoverArt` · `getBestCoverArtUrl` ·\n`getRecordingCoverArt` · `getCoverArtByISRC` · `PoliteJsonClient`\n</details>\n\n<details>\n<summary><b>HTTP &amp; errors</b></summary>\n\n`configureCache` · `cacheStats` · `clearSharedCaches` · `getJson` · `getText` ·\n`getBuffer` · `getStream` · `HttpClient` · `httpAgent` ·\n`httpsAgent` · `HttpStatusError` · `DeezerError` · `GeoBlocked` · `WrongLicense`\n· `ExpiredTrackToken`\n</details>\n\nSee the [FAQ](docs/faq.md) and the [`gerdur` CLI](https://www.npmjs.com/package/gerdur)\nfor end-to-end usage.\n\n<a id=\"migrating\"></a>\n\n## Migrating from @soulwax/d-fi-core\n\n`gerdur-core` is the continuation of `@soulwax/d-fi-core`. `gerdur-core@1.0.1` is\nthat codebase renamed; everything since is additive except a single `addTrackTags`\nsignature change. **[MIGRATING.md](MIGRATING.md)** has the exact steps —\ndependency swap, import rename, the one fix, the workarounds you can now delete,\nand the faster primitives (`downloadTrackBuffer`, batch `resolveDownloadUrls`,\n`streamTrackDownload`, `Session`, `DeezerError`) to adopt.\n\n## The name\n\n**Gerðr** is the jötunn Freyr sends Skírnir riding through a wall of fire to\nfetch. Her name is *garðr* — \"the enclosure, the walled garden\" (English\n*garden*). `gerdur-core` does the crossing: resolve the identifier, get past the\nwall, decrypt the stream, hand back a finished track.\n\n## Legal\n\nFor personal and archival use with content you are entitled to access. You are\nresponsible for complying with the terms of service of any provider and with\ncopyright law in your jurisdiction. The authors accept no liability for misuse.\nRespect the artists — buy the music you love.\n\nSee [LICENSE](LICENSE) · [Contributing](.github/CONTRIBUTING.md) ·\n[Issues](https://github.com/soulwax/gerdur-core/issues)\n","readmeFilename":"README.md"}