Add support for browsing and looking up collections (#12)

Fixes #6.
This commit is contained in:
Brian Beck 2016-12-11 20:03:05 -08:00 committed by GitHub
parent 0600c2026b
commit ef8e67c8a6
19 changed files with 1596 additions and 30 deletions

View file

@ -301,10 +301,46 @@ type BrowseQuery {
# The MBID of a release group to which the entity is linked.
releaseGroup: MBID
# The MBID of a work to which the artist is linked.
# The MBID of a work to which the entity is linked.
work: MBID
): ArtistConnection
# Browse collection entities linked to the given arguments.
collections(
after: String
first: Int
# The MBID of an area to which the entity is linked.
area: MBID
# The MBID of an artist to which the entity is linked.
artist: MBID
# The username of the editor who created the collection.
editor: String
# The MBID of an event to which the entity is linked.
event: MBID
# The MBID of a label to which the entity is linked.
label: MBID
# The MBID of a place to which the entity is linked.
place: MBID
# The MBID of a recording to which the entity is linked.
recording: MBID
# The MBID of a release to which the entity is linked.
release: MBID
# The MBID of a release group to which the entity is linked.
releaseGroup: MBID
# The MBID of a work to which the entity is linked.
work: MBID
): CollectionConnection
# Browse event entities linked to the given arguments.
events(
after: String
@ -319,7 +355,7 @@ type BrowseQuery {
# The MBID of a collection in which the entity is found.
collection: MBID
# The MBID of a place to which the event is linked.
# The MBID of a place to which the entity is linked.
place: MBID
): EventConnection
@ -383,7 +419,7 @@ type BrowseQuery {
# The MBID of a collection in which the entity is found.
collection: MBID
# The MBID of a label to which the release is linked.
# The MBID of a label to which the entity is linked.
label: MBID
# The MBID of a track that is included in the release.
@ -445,6 +481,100 @@ type BrowseQuery {
): WorkConnection
}
# [Collections](https://musicbrainz.org/doc/Collections) are
# lists of entities that users can create.
type Collection implements Node, Entity {
# The ID of an object
id: ID!
# The MBID of the entity.
mbid: MBID!
# The official name of the entity.
name: String
# The username of the editor who created the collection.
editor: String!
# The type of entity listed in the collection.
entityType: String!
# The type of collection.
type: String
# The MBID associated with the value of the `type`
# field.
typeID: MBID
# A list of areas linked to this entity.
areas(after: String, first: Int): AreaConnection
# A list of artists linked to this entity.
artists(after: String, first: Int): ArtistConnection
# A list of events linked to this entity.
events(after: String, first: Int): EventConnection
# A list of labels linked to this entity.
labels(after: String, first: Int): LabelConnection
# A list of places linked to this entity.
places(after: String, first: Int): PlaceConnection
# A list of recordings linked to this entity.
recordings(after: String, first: Int): RecordingConnection
# A list of releases linked to this entity.
releases(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
# Filter by one or more release statuses.
status: [ReleaseStatus]
): ReleaseConnection
# A list of release groups linked to this entity.
releaseGroups(
after: String
first: Int
# Filter by one or more release group types.
type: [ReleaseGroupType]
): ReleaseGroupConnection
# A list of works linked to this entity.
works(after: String, first: Int): WorkConnection
}
# A connection to a list of items.
type CollectionConnection {
# Information to aid in pagination.
pageInfo: PageInfo!
# A list of edges.
edges: [CollectionEdge]
# A count of the total number of items in this connection,
# ignoring pagination.
totalCount: Int
}
# An edge in a connection.
type CollectionEdge {
# The item at the end of the edge
node: Collection
# A cursor for use in pagination
cursor: String!
# The relevancy score (0100) assigned by the search engine, if
# these results were found through a search.
score: Int
}
# Geographic coordinates described with latitude and longitude.
type Coordinates {
# The northsouth position of a point on the Earths surface.
@ -475,6 +605,9 @@ scalar Degrees
# offsets and hence the same disc ID.
scalar DiscID
# A length of time, in milliseconds.
scalar Duration
# An entity in the MusicBrainz schema.
interface Entity {
# The MBID of the entity.
@ -775,6 +908,12 @@ type LookupQuery {
mbid: MBID!
): Artist
# Look up a specific collection by its MBID.
collection(
# The MBID of the entity.
mbid: MBID!
): Collection
# Look up a specific event by its MBID.
event(
# The MBID of the entity.
@ -1002,7 +1141,7 @@ type Recording implements Node, Entity {
# An approximation to the length of the recording, calculated
# from the lengths of the tracks using it.
length: Int
length: Duration
# Whether this is a video recording.
video: Boolean

View file

@ -14,6 +14,9 @@ You may also be interested in reading the [schema in GraphQL syntax](schema.md).
<li>[ArtistCredit](#artistcredit)</li>
<li>[ArtistEdge](#artistedge)</li>
<li>[BrowseQuery](#browsequery)</li>
<li>[Collection](#collection)</li>
<li>[CollectionConnection](#collectionconnection)</li>
<li>[CollectionEdge](#collectionedge)</li>
<li>[Coordinates](#coordinates)</li>
<li>[Event](#event)</li>
<li>[EventConnection](#eventconnection)</li>
@ -66,6 +69,7 @@ You may also be interested in reading the [schema in GraphQL syntax](schema.md).
<li>[Date](#date)</li>
<li>[Degrees](#degrees)</li>
<li>[DiscID](#discid)</li>
<li>[Duration](#duration)</li>
<li>[ID](#id)</li>
<li>[IPI](#ipi)</li>
<li>[ISNI](#isni)</li>
@ -897,7 +901,74 @@ entity.
<tr>
<td align="right" valign="top">work</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a work to which the artist is linked.</td>
<td>The MBID of a work to which the entity is linked.</td>
</tr>
<tr>
<td valign="top"><strong>collections</strong> </td>
<td valign="top"><a href="#collectionconnection">CollectionConnection</a></td>
<td>
Browse collection entities linked to the given arguments.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">area</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of an area to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">artist</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of an artist to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">editor</td>
<td valign="top"><a href="#string">String</a></td>
<td>The username of the editor who created the collection.</td>
</tr>
<tr>
<td align="right" valign="top">event</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of an event to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">label</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a label to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">place</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a place to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">recording</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a recording to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">release</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a release to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">releaseGroup</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a release group to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">work</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a work to which the entity is linked.</td>
</tr>
<tr>
<td valign="top"><strong>events</strong> </td>
@ -934,7 +1005,7 @@ entity.
<tr>
<td align="right" valign="top">place</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a place to which the event is linked.</td>
<td>The MBID of a place to which the entity is linked.</td>
</tr>
<tr>
<td valign="top"><strong>labels</strong> </td>
@ -1068,7 +1139,7 @@ entity.
<tr>
<td align="right" valign="top">label</td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>The MBID of a label to which the release is linked.</td>
<td>The MBID of a label to which the entity is linked.</td>
</tr>
<tr>
<td align="right" valign="top">track</td>
@ -1179,6 +1250,308 @@ associated with the release.</td>
</tr>
</tbody></table>
### Collection
[Collections](https://musicbrainz.org/doc/Collections) are
lists of entities that users can create.
<table><thead>
<tr>
<th align="left">Field&nbsp;/&nbsp;Argument</th>
<th align="left">Type</th>
<th align="left">Description</th>
</tr>
</thead><tbody>
<tr>
<td valign="top"><strong>id</strong> </td>
<td valign="top"><a href="#id">ID</a>!</td>
<td>
The ID of an object
</td>
</tr>
<tr>
<td valign="top"><strong>mbid</strong> </td>
<td valign="top"><a href="#mbid">MBID</a>!</td>
<td>
The MBID of the entity.
</td>
</tr>
<tr>
<td valign="top"><strong>name</strong> </td>
<td valign="top"><a href="#string">String</a></td>
<td>
The official name of the entity.
</td>
</tr>
<tr>
<td valign="top"><strong>editor</strong> </td>
<td valign="top"><a href="#string">String</a>!</td>
<td>
The username of the editor who created the collection.
</td>
</tr>
<tr>
<td valign="top"><strong>entityType</strong> </td>
<td valign="top"><a href="#string">String</a>!</td>
<td>
The type of entity listed in the collection.
</td>
</tr>
<tr>
<td valign="top"><strong>type</strong> </td>
<td valign="top"><a href="#string">String</a></td>
<td>
The type of collection.
</td>
</tr>
<tr>
<td valign="top"><strong>typeID</strong> </td>
<td valign="top"><a href="#mbid">MBID</a></td>
<td>
The MBID associated with the value of the <code>type</code>
field.
</td>
</tr>
<tr>
<td valign="top"><strong>areas</strong> </td>
<td valign="top"><a href="#areaconnection">AreaConnection</a></td>
<td>
A list of areas linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td valign="top"><strong>artists</strong> </td>
<td valign="top"><a href="#artistconnection">ArtistConnection</a></td>
<td>
A list of artists linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td valign="top"><strong>events</strong> </td>
<td valign="top"><a href="#eventconnection">EventConnection</a></td>
<td>
A list of events linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td valign="top"><strong>labels</strong> </td>
<td valign="top"><a href="#labelconnection">LabelConnection</a></td>
<td>
A list of labels linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td valign="top"><strong>places</strong> </td>
<td valign="top"><a href="#placeconnection">PlaceConnection</a></td>
<td>
A list of places linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td valign="top"><strong>recordings</strong> </td>
<td valign="top"><a href="#recordingconnection">RecordingConnection</a></td>
<td>
A list of recordings linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td valign="top"><strong>releases</strong> </td>
<td valign="top"><a href="#releaseconnection">ReleaseConnection</a></td>
<td>
A list of releases linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">type</td>
<td valign="top">[<a href="#releasegrouptype">ReleaseGroupType</a>]</td>
<td>Filter by one or more release group types.</td>
</tr>
<tr>
<td align="right" valign="top">status</td>
<td valign="top">[<a href="#releasestatus">ReleaseStatus</a>]</td>
<td>Filter by one or more release statuses.</td>
</tr>
<tr>
<td valign="top"><strong>releaseGroups</strong> </td>
<td valign="top"><a href="#releasegroupconnection">ReleaseGroupConnection</a></td>
<td>
A list of release groups linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">type</td>
<td valign="top">[<a href="#releasegrouptype">ReleaseGroupType</a>]</td>
<td>Filter by one or more release group types.</td>
</tr>
<tr>
<td valign="top"><strong>works</strong> </td>
<td valign="top"><a href="#workconnection">WorkConnection</a></td>
<td>
A list of works linked to this entity.
</td>
</tr>
<tr>
<td align="right" valign="top">after</td>
<td valign="top"><a href="#string">String</a></td>
<td></td>
</tr>
<tr>
<td align="right" valign="top">first</td>
<td valign="top"><a href="#int">Int</a></td>
<td></td>
</tr>
</tbody></table>
### CollectionConnection
A connection to a list of items.
<table><thead>
<tr>
<th align="left">Field&nbsp;/&nbsp;Argument</th>
<th align="left">Type</th>
<th align="left">Description</th>
</tr>
</thead><tbody>
<tr>
<td valign="top"><strong>pageInfo</strong> </td>
<td valign="top"><a href="#pageinfo">PageInfo</a>!</td>
<td>
Information to aid in pagination.
</td>
</tr>
<tr>
<td valign="top"><strong>edges</strong> </td>
<td valign="top">[<a href="#collectionedge">CollectionEdge</a>]</td>
<td>
A list of edges.
</td>
</tr>
<tr>
<td valign="top"><strong>totalCount</strong> </td>
<td valign="top"><a href="#int">Int</a></td>
<td>
A count of the total number of items in this connection,
ignoring pagination.
</td>
</tr>
</tbody></table>
### CollectionEdge
An edge in a connection.
<table><thead>
<tr>
<th align="left">Field&nbsp;/&nbsp;Argument</th>
<th align="left">Type</th>
<th align="left">Description</th>
</tr>
</thead><tbody>
<tr>
<td valign="top"><strong>node</strong> </td>
<td valign="top"><a href="#collection">Collection</a></td>
<td>
The item at the end of the edge
</td>
</tr>
<tr>
<td valign="top"><strong>cursor</strong> </td>
<td valign="top"><a href="#string">String</a>!</td>
<td>
A cursor for use in pagination
</td>
</tr>
<tr>
<td valign="top"><strong>score</strong> </td>
<td valign="top"><a href="#int">Int</a></td>
<td>
The relevancy score (0100) assigned by the search engine, if
these results were found through a search.
</td>
</tr>
</tbody></table>
### Coordinates
Geographic coordinates described with latitude and longitude.
@ -1872,6 +2245,18 @@ A lookup of an individual MusicBrainz entity by its MBID.
<td valign="top"><a href="#mbid">MBID</a>!</td>
<td>The MBID of the entity.</td>
</tr>
<tr>
<td valign="top"><strong>collection</strong> </td>
<td valign="top"><a href="#collection">Collection</a></td>
<td>
Look up a specific collection by its MBID.
</td>
</tr>
<tr>
<td align="right" valign="top">mbid</td>
<td valign="top"><a href="#mbid">MBID</a>!</td>
<td>The MBID of the entity.</td>
</tr>
<tr>
<td valign="top"><strong>event</strong> </td>
<td valign="top"><a href="#event">Event</a></td>
@ -2336,7 +2721,7 @@ and will be removed in a major release in the future. Use the equivalent
</tr>
<tr>
<td valign="top"><strong>length</strong> </td>
<td valign="top"><a href="#int">Int</a></td>
<td valign="top"><a href="#duration">Duration</a></td>
<td>
An approximation to the length of the recording, calculated
from the lengths of the tracks using it.
@ -4760,6 +5145,10 @@ hence different disc IDs.
Conversely, two different CDs may happen to have exactly the same set of frame
offsets and hence the same disc ID.
### Duration
A length of time, in milliseconds.
### ID
The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.

View file

@ -140,6 +140,33 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "collection",
"description": "Look up a specific collection by its MBID.",
"args": [
{
"name": "mbid",
"description": "The MBID of the entity.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "Collection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "event",
"description": "Look up a specific event by its MBID.",
@ -863,6 +890,11 @@
"name": "Place",
"ofType": null
},
{
"kind": "OBJECT",
"name": "Collection",
"ofType": null
},
{
"kind": "OBJECT",
"name": "Instrument",
@ -961,6 +993,11 @@
"name": "Place",
"ofType": null
},
{
"kind": "OBJECT",
"name": "Collection",
"ofType": null
},
{
"kind": "OBJECT",
"name": "Instrument",
@ -2053,7 +2090,7 @@
"args": [],
"type": {
"kind": "SCALAR",
"name": "Int",
"name": "Duration",
"ofType": null
},
"isDeprecated": false,
@ -2284,6 +2321,16 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "Duration",
"description": "A length of time, in milliseconds.",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "ReleaseGroupType",
@ -6332,6 +6379,573 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "Collection",
"description": "[Collections](https://musicbrainz.org/doc/Collections) are\nlists of entities that users can create.",
"fields": [
{
"name": "id",
"description": "The ID of an object",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "mbid",
"description": "The MBID of the entity.",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "name",
"description": "The official name of the entity.",
"args": [],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "editor",
"description": "The username of the editor who created the collection.",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "entityType",
"description": "The type of entity listed in the collection.",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "type",
"description": "The type of collection.",
"args": [],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "typeID",
"description": "The MBID associated with the value of the `type`\nfield.",
"args": [],
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "areas",
"description": "A list of areas linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "AreaConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "artists",
"description": "A list of artists linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "ArtistConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "events",
"description": "A list of events linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "EventConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "labels",
"description": "A list of labels linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "LabelConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "places",
"description": "A list of places linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "PlaceConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "recordings",
"description": "A list of recordings linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "RecordingConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "releases",
"description": "A list of releases linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "type",
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "ReleaseGroupType",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "status",
"description": "Filter by one or more release statuses.",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "ReleaseStatus",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "ReleaseConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "releaseGroups",
"description": "A list of release groups linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "type",
"description": "Filter by one or more release group types.",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "ReleaseGroupType",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "ReleaseGroupConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "works",
"description": "A list of works linked to this entity.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "WorkConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
{
"kind": "INTERFACE",
"name": "Node",
"ofType": null
},
{
"kind": "INTERFACE",
"name": "Entity",
"ofType": null
}
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AreaConnection",
"description": "A connection to a list of items.",
"fields": [
{
"name": "pageInfo",
"description": "Information to aid in pagination.",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "PageInfo",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "edges",
"description": "A list of edges.",
"args": [],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AreaEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "totalCount",
"description": "A count of the total number of items in this connection,\nignoring pagination.",
"args": [],
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AreaEdge",
"description": "An edge in a connection.",
"fields": [
{
"name": "node",
"description": "The item at the end of the edge",
"args": [],
"type": {
"kind": "OBJECT",
"name": "Area",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "cursor",
"description": "A cursor for use in pagination",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "score",
"description": "The relevancy score (0100) assigned by the search engine, if\nthese results were found through a search.",
"args": [],
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "Instrument",
@ -6870,7 +7484,7 @@
},
{
"name": "work",
"description": "The MBID of a work to which the artist is linked.",
"description": "The MBID of a work to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
@ -6887,6 +7501,139 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "collections",
"description": "Browse collection entities linked to the given arguments.",
"args": [
{
"name": "after",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "area",
"description": "The MBID of an area to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "artist",
"description": "The MBID of an artist to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "editor",
"description": "The username of the editor who created the collection.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "event",
"description": "The MBID of an event to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "label",
"description": "The MBID of a label to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "place",
"description": "The MBID of a place to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "recording",
"description": "The MBID of a recording to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "release",
"description": "The MBID of a release to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "releaseGroup",
"description": "The MBID of a release group to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
},
{
"name": "work",
"description": "The MBID of a work to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "CollectionConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "events",
"description": "Browse event entities linked to the given arguments.",
@ -6943,7 +7690,7 @@
},
{
"name": "place",
"description": "The MBID of a place to which the event is linked.",
"description": "The MBID of a place to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
@ -7205,7 +7952,7 @@
},
{
"name": "label",
"description": "The MBID of a label to which the release is linked.",
"description": "The MBID of a label to which the entity is linked.",
"type": {
"kind": "SCALAR",
"name": "MBID",
@ -7448,7 +8195,7 @@
},
{
"kind": "OBJECT",
"name": "AreaConnection",
"name": "CollectionConnection",
"description": "A connection to a list of items.",
"fields": [
{
@ -7476,7 +8223,7 @@
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AreaEdge",
"name": "CollectionEdge",
"ofType": null
}
},
@ -7503,7 +8250,7 @@
},
{
"kind": "OBJECT",
"name": "AreaEdge",
"name": "CollectionEdge",
"description": "An edge in a connection.",
"fields": [
{
@ -7512,7 +8259,7 @@
"args": [],
"type": {
"kind": "OBJECT",
"name": "Area",
"name": "Collection",
"ofType": null
},
"isDeprecated": false,

View file

@ -1,10 +1,11 @@
import { GraphQLObjectType } from 'graphql'
import { GraphQLObjectType, GraphQLString } from 'graphql'
import { forwardConnectionArgs } from 'graphql-relay'
import { resolveBrowse } from '../resolvers'
import {
MBID,
AreaConnection,
ArtistConnection,
CollectionConnection,
EventConnection,
DiscID,
ISRC,
@ -30,6 +31,18 @@ const collection = {
type: MBID,
description: 'The MBID of a collection in which the entity is found.'
}
const event = {
type: MBID,
description: 'The MBID of an event to which the entity is linked.'
}
const label = {
type: MBID,
description: 'The MBID of a label to which the entity is linked.'
}
const place = {
type: MBID,
description: 'The MBID of a place to which the entity is linked.'
}
const recording = {
type: MBID,
description: 'The MBID of a recording to which the entity is linked.'
@ -42,6 +55,10 @@ const releaseGroup = {
type: MBID,
description: 'The MBID of a release group to which the entity is linked.'
}
const work = {
type: MBID,
description: 'The MBID of a work to which the entity is linked.'
}
function createBrowseField (connectionType, args) {
const typeName = toWords(connectionType.name.slice(0, -10))
@ -70,19 +87,28 @@ entity.`,
recording,
release,
releaseGroup,
work: {
type: MBID,
description: 'The MBID of a work to which the artist is linked.'
}
work
}),
collections: createBrowseField(CollectionConnection, {
area,
artist,
editor: {
type: GraphQLString,
description: 'The username of the editor who created the collection.'
},
event,
label,
place,
recording,
release,
releaseGroup,
work
}),
events: createBrowseField(EventConnection, {
area,
artist,
collection,
place: {
type: MBID,
description: 'The MBID of a place to which the event is linked.'
}
place
}),
labels: createBrowseField(LabelConnection, {
area,
@ -107,10 +133,7 @@ entity.`,
area,
artist,
collection,
label: {
type: MBID,
description: 'The MBID of a label to which the release is linked.'
},
label,
track: {
type: MBID,
description: 'The MBID of a track that is included in the release.'

View file

@ -4,6 +4,7 @@ import { mbid, toWords } from '../types/helpers'
import {
Area,
Artist,
Collection,
Event,
Instrument,
Label,
@ -34,6 +35,7 @@ export const LookupQuery = new GraphQLObjectType({
fields: {
area: createLookupField(Area),
artist: createLookupField(Artist),
collection: createLookupField(Collection),
event: createLookupField(Event),
instrument: createLookupField(Instrument),
label: createLookupField(Label),

60
src/types/collection.js Normal file
View file

@ -0,0 +1,60 @@
import {
GraphQLObjectType,
GraphQLNonNull,
GraphQLString
} from 'graphql/type'
import Node from './node'
import Entity from './entity'
import {
id,
mbid,
name,
areas,
artists,
events,
labels,
places,
recordings,
releases,
releaseGroups,
works,
fieldWithID,
resolveHyphenated,
connectionWithExtras
} from './helpers'
const Collection = new GraphQLObjectType({
name: 'Collection',
description: `[Collections](https://musicbrainz.org/doc/Collections) are
lists of entities that users can create.`,
interfaces: () => [Node, Entity],
fields: () => ({
id,
mbid,
name,
editor: {
type: new GraphQLNonNull(GraphQLString),
description: 'The username of the editor who created the collection.'
},
entityType: {
type: new GraphQLNonNull(GraphQLString),
description: 'The type of entity listed in the collection.',
resolve: resolveHyphenated
},
...fieldWithID('type', {
description: 'The type of collection.'
}),
areas,
artists,
events,
labels,
places,
recordings,
releases,
releaseGroups,
works
})
})
export const CollectionConnection = connectionWithExtras(Collection)
export default Collection

View file

@ -18,6 +18,7 @@ import { MBID } from './scalars'
import { ReleaseGroupType, ReleaseStatus } from './enums'
import Alias from './alias'
import ArtistCredit from './artist-credit'
import { AreaConnection } from './area'
import { ArtistConnection } from './artist'
import { EventConnection } from './event'
import { LabelConnection } from './label'
@ -221,6 +222,7 @@ export const releaseStatus = {
description: 'Filter by one or more release statuses.'
}
export const areas = linkedQuery(AreaConnection)
export const artists = linkedQuery(ArtistConnection)
export const events = linkedQuery(EventConnection)
export const labels = linkedQuery(LabelConnection)

View file

@ -4,6 +4,7 @@ export { default as Node } from './node'
export { default as Entity, EntityConnection } from './entity'
export { default as Area, AreaConnection } from './area'
export { default as Artist, ArtistConnection } from './artist'
export { default as Collection, CollectionConnection } from './collection'
export { default as Event, EventConnection } from './event'
export { default as Instrument, InstrumentConnection } from './instrument'
export { default as Label, LabelConnection } from './label'

View file

@ -0,0 +1 @@
{"editor":"offbeatadam","type-id":"d94659b2-4ce5-3a98-b4b8-da1131cf33ee","id":"85da782d-2ec0-41ec-a97f-9be464bba309","type":"Release","release-count":579,"name":"Beets Music Collection","entity-type":"release"}

View file

@ -0,0 +1,27 @@
{
"statusCode": 200,
"headers": {
"date": "Mon, 12 Dec 2016 03:50:32 GMT",
"content-type": "application/json; charset=utf-8",
"content-length": "210",
"connection": "keep-alive",
"keep-alive": "timeout=15",
"x-ratelimit-limit": "700",
"x-ratelimit-remaining": "240",
"x-ratelimit-reset": "1481514632",
"server": "Plack::Handler::Starlet",
"etag": "\"a56ef76b83ccc2d2620ac3f66c7ead50\"",
"access-control-allow-origin": "*"
},
"url": "http://musicbrainz.org:80/ws/2/collection/85da782d-2ec0-41ec-a97f-9be464bba309?fmt=json",
"time": 404,
"request": {
"method": "GET",
"headers": {
"User-Agent": "graphbrainz/4.2.0 ( https://github.com/exogen/graphbrainz )",
"host": "musicbrainz.org",
"accept-encoding": "gzip, deflate",
"accept": "application/json"
}
}
}

Binary file not shown.

View file

@ -0,0 +1,29 @@
{
"statusCode": 200,
"headers": {
"date": "Mon, 12 Dec 2016 02:59:37 GMT",
"content-type": "application/json; charset=utf-8",
"transfer-encoding": "chunked",
"connection": "keep-alive",
"keep-alive": "timeout=15",
"vary": "Accept-Encoding",
"x-ratelimit-limit": "700",
"x-ratelimit-remaining": "433",
"x-ratelimit-reset": "1481511578",
"server": "Plack::Handler::Starlet",
"etag": "W/\"732418d1bfab7578b6e228d91a40da59\"",
"access-control-allow-origin": "*",
"content-encoding": "gzip"
},
"url": "http://musicbrainz.org:80/ws/2/artist?collection=06535ef2-adc9-4c50-ad19-ab607d143485&fmt=json",
"time": 483,
"request": {
"method": "GET",
"headers": {
"User-Agent": "graphbrainz/4.2.0 ( https://github.com/exogen/graphbrainz )",
"host": "musicbrainz.org",
"accept-encoding": "gzip, deflate",
"accept": "application/json"
}
}
}

Binary file not shown.

View file

@ -0,0 +1,29 @@
{
"statusCode": 200,
"headers": {
"date": "Mon, 12 Dec 2016 03:50:33 GMT",
"content-type": "application/json; charset=utf-8",
"transfer-encoding": "chunked",
"connection": "keep-alive",
"keep-alive": "timeout=15",
"vary": "Accept-Encoding",
"x-ratelimit-limit": "700",
"x-ratelimit-remaining": "619",
"x-ratelimit-reset": "1481514634",
"server": "Plack::Handler::Starlet",
"etag": "W/\"97326a717e48b9b3aa03b6455ba690bc\"",
"access-control-allow-origin": "*",
"content-encoding": "gzip"
},
"url": "http://musicbrainz.org:80/ws/2/release?collection=85da782d-2ec0-41ec-a97f-9be464bba309&fmt=json",
"time": 656,
"request": {
"method": "GET",
"headers": {
"User-Agent": "graphbrainz/4.2.0 ( https://github.com/exogen/graphbrainz )",
"host": "musicbrainz.org",
"accept-encoding": "gzip, deflate",
"accept": "application/json"
}
}
}

Binary file not shown.

View file

@ -0,0 +1,29 @@
{
"statusCode": 200,
"headers": {
"date": "Mon, 12 Dec 2016 02:59:36 GMT",
"content-type": "application/json; charset=utf-8",
"transfer-encoding": "chunked",
"connection": "keep-alive",
"keep-alive": "timeout=15",
"vary": "Accept-Encoding",
"x-ratelimit-limit": "700",
"x-ratelimit-remaining": "547",
"x-ratelimit-reset": "1481511578",
"server": "Plack::Handler::Starlet",
"etag": "W/\"c9830e30ce33960f506234d5af63ad79\"",
"access-control-allow-origin": "*",
"content-encoding": "gzip"
},
"url": "http://musicbrainz.org:80/ws/2/collection?artist=24f1766e-9635-4d58-a4d4-9413f9f98a4c&fmt=json",
"time": 516,
"request": {
"method": "GET",
"headers": {
"User-Agent": "graphbrainz/4.2.0 ( https://github.com/exogen/graphbrainz )",
"host": "musicbrainz.org",
"accept-encoding": "gzip, deflate",
"accept": "application/json"
}
}
}

Binary file not shown.

View file

@ -0,0 +1,29 @@
{
"statusCode": 200,
"headers": {
"date": "Mon, 12 Dec 2016 02:59:37 GMT",
"content-type": "application/json; charset=utf-8",
"transfer-encoding": "chunked",
"connection": "keep-alive",
"keep-alive": "timeout=15",
"vary": "Accept-Encoding",
"x-ratelimit-limit": "700",
"x-ratelimit-remaining": "435",
"x-ratelimit-reset": "1481511578",
"server": "Plack::Handler::Starlet",
"etag": "W/\"ab16e83e578aff3fc917a4a296e76557\"",
"access-control-allow-origin": "*",
"content-encoding": "gzip"
},
"url": "http://musicbrainz.org:80/ws/2/artist?collection=974fcec4-eca0-4bfe-9a3a-e61aa93c186b&fmt=json",
"time": 579,
"request": {
"method": "GET",
"headers": {
"User-Agent": "graphbrainz/4.2.0 ( https://github.com/exogen/graphbrainz )",
"host": "musicbrainz.org",
"accept-encoding": "gzip, deflate",
"accept": "application/json"
}
}
}

View file

@ -83,7 +83,7 @@ test('schema has a search query', testData, `
test('schema has a browse query', testData, `
{
browse {
releaseGroups (artist: "c8da2e40-bd28-4d4e-813a-bd2f51958ba8") {
releaseGroups(artist: "c8da2e40-bd28-4d4e-813a-bd2f51958ba8") {
totalCount
edges {
node {
@ -592,3 +592,62 @@ test('Recordings have a length in milliseconds', testData, `
const { recording } = data.lookup
t.is(recording.length, 383493)
})
test('Collections can be browsed by the entities they contain', testData, `
{
browse {
collections(artist: "24f1766e-9635-4d58-a4d4-9413f9f98a4c") {
totalCount
edges {
node {
name
editor
entityType
type
artists {
totalCount
edges {
node {
mbid
name
}
}
}
}
}
}
}
}
`, (t, data) => {
const collections = data.browse.collections.edges.map(edge => edge.node)
t.true(collections.length >= 2)
t.true(collections.some(collection => collection.editor === 'arist.on'))
t.true(collections.some(collection => collection.editor === 'ListMyCDs.com'))
collections.forEach(collection => {
t.is(collection.entityType, 'artist')
t.is(collection.type, 'Artist')
t.true(collection.artists.totalCount > 0)
t.true(collection.artists.edges.length > 0)
})
})
test('Collections can be looked up by MBID', testData, `
{
lookup {
collection(mbid: "85da782d-2ec0-41ec-a97f-9be464bba309") {
name
releases {
edges {
node {
title
}
}
}
}
}
}
`, (t, data) => {
const { collection } = data.lookup
t.is(collection.name, 'Beets Music Collection')
t.is(collection.releases.edges.length, 25)
})