Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/patrickkfkan/bandcamp-fetch

Library for scraping Bandcamp content.
https://github.com/patrickkfkan/bandcamp-fetch

api bandcamp scraper

Last synced: 4 days ago
JSON representation

Library for scraping Bandcamp content.

Awesome Lists containing this project

README

        

Buy Me a Coffee at ko-fi.com

# bandcamp-fetch

Library for scraping Bandcamp content.

Coverage:

- Bandcamp Discover
- Album and track info
- Artists, labels, label artists, discography
- Articles (aka. Bandcamp Daily)
- Shows
- Tags, including releases and highlights by tag
- Search
- Fan collections, wishlists and following artists / genres

Packaged as ESM + CJS hybrid module with typings.

# Installation

```
npm i bandcamp-fetch --save
```

# Usage

```
import bcfetch from 'bandcamp-fetch';

const results = await bcfetch.discovery.discover(...);
```

### User Sessions

When you sign into Bandcamp, a "Cookie" is created to identify the user session. You can pass the value of this cookie to the library and gain access to your private collection as well as high-quality MP3 streams of purchased media:

```
bcfetch.setCookie('xxxx');

const album = await bcfetch.album.getInfo({
albumUrl: '...' // URL of purchased album
});

// Normal quality stream
const streamUrl = album.tracks[0].streamUrl;

// High quality stream - only available when `cookie` is set
const streamUrlHQ = album.tracks[0].streamUrlHQ;
```

Guide: [How to obtain Cookie](https://github.com/patrickkfkan/bandcamp-fetch/wiki/How-to-obtain-Cookie)

### `BandcampFetch`

The library exports a default [BandcampFetch](./docs/api/classes/BandcampFetch.md) instance mainly for backward compatibility with previous versions:

```
// Imports the default `BandcampFetch` instance
import bcfetch from 'bandcamp-fetch';
```

You can also create separate instances. This is useful when you want to support multiple user sessions:

```
import { BandcampFetch } from 'bandcamp-fetch';

const bcfetch1 = new BandcampFetch({
cookie: 'xxxx' // Cookie for user session 1
});

const bcfetch2 = new BandcampFetch();
bcfetch2.setCookie('yyyy'); // Cookie for user sesion 2
```

###

# API

## Discovery API

To access the Discovery API:

```
import bcfetch from 'bandcamp-fetch';

const discovery = bcfetch.discovery;

const options = await discovery.getAvailableOptions();
const results = await discovery.discover(...);
```
**Methods:**

discover([params])

[**Example**](examples/discovery/discover.ts) ([output](examples/discovery/discover_output.txt))

Fetches albums through Bandcamp Discover.

**Params**

- `params`: ([DiscoverParams](docs/api/interfaces/DiscoverParams.md)) (*optional* and *all properties optional*)
- `genre`: (string)
- `subgenre`: (string) only valid when `genre` is set to something other than 'all'.
- `location`: (string)
- `sortBy`: (string)
- `artistRecommendationType`: (string) only valid when `sortBy` is 'rec' (artist recommended).
- `format`: (string)
- `time`: (number)
- `page`: (number)
- `albumImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md))
- `artistImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md))

To see what values can be set in `params`, call `getAvailableOptions()`.

**Returns**

Promise resolving to [DiscoverResult](docs/api/interfaces/DiscoverResult.md).

---

getAvailableOptions()

[**Example**](examples/discovery/getAvailableOptions.ts) ([output](examples/discovery/getAvailableOptions_output.txt))

Fetches Bandcamp Discover options that can be used to configure params for passing into discover().

**Returns**

Promise resolving to [DiscoverOptions](docs/api/interfaces/DiscoverOptions.md).

---

sanitizeDiscoverParams([params])

[**Example**](examples/discovery/sanitizeDiscoverParams.ts) ([output](examples/discovery/sanitizeDiscoverParams_output.txt))

Sanitizes params by setting default values for omitted properties and removing irrelevant or inapplicable ones.


Note that you don't have to call this method on params passed into discover() as they will be sanitized automatically.

**Params**

- `params`: ([DiscoverParams](docs/api/interfaces/DiscoverParams.md)) (*optional*) the discover params to sanitize.

