diff --git a/docs/schema.md b/docs/schema.md
index fd2a15d..1f4711c 100644
--- a/docs/schema.md
+++ b/docs/schema.md
@@ -987,6 +987,31 @@ type LookupQuery {
# 36-character UUIDs.
scalar MBID
+# A medium is the actual physical medium the audio content is
+# stored upon. This means that each CD in a multi-disc release will be entered as
+# separate mediums within the release, and that both sides of a vinyl record or
+# cassette will exist on one medium. Mediums have a format (e.g. CD, DVD, vinyl,
+# cassette) and can optionally also have a title.
+type Medium {
+ # The title of this particular medium.
+ title: String
+
+ # The [format](https://musicbrainz.org/doc/Release/Format) of
+ # the medium (e.g. CD, DVD, vinyl, cassette).
+ format: String
+
+ # The MBID associated with the value of the `format`
+ # field.
+ formatID: MBID
+
+ # The order of this medium in the release (for example, in a
+ # multi-disc release).
+ position: Int
+
+ # The number of audio tracks on this medium.
+ trackCount: Int
+}
+
# An object with an ID
interface Node {
# The id of the object.
@@ -1551,6 +1576,9 @@ type Release implements Node, Entity {
# [ratings](https://musicbrainz.org/doc/Rating_System).
quality: String
+ # The media on which the release was distributed.
+ media: [Medium]
+
# A list of artists linked to this entity.
artists(after: String, first: Int): ArtistConnection
diff --git a/docs/types.md b/docs/types.md
index 935fa3d..eef0911 100644
--- a/docs/types.md
+++ b/docs/types.md
@@ -29,6 +29,7 @@ You may also be interested in reading the [schema in GraphQL syntax](schema.md).
[LabelEdge](#labeledge)
[LifeSpan](#lifespan)
[LookupQuery](#lookupquery)
+ [Medium](#medium)
[PageInfo](#pageinfo)
[Place](#place)
[PlaceConnection](#placeconnection)
@@ -2503,6 +2504,61 @@ A lookup of an individual MusicBrainz entity by its MBID.
+### Medium
+
+A medium is the actual physical medium the audio content is
+stored upon. This means that each CD in a multi-disc release will be entered as
+separate mediums within the release, and that both sides of a vinyl record or
+cassette will exist on one medium. Mediums have a format (e.g. CD, DVD, vinyl,
+cassette) and can optionally also have a title.
+
+
+
+ | Field / Argument |
+ Type |
+ Description |
+
+
+
+ | title |
+ String |
+
+ The title of this particular medium.
+ |
+
+
+ | format |
+ String |
+
+ The format of
+the medium (e.g. CD, DVD, vinyl, cassette).
+ |
+
+
+ | formatID |
+ MBID |
+
+ The MBID associated with the value of the format
+field.
+ |
+
+
+ | position |
+ Int |
+
+ The order of this medium in the release (for example, in a
+multi-disc release).
+ |
+
+
+ | trackCount |
+ Int |
+
+ The number of audio tracks on this medium.
+ |
+
+
+
### PageInfo
Information about pagination in a connection.
@@ -3877,6 +3933,13 @@ It is not a mark of how good or bad the music itself is – for that, use
ratings.
+
+ | media |
+ [Medium] |
+
+ The media on which the release was distributed.
+ |
+
| artists |
ArtistConnection |
diff --git a/schema.json b/schema.json
index ddb165d..e75dcd0 100644
--- a/schema.json
+++ b/schema.json
@@ -2911,6 +2911,22 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "media",
+ "description": "The media on which the release was distributed.",
+ "args": [],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "Medium",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "artists",
"description": "A list of artists linked to this entity.",
@@ -3197,6 +3213,77 @@
"enumValues": null,
"possibleTypes": null
},
+ {
+ "kind": "OBJECT",
+ "name": "Medium",
+ "description": "A medium is the actual physical medium the audio content is\nstored upon. This means that each CD in a multi-disc release will be entered as\nseparate mediums within the release, and that both sides of a vinyl record or\ncassette will exist on one medium. Mediums have a format (e.g. CD, DVD, vinyl,\ncassette) and can optionally also have a title.",
+ "fields": [
+ {
+ "name": "title",
+ "description": "The title of this particular medium.",
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "format",
+ "description": "The [format](https://musicbrainz.org/doc/Release/Format) of\nthe medium (e.g. CD, DVD, vinyl, cassette).",
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "formatID",
+ "description": "The MBID associated with the value of the `format`\nfield.",
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "MBID",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "position",
+ "description": "The order of this medium in the release (for example, in a\nmulti-disc release).",
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "trackCount",
+ "description": "The number of audio tracks on this medium.",
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
{
"kind": "OBJECT",
"name": "LabelConnection",
diff --git a/src/resolvers.js b/src/resolvers.js
index f75cfba..7366990 100644
--- a/src/resolvers.js
+++ b/src/resolvers.js
@@ -42,6 +42,7 @@ export function includeSubqueries (params, info, fragments = info.fragments) {
artistCredit: 'artist-credits',
artistCredits: 'artist-credits',
isrcs: 'isrcs',
+ media: 'media',
tags: 'tags'
}
let fields = getFields(info, fragments)
diff --git a/src/types/media.js b/src/types/media.js
new file mode 100644
index 0000000..abc43d0
--- /dev/null
+++ b/src/types/media.js
@@ -0,0 +1,31 @@
+import { GraphQLObjectType, GraphQLString, GraphQLInt } from 'graphql/type'
+import { resolveHyphenated, fieldWithID } from './helpers'
+
+export default new GraphQLObjectType({
+ name: 'Medium',
+ description: `A medium is the actual physical medium the audio content is
+stored upon. This means that each CD in a multi-disc release will be entered as
+separate mediums within the release, and that both sides of a vinyl record or
+cassette will exist on one medium. Mediums have a format (e.g. CD, DVD, vinyl,
+cassette) and can optionally also have a title.`,
+ fields: () => ({
+ title: {
+ type: GraphQLString,
+ description: 'The title of this particular medium.'
+ },
+ ...fieldWithID('format', {
+ description: `The [format](https://musicbrainz.org/doc/Release/Format) of
+the medium (e.g. CD, DVD, vinyl, cassette).`
+ }),
+ position: {
+ type: GraphQLInt,
+ description: `The order of this medium in the release (for example, in a
+multi-disc release).`
+ },
+ trackCount: {
+ type: GraphQLInt,
+ description: 'The number of audio tracks on this medium.',
+ resolve: resolveHyphenated
+ }
+ })
+})
diff --git a/src/types/release.js b/src/types/release.js
index dd60f91..80f8abc 100644
--- a/src/types/release.js
+++ b/src/types/release.js
@@ -2,6 +2,7 @@ import { GraphQLObjectType, GraphQLString, GraphQLList } from 'graphql/type'
import Node from './node'
import Entity from './entity'
import { ASIN, DateType } from './scalars'
+import Media from './media'
import { ReleaseStatus } from './enums'
import ReleaseEvent from './release-event'
import {
@@ -82,6 +83,10 @@ information.`
It is not a mark of how good or bad the music itself is – for that, use
[ratings](https://musicbrainz.org/doc/Rating_System).`
},
+ media: {
+ type: new GraphQLList(Media),
+ description: 'The media on which the release was distributed.'
+ },
artists,
labels,
recordings,
diff --git a/test/fixtures/f70e148191e1ebbc95eb12ddc2d85be2 b/test/fixtures/f70e148191e1ebbc95eb12ddc2d85be2
new file mode 100644
index 0000000..b27d798
Binary files /dev/null and b/test/fixtures/f70e148191e1ebbc95eb12ddc2d85be2 differ
diff --git a/test/fixtures/f70e148191e1ebbc95eb12ddc2d85be2.headers b/test/fixtures/f70e148191e1ebbc95eb12ddc2d85be2.headers
new file mode 100644
index 0000000..b5a472a
--- /dev/null
+++ b/test/fixtures/f70e148191e1ebbc95eb12ddc2d85be2.headers
@@ -0,0 +1,29 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "date": "Mon, 12 Dec 2016 08:53:41 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": "287",
+ "x-ratelimit-reset": "1481532821",
+ "server": "Plack::Handler::Starlet",
+ "etag": "W/\"87b80866564432cc2d6a470811edc6a8\"",
+ "access-control-allow-origin": "*",
+ "content-encoding": "gzip"
+ },
+ "url": "http://musicbrainz.org:80/ws/2/release/a4864e94-6d75-4ade-bc93-0dabf3521453?inc=media&fmt=json",
+ "time": 506,
+ "request": {
+ "method": "GET",
+ "headers": {
+ "User-Agent": "graphbrainz/4.3.1 ( https://github.com/exogen/graphbrainz )",
+ "host": "musicbrainz.org",
+ "accept-encoding": "gzip, deflate",
+ "accept": "application/json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/schema.js b/test/schema.js
index dff9d7d..f1fa856 100644
--- a/test/schema.js
+++ b/test/schema.js
@@ -685,3 +685,37 @@ test('entities have a collections field', testData, `
t.true(release.collections.edges.length > 0)
t.true(artist.collections.edges.length > 0)
})
+
+test('Releases support a list of media', testData, `
+ {
+ lookup {
+ release(mbid: "a4864e94-6d75-4ade-bc93-0dabf3521453") {
+ media {
+ title
+ format
+ formatID
+ position
+ trackCount
+ }
+ }
+ }
+ }
+`, (t, data) => {
+ const { release } = data.lookup
+ t.deepEqual(release.media, [
+ {
+ title: 'Left',
+ format: 'CD',
+ formatID: '9712d52a-4509-3d4b-a1a2-67c88c643e31',
+ position: 1,
+ trackCount: 12
+ },
+ {
+ title: 'Right',
+ format: 'CD',
+ formatID: '9712d52a-4509-3d4b-a1a2-67c88c643e31',
+ position: 2,
+ trackCount: 11
+ }
+ ])
+})