{"_id":"@barnemax/bandcamp-types","_rev":"6-fd7058cedbc32d15a0fe310fce08c5dc","name":"@barnemax/bandcamp-types","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.0":{"name":"@barnemax/bandcamp-types","version":"0.1.0","_id":"@barnemax/bandcamp-types@0.1.0","maintainers":[{"name":"barnemax","email":"maxime.etchebarne@gmail.com"}],"dist":{"shasum":"40e03e1cca487978f71ceb43f7cc7b5851c751e4","tarball":"https://registry.npmjs.org/@barnemax/bandcamp-types/-/bandcamp-types-0.1.0.tgz","fileCount":13,"integrity":"sha512-kazc/tmUmWsS6OpDFB3GkhUXW8EO2MHyaTWUgLxzmX34nFWfhPmqk2/SF/Kihjc8xr9EN0MhDKRB8tP7iflS7A==","signatures":[{"sig":"MEYCIQC/mHkpaNicuqmxEQEj/dclw6Ky4Y0jx8OJTrdw6CR4mQIhAOKtP+EuG9nOQ3miWYKhBAWyVPe6DhrXVQ095Yua+uto","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13619},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"39a4830c04a26976644d020d09c7d1d73ffc77e3","scripts":{"build":"tsc -p tsconfig.build.json","compile":"tsc --noEmit","prepublishOnly":"pnpm build"},"_npmUser":{"name":"barnemax","email":"maxime.etchebarne@gmail.com"},"_npmVersion":"11.6.2","directories":{},"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/bandcamp-types_0.1.0_1772303779176_0.5162228366774724","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@barnemax/bandcamp-types","version":"0.1.1","_id":"@barnemax/bandcamp-types@0.1.1","maintainers":[{"name":"barnemax","email":"maxime.etchebarne@gmail.com"}],"dist":{"shasum":"f93eff5b5da7b4263a1987bfaec8c27a157f799b","tarball":"https://registry.npmjs.org/@barnemax/bandcamp-types/-/bandcamp-types-0.1.1.tgz","fileCount":16,"integrity":"sha512-PUahrIVBLmNxxs5qN4BAT1G6U8lJ6oibBr0iOPG/6RjFBmVf5KSAW8IBhxTDwKAAkQ6T5XE4olJj1iEr1V2yaw==","signatures":[{"sig":"MEUCIHoiUhAuxGxGeO+8mRI/eXHqlulp6kunLNcjpf8b51JqAiEA6UwOZUBI0q8l3oviDoxNK24citY26L34qAVPnBehh1k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17739},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"26a59cfd8119e7e3cac149b65a46cec988714ec8","scripts":{"build":"tsc -p tsconfig.build.json","compile":"tsc --noEmit","prepublishOnly":"pnpm build"},"_npmUser":{"name":"barnemax","email":"maxime.etchebarne@gmail.com"},"_npmVersion":"11.6.2","description":"TypeScript types for Bandcamp's internal DOM structures, page data blobs, and collection APIs.","directories":{},"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/bandcamp-types_0.1.1_1772304883257_0.05927390317959258","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@barnemax/bandcamp-types","version":"0.1.2","keywords":["bandcamp","typescript","types"],"_id":"@barnemax/bandcamp-types@0.1.2","maintainers":[{"name":"barnemax","email":"maxime.etchebarne@gmail.com"}],"homepage":"https://github.com/Barnemax/bandcamp-types","dist":{"shasum":"53c8d1c52526104d70afae64118a09b97a6a76b0","tarball":"https://registry.npmjs.org/@barnemax/bandcamp-types/-/bandcamp-types-0.1.2.tgz","fileCount":16,"integrity":"sha512-LwC/MT+2O4X0/VyYdXZ39XWXJZNXuaB2UFd9vgN4O//lkOucqoEEbyznePz0sDz3MGjfS9+ygV3pD+YhoHS+Fw==","signatures":[{"sig":"MEQCIF4l6eDcT2XkuCqsVXR9li/LgOWK6DdDN8vCD2Bid1igAiAO5VUcHGiBYGl3BZmAyaygCPwg19gkierxSuGGs0c82Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22333},"pnpm":{"onlyBuiltDependencies":["esbuild"]},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"225ae2bd1ab56d67c42f66619438e464b6a0be33","scripts":{"lint":"eslint src scripts tests","test":"tsx scripts/gen-keys.ts && vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc --noEmit","gen-keys":"tsx scripts/gen-keys.ts","test:watch":"tsx scripts/gen-keys.ts && vitest","prepublishOnly":"pnpm build"},"_npmUser":{"name":"barnemax","email":"maxime.etchebarne@gmail.com"},"_npmVersion":"11.6.2","description":"TypeScript types for Bandcamp's internal DOM structures, page data blobs, and collection APIs.","directories":{},"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","eslint":"^10.0.2","vitest":"^4.0.18","ts-morph":"^27.0.2","typescript":"^5.9.3","@types/node":"^25.3.3","node-html-parser":"^7.0.2","@typescript-eslint/parser":"^8.56.1","@typescript-eslint/eslint-plugin":"^8.56.1"},"_npmOperationalInternal":{"tmp":"tmp/bandcamp-types_0.1.2_1772474605405_0.48149203578119226","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@barnemax/bandcamp-types","version":"0.1.3","keywords":["bandcamp","typescript","types"],"_id":"@barnemax/bandcamp-types@0.1.3","maintainers":[{"name":"barnemax","email":"maxime.etchebarne@gmail.com"}],"homepage":"https://github.com/Barnemax/bandcamp-types","dist":{"shasum":"5a218e6be4a59ba1b435a84dc7d82274fed3b10d","tarball":"https://registry.npmjs.org/@barnemax/bandcamp-types/-/bandcamp-types-0.1.3.tgz","fileCount":16,"integrity":"sha512-fGpKYMVpygY5RN79aI48ee/eFlseumByztoQS4VLDT2t+lwuVv6bXPLLwJ/yPsKg+TXqCjRnR1F+tDcftI7HHA==","signatures":[{"sig":"MEUCIQCpJiAgQ/tLWuHorqcfqZLHqmV+EMPXPwLX3f8Q2tTbWwIgV7nKRvpeINY0AyyRHpYCqicxBoU0s6UR2VssNq9fm2c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22813},"pnpm":{"onlyBuiltDependencies":["esbuild"]},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"4ec8485939a46b435276949d89ce97ceab8e26b9","scripts":{"lint":"eslint src scripts tests","test":"tsx scripts/gen-keys.ts && vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc --noEmit","gen-keys":"tsx scripts/gen-keys.ts","test:watch":"tsx scripts/gen-keys.ts && vitest","prepublishOnly":"pnpm build"},"_npmUser":{"name":"barnemax","email":"maxime.etchebarne@gmail.com"},"_npmVersion":"11.6.2","description":"TypeScript types for Bandcamp's internal DOM structures, page data blobs, and collection APIs.","directories":{},"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","eslint":"^10.0.2","vitest":"^4.0.18","ts-morph":"^27.0.2","typescript":"^5.9.3","@types/node":"^25.3.3","node-html-parser":"^7.0.2","@typescript-eslint/parser":"^8.56.1","@typescript-eslint/eslint-plugin":"^8.56.1"},"_npmOperationalInternal":{"tmp":"tmp/bandcamp-types_0.1.3_1772658945788_0.7992342635029905","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@barnemax/bandcamp-types","version":"0.1.4","keywords":["bandcamp","typescript","types"],"_id":"@barnemax/bandcamp-types@0.1.4","maintainers":[{"name":"barnemax","email":"maxime.etchebarne@gmail.com"}],"homepage":"https://github.com/Barnemax/bandcamp-types","dist":{"shasum":"89d2fbe017fd274ac8a5cb672847bfa1352a7a52","tarball":"https://registry.npmjs.org/@barnemax/bandcamp-types/-/bandcamp-types-0.1.4.tgz","fileCount":16,"integrity":"sha512-xSScE0eA4yF6uutFnkfyBttS6YZl4trN73ixuKVT3GHZZcV+yH1zvICumq+TTBs0DoocVEbpVF6jNR98uvrWKQ==","signatures":[{"sig":"MEQCIEb+ovpjgkCsM2dJ5PxjFTVsAqH9GO4Vf8O5Zy4KDNCPAiB7bzaATyZbbfZ65WqzGfWkH1xkiudySQUq/jYews4U1w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23149},"pnpm":{"onlyBuiltDependencies":["esbuild"]},"type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"bf991a76209b7375dc372a8967431c222db2ea73","scripts":{"lint":"eslint src scripts tests","test":"tsx scripts/gen-keys.ts && vitest run","build":"tsc -p tsconfig.build.json","compile":"tsc --noEmit","gen-keys":"tsx scripts/gen-keys.ts","test:watch":"tsx scripts/gen-keys.ts && vitest","prepublishOnly":"pnpm build"},"_npmUser":{"name":"barnemax","email":"maxime.etchebarne@gmail.com"},"_npmVersion":"11.6.2","description":"TypeScript types for Bandcamp's internal DOM structures, page data blobs, and collection APIs.","directories":{},"_nodeVersion":"22.13.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","eslint":"^10.0.2","vitest":"^4.0.18","ts-morph":"^27.0.2","typescript":"^5.9.3","@types/node":"^25.3.3","node-html-parser":"^7.0.2","@typescript-eslint/parser":"^8.56.1","@typescript-eslint/eslint-plugin":"^8.56.1"},"_npmOperationalInternal":{"tmp":"tmp/bandcamp-types_0.1.4_1772962393897_0.16793868399774392","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@barnemax/bandcamp-types","version":"0.1.5","type":"module","publishConfig":{"access":"public"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"types":"./dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.build.json","compile":"tsc --noEmit","gen-keys":"tsx scripts/gen-keys.ts","lint":"eslint src scripts tests","prepublishOnly":"pnpm build","test":"tsx scripts/gen-keys.ts && vitest run","test:watch":"tsx scripts/gen-keys.ts && vitest"},"pnpm":{"onlyBuiltDependencies":["esbuild"]},"homepage":"https://github.com/Barnemax/bandcamp-types","keywords":["bandcamp","typescript","types"],"devDependencies":{"@types/node":"^25.3.3","@typescript-eslint/eslint-plugin":"^8.56.1","@typescript-eslint/parser":"^8.56.1","eslint":"^10.0.2","node-html-parser":"^7.0.2","ts-morph":"^27.0.2","tsx":"^4.21.0","typescript":"^5.9.3","vitest":"^4.0.18"},"gitHead":"90da78b1a502a53dae37e368370b889775704656","_id":"@barnemax/bandcamp-types@0.1.5","description":"TypeScript types for Bandcamp's internal DOM structures, page data blobs, and collection APIs.","_nodeVersion":"22.13.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-19FGJgK9+7RYpclp+ZKf13BbA21EO760b4HwQDviwOjehFbDGu3CfOHuPmf+hLCXe+1i17AVMxP09b57cUuIkQ==","shasum":"95f432615996ec799ff982db62d1bb25ebab7ab6","tarball":"https://registry.npmjs.org/@barnemax/bandcamp-types/-/bandcamp-types-0.1.5.tgz","fileCount":16,"unpackedSize":23219,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBMCdD1DOZKa/DB1R2lTHQrjIfx2R5fcJgsmkuQKykK8AiEArruN9QdakPIUunPAFSFdoxbR/bZLmRAaHGfteQEBdG0="}]},"_npmUser":{"name":"barnemax","email":"maxime.etchebarne@gmail.com"},"directories":{},"maintainers":[{"name":"barnemax","email":"maxime.etchebarne@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bandcamp-types_0.1.5_1772962872194_0.9203086505890685"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-28T18:36:19.023Z","modified":"2026-03-08T09:41:12.439Z","0.1.0":"2026-02-28T18:36:19.353Z","0.1.1":"2026-02-28T18:54:43.406Z","0.1.2":"2026-03-02T18:03:25.558Z","0.1.3":"2026-03-04T21:15:45.940Z","0.1.4":"2026-03-08T09:33:14.050Z","0.1.5":"2026-03-08T09:41:12.335Z"},"homepage":"https://github.com/Barnemax/bandcamp-types","keywords":["bandcamp","typescript","types"],"description":"TypeScript types for Bandcamp's internal DOM structures, page data blobs, and collection APIs.","maintainers":[{"name":"barnemax","email":"maxime.etchebarne@gmail.com"}],"readme":"# @barnemax/bandcamp-types\n\nTypeScript types for Bandcamp's internal DOM structures, page data blobs, and collection APIs.\n\n## Installation\n\n```sh\nnpm install -D @barnemax/bandcamp-types\n# or\npnpm add -D @barnemax/bandcamp-types\n```\n\n## Page blob\n\nBandcamp embeds a JSON blob in `#pagedata[data-blob]` on every page. The shape varies by page type — modelled here as a discriminated union.\n\n```ts\nimport type { PageBlob } from '@barnemax/bandcamp-types'\nimport { SEL_PAGE_BLOB } from '@barnemax/bandcamp-types'\n\nconst el = document.querySelector(SEL_PAGE_BLOB)\nconst blob: PageBlob = JSON.parse(el!.getAttribute('data-blob')!)\n```\n\n### Narrowing with guards\n\n```ts\nimport { isCollectionPage, isTralbumPage, isDownloadPage } from '@barnemax/bandcamp-types'\n\nif (isCollectionPage(blob)) {\n  // blob is CollectionPageBlob\n  console.log(blob.fan_data.username)\n} else if (isTralbumPage(blob)) {\n  // blob is TralbumPageBlob\n  // album if blob.track_id is absent, track if present\n  console.log(blob.fan_tralbum_data.is_purchased)\n} else if (isDownloadPage(blob)) {\n  // blob is DownloadPageBlob\n  console.log(blob.download_items)\n}\n```\n\nThe guards also accept `unknown`, so they work directly on a freshly parsed value without an intermediate cast.\n\n### LoosePageBlob — skip narrowing\n\nA flat optional merge of all three variants. Every field is optional, so accesses are safe without committing to a specific page type. Useful for quick ad-hoc access when the page type is genuinely unknown.\n\n```ts\nimport type { LoosePageBlob } from '@barnemax/bandcamp-types'\n\nconst blob = JSON.parse(el!.getAttribute('data-blob')!) as LoosePageBlob\n\nconst username = blob.fan_data?.username\nconst isPurchased = blob.fan_tralbum_data?.is_purchased\nconst downloads = blob.download_items\n```\n\n## Other exports\n\n| Export | Description |\n|---|---|\n| `ReleaseLdJson` | `script[type=\"application/ld+json\"]` on release pages (schema.org `MusicAlbum` / `MusicRecording`) |\n| `TralbumTrackInfo` | Track data from the `data-tralbum` attribute or Tralbum API |\n| `CollectorsBlob`, `BandcampCollectionItem`, etc. | Collection API response shapes |\n| `BANDCAMP_COLLECTION_URL` | `https://bandcamp.com/api/fancollection/1/collection_items` |\n| `BANDCAMP_COLLECTORS_URL` | `https://bandcamp.com/api/tralbumcollectors/1/thumbs` |\n| `SEL_PAGE_BLOB`, `SEL_LD_JSON`, etc. | DOM selectors |\n\n## Notes\n\nTypes are reverse-engineered from Bandcamp's live DOM — Bandcamp can change them without notice.\n\nThese types are **intentionally partial**: only properties useful to a consuming project are included. Internal Bandcamp fields (rendering hints, A/B flags, payment config, CAPTCHA keys, etc.) are omitted even when present in the real blob. If you need a field that isn't typed, open an issue or add it directly.\n","readmeFilename":"README.md"}