**Returns**

Promise resolving to sanitized [DiscoverParams](docs/api/interfaces/DiscoverParams.md).

---

## Image API

To access the Image API:

```
import bcfetch, { ImageFormatFilter } from 'bandcamp-fetch';

const image = bcfetch.image;

const formats = await image.getFormats(ImageFormatFilter.Album);
```
**Methods:**

getFormats([filter])

[**Example**](examples/image/getFormats.ts) ([output](examples/image/getFormats_output.txt))

Fetches the list of image formats used in Bandcamp.

**Params**

- `filter`: ([ImageFormatFilter](docs/api/enums/ImageFormatFilter.md)) (*optional*) if specified, narrows down the result to include only formats applicable to the specified value.

**Returns**

Promise resolving to Array<[ImageFormat](docs/api/interfaces/ImageFormat.md)>.

---

getImageFormat(target, [fallbackId])

Fetches the image format that matches target. If none is found, the result will be null.

**Params**

- `target`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md))
- If target is string or number, the method finds the image format with matching name or Id (as appropriate).
- If target satisfies the [ImageFormat](docs/api/interfaces/ImageFormat.md) interface constraint, then it is returned as is.
- `fallbackId`: (number) (*optional*) if no match is found for `target`, try to obtain format with Id matching `fallbackId`.

**Returns**

Promise resolving to matching [ImageFormat](docs/api/interfaces/ImageFormat.md), or `null` if none matches `target` nor `fallbackId` (if specified).

---

## Band API

A band can be an artist or label. To access the Band API:

```
import bcfetch from 'bandcamp-fetch';

const band = bcfetch.band;

const info = await band.getInfo(...);
```

**Methods:**

getInfo(params)

[**Example**](examples/band/getInfo.ts) ([output](examples/band/getInfo_output.txt))

Fetches information about an artist or label.

**Params**

- `params`: ([BandAPIGetInfoParams](docs/api/interfaces/BandAPIGetInfoParams.md))
- `bandUrl`: (string)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `labelId`: (number) (*optional*)

The method tries to assemble the most complete set of data by scraping the following pages (returning immediately at any point the data becomes complete):

1. The page referred to by `bandUrl`
2. The 'music' page of the artist or label (`bandUrl/music`)
3. The first album or track in the artist's or label's discography

Sometimes, label information is missing for artists even when they do belong to a label. If you know the `labelId` of the label that the artist belongs to, you can specify it in `params`. This will ensure that `label` will not be `null` in the artist info. If you pass a label URL to this function, you can find the `labelId` in the result.

**Returns**

Promise resolving to [Artist](docs/api/interfaces/Artist.md) or [Label](docs/api/interfaces/Label.md).

---

getLabelArtists(params)

[**Example**](examples/band/getLabelArtists.ts) ([output](examples/band/getLabelArtists_output.txt))

Fetches the list of artists belonging to a label.

**Params**

- `params`: ([BandAPIGetLabelArtistsParams](docs/api/interfaces/BandAPIGetLabelArtistsParams.md))
- `labelUrl`: (string)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

**Returns**

Promise resolving to Array<[LabelArtist](docs/api/README.md#labelartist)>.

---

getDiscography(params)

[**Example**](examples/band/getDiscography.ts) ([output](examples/band/getDiscography_output.txt))

Fetches the list of albums and standalone tracks belonging to an artist or label.

**Params**

- `params`: ([BandAPIGetDiscographyParams](docs/api/interfaces/BandAPIGetDiscographyParams.md))
- `bandUrl`: (string)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

**Returns**

Promise resolving to Array<[Album](docs/api/interfaces/Album.md) | [Track](docs/api/interfaces/Track.md)>.

---

## Album API

To access the Album API:

```
import bcfetch from 'bandcamp-fetch';

const album = bcfetch.album;

const info = await album.getInfo(...);
```

**Methods:**

getInfo(params)

[**Example**](examples/album/getInfo.ts) ([output](examples/album/getInfo_output.txt))

Fetches info about an album.

**Params**

- `params`: ([AlbumAPIGetInfoParams](docs/api/interfaces/AlbumAPIGetInfoParams.md))
- `albumUrl`: (string)
- `albumImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `artistImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `includeRawData`: (boolean) (*optional)

**Returns**

Promise resolving to [Album](docs/api/interfaces/Album.md).

> If artist URL is not found in the scraped data, then `artist.url` will be set to the same value as `publisher.url`

---

## Track API

To access the Track API:

```
import bcfetch from 'bandcamp-fetch';

const track = bcfetch.track;

const info = await track.getInfo(...);
```

**Methods:**

getInfo(params)

[**Example**](examples/track/getInfo.ts) ([output](examples/track/getInfo_output.txt))

Fetches info about a track.

**Params**

- `params`: ([TrackAPIGetInfoParams](docs/api/interfaces/Tra))
- `trackUrl`: (string)
- `albumImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `artistImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `includeRawData`: (boolean) (*optional)

**Returns**

Promise resolving to [Track](docs/api/interfaces/Track.md).

> If artist URL is not found in the scraped data, then `artist.url` will be set to the same value as `publisher.url`

---

## Tag API

To access the Tag API:

```
import bcfetch from 'bandcamp-fetch';

const tag = bcfetch.tag;

const info = await tag.getInfo(...);
const highlights = await tag.getAlbumHighlights(...);
```

**Methods:**

getInfo(tagUrl)

[**Example**](examples/tag/getInfo.ts) ([output](examples/tag/getInfo_output.txt))

Fetches info about a tag.

**Params**

- `tagUrl`: (string)

**Returns**

Promise resolving to [Tag](docs/api/interfaces/Tag.md).

---

list()

[**Example**](examples/tag/list.ts) ([output](examples/tag/list_output.txt))

Fetches the full list of tags.

**Returns**

Promise resolving to [TagList](docs/api/interfaces/TagList.md), which groups results into `tags`(for non-location tags) and `locations` (for location tags).

---

getAlbumHighlights(params)

[**Example**](examples/tag/getAlbumHighlights.ts) ([output](examples/tag/getAlbumHighlights_output.txt))

Fetches album highlights for the tag referred to by params.tagUrl.

Albums are placed in groups. Each group corresponds to a highlight category such as 'new and notable' and 'all-time best selling'.

**Params**

- `params`: ([TagAPIGetAlbumHighlightsParams](docs/api/interfaces/TagAPIGetAlbumHighlightsParams.md))
- `tagUrl`: (string)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

**Returns**

Promise resolving to Array<[AlbumHighlightsByTag](docs/api/interfaces/AlbumHighlightsByTag.md)>.

---

getReleases(params)

[**Example**](examples/tag/getReleases.ts) ([output](examples/tag/getReleases_output.txt))

Fetches releases matching the tag referred to by params.tagUrl.

**Params**

- `params`: ([TagAPIGetReleasesParams](docs/api/interfaces/TagAPIGetReleasesParams.md))
- `tagUrl`: (string)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `useHardcodedDefaultFilters`: (boolean) (*optional*) if `true`, use hardcoded default values for filters not specified in `params.filters`. If `false` or unspecified, default filter values will be obtained by calling ``getReleasesAvailableFilters`()` (extra query means slower performance).
- `filters`: (object{ string: string | number | Array}) (*optional*)
- `page`: (number) (*optional*) 1 if omitted.

#### `params.filters`:

Properties of `params.filters` are not strictly defined. As of this documentation, the curent filters available on Bandcamp are:

- `location`: (number)
- `tags`: (Array<string>) list of tags to match, in addition to the one referred to by `params.tagUrl`.
- `sort`: (string)
- `format`: (string)

Omitted properties are populated with default values obtained from `params.tagUrl`. Possible filter values can be obtained by calling `getReleasesAvailableFilters()`. For `location` and `tag` filters, you may look up additional values not returned by `getReleasesAvailableFilters()` through `getSuggestions()` of the [Autocomplete API](#autocomplete-api).

**Returns**

Promise resolving to [ReleasesByTag](docs/api/interfaces/ReleasesByTag-1.md).

---

getReleasesAvailableFilters(tagUrl)

[**Example**](examples/tag/getReleasesAvailableFilters.ts) ([output](examples/tag/getReleasesAvailableFilters_output.txt))

Fetches the list of possible filter values for getReleases().

For `location` and `tag` filters, this method does not return an exhaustive list of values. You may use `getSuggestions()` of the [Autocomplete API](#autocomplete-api) to look up additional values.

**Params**

- `tagUrl`: (string) the URL of the tag for which filter values are to be returned.

**Returns**

Promise resolving to Array<[ReleasesByTag.Filter](docs/api/interfaces/ReleasesByTag.Filter.md)>.

---

## Show API

To access the Show API:

```
import bcfetch from 'bandcamp-fetch';

const show = bcfetch.show;

const list = await show.list(...);
```

**Methods:**

list(params)

[**Example**](examples/show/list.ts) ([output](examples/show/list_output.txt))

Fetches the full list of Bandcamp shows.

Each list entry contains basic info about a show. To obtain full details, pass its `url` to `getShow()`.

**Params**

- `params`: ([ShowAPIListParams](docs/api/interfaces/ShowAPIListParams.md)) (*optional*)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

**Returns**

Promise resolving to Array<[Show](docs/api/interfaces/Show.md)>.

---

getShow(params)

[**Example**](examples/show/getShow.ts) ([output](examples/show/getShow_output.txt))

Fetches full details about the Bandcamp show referred to by params.showUrl.

**Params**

- `params`: ([ShowAPIGetShowParams](docs/api/interfaces/ShowAPIGetShowParams.md))
- `showUrl`: (string)
- `albumImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `artistImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `showImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

**Returns**

Promise resolving to [Show](docs/api/interfaces/Show.md).

---

## Article API

To access the Article API:

```
import bcfetch from 'bandcamp-fetch';

const article = bcfetch.article;

const list = await article.list(...);
```

**Methods:**

getCategories()

[**Example**](examples/article/getCategories.ts) ([output](examples/article/getCategories_output.txt))

Fetches the list of Bandcamp Daily article categories. Categories are grouped into sections.

**Returns**

Promise resolving to Array<[ArticleCategorySection](docs/api/interfaces/ArticleCategorySection.md)>.

---

list(params)

[**Example**](examples/article/list.ts) ([output](examples/article/list_output.txt))

Fetches the list of Bandcamp Daily articles under the category specified by params.categoryUrl (or all categories if not specified).

**Params**

- `params`: ([ArticleAPIListParams](docs/api/interfaces/ArticleAPIListParams.md)) (*optional* and *all properties optional*)
- `categoryUrl`: (string)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md))
- `page`: (number)

**Returns**

Promise resolving to [ArticleList](docs/api/interfaces/ArticleList.md).

---

getArticle(params)

[**Example**](examples/article/getArticle.ts) ([output](examples/article/getArticle_output.txt))

Fetches the contents of the Bandcamp Daily article at params.articleUrl.

**Params**

- `params`: ([ArticleAPIGetArticleParams](docs/api/interfaces/ArticleAPIGetArticleParams.md))
- `articleUrl`: (string)
- `albumImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `artistImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `includeRawData`: (boolean) (*optional*)

**Returns**

Promise resolving to [Article](docs/api/interfaces/Article.md).

---

## Fan API

To access the Fan API:

```
import bcfetch from 'bandcamp-fetch';

const fan = bcfetch.fan;

const info = await fan.getInfo(...);
const collection = await fan.getCollection(...);
```

**Methods:**

getInfo(params)

[**Example**](examples/fan/getInfo.ts) ([output](examples/fan/getInfo_output.txt))

Fetches info about a fan.

**Params**

- `params`: ([FanAPIGetInfoParams](docs/api/interfaces/FanAPIGetInfoParams.md))
- `username`: (string) (*optional*)
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

If `username` is not specified, result will be obtained for the user of the [session](#user-sessions) tied to the `BandcampFetch` instance.

**Returns**

Promise resolving to [Fan](docs/api/interfaces/Fan.md).

---

getCollection(params)

[**Example**](examples/fan/getCollection.ts) ([output](examples/fan/getCollection_output.txt))

Fetches the list of albums and tracks in a fan's collection.

**Params**

- `params`: ([FanAPIGetItemsParams](docs/api/interfaces/FanAPIGetItemsParams.md))
- `target`: (string | [FanItemsContinuation](docs/api/interfaces/FanItemsContinuation.md)) (*optional*) if username (string) is specified, returns the first batch of items in the collection. To obtain further items, call the method again but, instead of username, pass `continuation` from the result of the first call. If there are no further items available, `continuation` will be `null`.
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

If `target` is not specified, result will be obtained for the user of the [session](#user-sessions) tied to the `BandcampFetch` instance.

**Returns**

Promise resolving to ([FanPageItemsResult](docs/api/interfaces/FanPageItemsResult.md) | [FanContinuationItemsResult](docs/api/interfaces/FanContinuationItemsResult.md))<[Album](docs/api/interfaces/Album.md) | [Track](docs/api/interfaces/Track.md)>.

---

getWishlist(params)

[**Example**](examples/fan/getWishlist.ts) ([output](examples/fan/getWishlist_output.txt))

Fetches the list of albums and tracks added to a fan's wishlist.

**Params**

- `params`: ([FanAPIGetItemsParams](docs/api/interfaces/FanAPIGetItemsParams.md))
- `target`: (string | [FanItemsContinuation](docs/api/interfaces/FanItemsContinuation.md)) (*optional*) if username (string) is specified, returns the first batch of items in the wishlist. To obtain further items, call the method again but, instead of username, pass `continuation` from the result of the first call. If there are no further items available, `continuation` will be `null`.
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

If `target` is not specified, result will be obtained for the user of the [session](#user-sessions) tied to the `BandcampFetch` instance.

**Returns**

Promise resolving to ([FanPageItemsResult](docs/api/interfaces/FanPageItemsResult.md) | [FanContinuationItemsResult](docs/api/interfaces/FanContinuationItemsResult.md))<[Album](docs/api/interfaces/Album.md) | [Track](docs/api/interfaces/Track.md)>.

---

getFollowingArtistsAndLabels(params)

[**Example**](examples/fan/getFollowingArtistsAndLabels.ts) ([output](examples/fan/getFollowingArtistsAndLabels_output.txt))

Fetches the list of artists and labels followed by a fan.

**Params**

- `params`: ([FanAPIGetItemsParams](docs/api/interfaces/FanAPIGetItemsParams.md))
- `target`: (string | [FanItemsContinuation](docs/api/interfaces/FanItemsContinuation.md)) (*optional*) if username (string) is specified, returns the first batch of artists and labels. To obtain further items, call the method again but, instead of username, pass `continuation` from the result of the first call. If there are no further items available, `continuation` will be `null`.
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

If `target` is not specified, result will be obtained for the user of the [session](#user-sessions) tied to the `BandcampFetch` instance.

**Returns**

Promise resolving to ([FanPageItemsResult](docs/api/interfaces/FanPageItemsResult.md) | [FanContinuationItemsResult](docs/api/interfaces/FanContinuationItemsResult.md))<[UserKind](docs/api/interfaces/UserKind.md)>.

---

getFollowingGenres(params)

[**Example**](examples/fan/getFollowingGenres.ts) ([output](examples/fan/getFollowingGenres_output.txt))

Fetches the list of genres followed by a fan.

Each genre is actually a Bandcamp tag, so you can, for example, pass its `url` to `getReleases()` of the [Tag API](#tag-api).

**Params**

- `params`: ([FanAPIGetItemsParams](docs/api/interfaces/FanAPIGetItemsParams.md))
- `target`: (string | [FanItemsContinuation](docs/api/interfaces/FanItemsContinuation.md)) (*optional*) if username (string) is specified, returns the first batch of genres. To obtain further items, call the method again but, instead of username, pass `continuation` from the result of the first call. If there are no further items available, `continuation` will be `null`.
- `imageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

If `target` is not specified, result will be obtained for the user of the [session](#user-sessions) tied to the `BandcampFetch` instance.

**Returns**

Promise resolving to ([FanPageItemsResult](docs/api/interfaces/FanPageItemsResult.md) | [FanContinuationItemsResult](docs/api/interfaces/FanContinuationItemsResult.md))<[Tag](docs/api/interfaces/Tag.md)>.

---

## Search API

To access the Search API:

```
import bcfetch from 'bandcamp-fetch';

const search = bcfetch.search;

const albums = await search.albums(...);
const all = await search.all(...);
```

**Methods:**

all(params) / artistsAndLabels(params) / albums(params) / tracks(params) / fans(params)

[**Example**](examples/search/search.ts) ([output](examples/search/search_output.txt))

- `all(params)`: search all item types
- `artistsAndLabels(params)`: search artists and labels
- `albums(params)`: search albums
- `tracks(params)`: search tracks
- `fans(params)`: search fans

**Params**

- `params`: ([SearchAPISearchParams](docs/api/interfaces/SearchAPISearchParams.md))
- `query`: (string)
- `page`: (number) (*optional*) 1 if omitted
- `albumImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)
- `artistImageFormat`: (string | number | [ImageFormat](docs/api/interfaces/ImageFormat.md)) (*optional*)

**Returns**

Promise resolving to [SearchResults](docs/api/interfaces/SearchResults.md)<`T`>, where `T` depends on the item type being searched and can be one of:
- Artist ([SearchResultArtist](docs/api/interfaces/SearchResultArtist.md))
- Label ([SearchResultLabel](docs/api/interfaces/SearchResultLabel.md))
- Album ([SearchResultAlbum](docs/api/interfaces/SearchResultAlbum.md))
- Track ([SearchResultTrack](docs/api/interfaces/SearchResultTrack.md))
- Fan ([SearchResultFan](docs/api/interfaces/SearchResultFan.md))

You can use the `type` property to determine the search result item type.

---

## Autocomplete API

To access the Autocomplete API:

```
import bcfetch from 'bandcamp-fetch';

const autocomplete = bcfetch.autocomplete;

const suggestions = await autocomplete.getSuggestions(...);
```

**Methods:**

getSuggestions(params)

[**Example**](examples/autocomplete/getSuggestions.ts) ([output](examples/autocomplete/getSuggestions_output.txt))

Fetches autocomplete suggestions for tags and locations, based on partial and full matches against `params.query`.

The `value` property of returned suggestions can be used to set the `location` or `tags` property (as the case may be) of `params.filters` that is passed into `getReleases()` of the [Tag API](#tag-api).

**Params**

- `params`: ([AutocompleteAPIGetSuggestionsParams](docs/api/interfaces/AutocompleteAPIGetSuggestionsParams.md))
- `query`: (string)
- `itemType`: ([AutocompleteItemType](docs/api/enums/AutocompleteItemType.md)) 'Tag' or 'Location'
- limit: (number) (*optional*) the maximum number of results to return; 5 if omitted.

**Returns**

- If `params.itemType` is `AutocompleteItemType.Tag`, a Promise resolving to Array<[AutocompleteTag](docs/api/interfaces/AutoCompleteTag.md)>.
- If `params.itemType` is `AutocompleteItemType.Location`, a Promise resolving to Array<[AutocompleteLocation](docs/api/interfaces/AutocompleteLocation.md)>.

---

## Stream API

Stream URLs returned by Bandcamp can sometimes be invalid (perhaps expired). Before playing a stream, you are recommended to test its URL and refresh it if necessary with the Stream API.

To access the Stream API:

```
import bcfetch from 'bandcamp-fetch';

const stream = bcfetch.stream;

// Test a stream URL
const streamURL = '...';
const testResult = await stream.test(streamUrl);

if (!testResult.ok) {
const refreshedStreamURL = await stream.refresh(streamURL);
}
```

**Methods:**

test(url)

[**Example**](examples/stream/testAndRefresh.ts) ([output](examples/stream/testAndRefresh_output.txt))

Tests validity of the stream given by `url`.

**Params**

- `url`: (string) the URL of the stream to test

**Returns**

Promise resolving to [StreamTestResult](docs/api/interfaces/StreamTestResult.md):
- `ok`: (boolean) whether the stream is valid
- `status`: (number) the HTTP response status code returned by the test

---

refresh(url)

[**Example**](examples/stream/testAndRefresh.ts) ([output](examples/stream/testAndRefresh_output.txt))

Refreshes a stream URL.

**Params**

- `url`: (string) the URL of the stream to refresh

**Returns**

Promise resolving to the refreshed URL of the stream or `null` if no valid result was obtained.

---

# Rate Limiting

Each `BandcampFetch` instance comes with a rate limiter, which limits the number of requests made within a specific time period.

Rate limiting is useful when you need to make a large number of queries and don't want to run the risk of getting rejected by the server for making too many requests within a short time interval. If you get a '429 Too Many Requests' error, then you should consider using the rate limiter.

Each API has a limiter-enabled counterpart which you can access in the following manner:

```
import bcfetch from 'bandcamp-fetch';

// Album API - no limiter enabled
const albumAPI = bcfetch.album;

// Album API - limiter enabled
const limiterAlbumAPI = bcfetch.limiter.album;
```

[**Example**](examples/limiter/limiter.ts) ([output](examples/limiter/limiter_output.txt))

The library uses [Bottleneck](https://www.npmjs.com/package/bottleneck) for rate limiting. You can configure the rate limiter like this:

```
bcfetch.limiter.updateSettings({
maxConcurrent: 10, // default: 5
minTime: 100 // default: 200
});
```

`updateSettings()` is just a passthrough function to Bottleneck. Check the [Bottleneck doc](https://www.npmjs.com/package/bottleneck#docs) for the list of options you can set.

# Cache

Each `BandcampFetch` instance has an in-memory cache for two types of data (as defined by [CacheDataType](docs/api/enums/CacheDataType.md)):

1. `CacheDataType.Page` - pages fetched during scraping
2. `CacheDataType.Constants` - image formats and discover options

To access the cache:

```
import bcfetch, { CacheDataType } from 'bandcamp-fetch';

const cache = bcfetch.cache;

cache.setTTL(CacheDataType.Page, 500);
```

**Methods:**

setTTL(type, ttl)

Sets the expiry time, in seconds, of cache entries for the given data type.

**Params**

- `type`: ([CacheDataType](docs/api/enums/CacheDataType.md))
- `TTL`: (number) expiry time in seconds (default: 300 for `CacheDataType.Page` and 3600 for `CacheDataType.Constants`)

---

setMaxPages(maxPages)

Sets the maximum number of pages that can be stored in the cache. A negative value means unlimited. Default: 10.

**Params**

- `maxPages`: (number)

---

clear([type])

Clears the cache entries for the specified data type (or all entries if no data type specified).

**Params**

- `type`: ([CacheDataType](docs/api/enums/CacheDataType.md)) (*optional*)

---

# Changelog

1.2.1
- Fix `duration` not returned in result of `TrackAPI::getInfo()` ([#7](https://github.com/patrickkfkan/bandcamp-fetch/issues/7))

1.2.0
- Add Stream API for testing and refreshing stream URLs

1.1.1
- Fix exports

1.1.0
- Add support for user sessions through cookies. This means you can access your private collection and high-quality MP3 streams of purchased media.
- Add ability to create multiple `BandcampFetch` instances

1.0.2
- Improve parsing of album track info

1.0.1
- Fix limiter throwing private access errors

1.0.0 (breaking changes!)
- Move to TypeScript
- Package as ESM + CJS hybrid module
- Restructure API
- Remove `safe-eval` dependency

0.3.1-b.1
- Add `getFanCollection()` function

0.3.0-b.1
- Add fan functions

0.2.2-b.1
- Add `itemType` option to search params

0.2.1-b.20211020b
- Fix URL sometimes null in result of `getArtistOrLabelInfo()`

0.2.1-b.20211020
- Improve data fetching in `getArtistOrLabelInfo()`

0.2.0-b.20211020
- Adapt to Bandcamp changes since last version
- Add `publisher` and `label` to data fetched by `getAlbumInfo()` and `getTrackInfo()`
- Add `labelId` to data fetched by `getArtistOrLabelInfo(labelUrl)`
- Add `labelId` option to `getArtistOrLabelInfo()` for artist URLs

...(no changelog for earlier versions due to laziness)

# License

MIT