diff --git a/README.md b/README.md index b405751..40897e0 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,14 @@ The `graphbrainz` middleware function accepts the following options: if you are running your own MusicBrainz mirror. Defaults to `http://musicbrainz.org/ws/2/`. * **`GRAPHBRAINZ_PATH`**: The URL route at which to expose the GraphQL endpoint, if running the standalone server. Defaults to `/`. +* **`GRAPHBRAINZ_CACHE_SIZE`**: The maximum number of REST API responses to + cache. Increasing the cache size and TTL will greatly lower query execution + time for complex queries involving frequently accessed entities. Defaults to + `8192`. +* **`GRAPHBRAINZ_CACHE_TTL`**: The maximum age of REST API responses in the + cache, in milliseconds. Responses older than this will be disposed of (and + re-requested) the next time they are accessed. Defaults to `86400000` (one + day). * **`GRAPHBRAINZ_GRAPHIQL`**: Set this to `true` if you want to force the [GraphiQL][] interface to be available even in production mode. * **`PORT`**: Port number to use, if running the standalone server. diff --git a/schema.json b/schema.json index 577a330..6e6519c 100644 --- a/schema.json +++ b/schema.json @@ -53,7 +53,7 @@ }, { "name": "browse", - "description": "Browse all MusicBrainz entities directly linked to another\nentity.", + "description": "Browse all MusicBrainz entities directly linked to another entity.", "args": [], "type": { "kind": "OBJECT", @@ -65,7 +65,7 @@ }, { "name": "search", - "description": "Search for MusicBrainz entities using Lucene query\nsyntax.", + "description": "Search for MusicBrainz entities using Lucene query syntax.", "args": [], "type": { "kind": "OBJECT", @@ -597,6 +597,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "isoCodes", "description": "[ISO 3166 codes](https://en.wikipedia.org/wiki/ISO_3166) are\nthe codes assigned by ISO to countries and subdivisions.", @@ -615,7 +631,7 @@ }, { "name": "artists", - "description": "A list of artist entities linked to this entity.", + "description": "A list of artists linked to this entity.", "args": [ { "name": "after", @@ -648,7 +664,7 @@ }, { "name": "events", - "description": "A list of event entities linked to this entity.", + "description": "A list of events linked to this entity.", "args": [ { "name": "after", @@ -681,7 +697,7 @@ }, { "name": "labels", - "description": "A list of label entities linked to this entity.", + "description": "A list of labels linked to this entity.", "args": [ { "name": "after", @@ -714,7 +730,7 @@ }, { "name": "places", - "description": "A list of place entities linked to this entity.", + "description": "A list of places linked to this entity.", "args": [ { "name": "after", @@ -747,7 +763,7 @@ }, { "name": "releases", - "description": "A list of release entities linked to this entity.", + "description": "A list of releases linked to this entity.", "args": [ { "name": "after", @@ -805,6 +821,51 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "relationships", + "description": "Relationships between this entity and other entitites.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Relationships", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -921,6 +982,99 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "Alias", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are variant names\nthat are mostly used as search help: if a search matches an entity’s alias, the\nentity will be given as a result – even if the actual name wouldn’t be. They are\navailable for artists, labels, and works.", + "fields": [ + { + "name": "name", + "description": "The aliased name of the entity.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sortName", + "description": "The string to use for the purpose of ordering by name (for\nexample, by moving articles like ‘the’ to the end or a person’s last name to\nthe front).", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locale", + "description": "The locale (language and/or country) in which the alias is\nused.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "primary", + "description": "Whether this is the main alias for the entity in the\nspecified locale (this could mean the most recent or the most common).", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "The type or purpose of the alias – whether it is a variant,\nsearch hint, etc.", + "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 + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "Boolean", + "description": "The `Boolean` scalar type represents `true` or `false`.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "SCALAR", "name": "Int", @@ -967,6 +1121,18 @@ }, "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, @@ -1041,16 +1207,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "SCALAR", - "name": "Boolean", - "description": "The `Boolean` scalar type represents `true` or `false`.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, { "kind": "OBJECT", "name": "ArtistEdge", @@ -1165,7 +1321,7 @@ }, { "name": "aliases", - "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to\nstore alternate names or misspellings.", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", "args": [], "type": { "kind": "LIST", @@ -1289,7 +1445,7 @@ }, { "name": "recordings", - "description": "A list of recording entities linked to this entity.", + "description": "A list of recordings linked to this entity.", "args": [ { "name": "after", @@ -1322,7 +1478,7 @@ }, { "name": "releases", - "description": "A list of release entities linked to this entity.", + "description": "A list of releases linked to this entity.", "args": [ { "name": "after", @@ -1383,7 +1539,7 @@ }, { "name": "releaseGroups", - "description": "A list of release group entities linked to this entity.", + "description": "A list of release groups linked to this entity.", "args": [ { "name": "after", @@ -1430,7 +1586,7 @@ }, { "name": "works", - "description": "A list of work entities linked to this entity.", + "description": "A list of works linked to this entity.", "args": [ { "name": "after", @@ -1472,6 +1628,39 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -1490,89 +1679,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "OBJECT", - "name": "Alias", - "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are variant names\nthat are mostly used as search help: if a search matches an entity’s alias, the\nentity will be given as a result – even if the actual name wouldn’t be. They are\navailable for artists, labels, and works.", - "fields": [ - { - "name": "name", - "description": "The aliased name of the entity.", - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "sortName", - "description": "The string to use for the purpose of ordering by name (for\nexample, by moving articles like ‘the’ to the end or a person’s last name to\nthe front).", - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "locale", - "description": "The locale (language and/or country) in which the alias is\nused.", - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "primary", - "description": "Whether this is the main alias for the entity in the\nspecified locale (this could mean the most recent or the most common).", - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "type", - "description": "The type or purpose of the alias – whether it is a variant,\nsearch hint, etc.", - "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 - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, { "kind": "OBJECT", "name": "LifeSpan", @@ -1666,6 +1772,18 @@ }, "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, @@ -1773,6 +1891,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "artistCredit", "description": "The main credited artist(s).", @@ -1815,7 +1949,7 @@ }, { "name": "artists", - "description": "A list of artist entities linked to this entity.", + "description": "A list of artists linked to this entity.", "args": [ { "name": "after", @@ -1848,7 +1982,7 @@ }, { "name": "releases", - "description": "A list of release entities linked to this entity.", + "description": "A list of releases linked to this entity.", "args": [ { "name": "after", @@ -1918,6 +2052,39 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -2161,6 +2328,18 @@ }, "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, @@ -2268,6 +2447,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "artistCredit", "description": "The main credited artist(s).", @@ -2398,7 +2593,7 @@ }, { "name": "artists", - "description": "A list of artist entities linked to this entity.", + "description": "A list of artists linked to this entity.", "args": [ { "name": "after", @@ -2431,7 +2626,7 @@ }, { "name": "labels", - "description": "A list of label entities linked to this entity.", + "description": "A list of labels linked to this entity.", "args": [ { "name": "after", @@ -2464,7 +2659,7 @@ }, { "name": "recordings", - "description": "A list of recording entities linked to this entity.", + "description": "A list of recordings linked to this entity.", "args": [ { "name": "after", @@ -2497,7 +2692,7 @@ }, { "name": "releaseGroups", - "description": "A list of release group entities linked to this entity.", + "description": "A list of release groups linked to this entity.", "args": [ { "name": "after", @@ -2553,6 +2748,39 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -2642,6 +2870,18 @@ }, "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, @@ -2761,6 +3001,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "country", "description": "The country of origin for the label.", @@ -2851,355 +3107,7 @@ }, { "name": "releases", - "description": "A list of release entities 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": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "ReleaseGroupType", - "ofType": null - } - }, - "defaultValue": null - }, - { - "name": "status", - "description": null, - "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 - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "Node", - "ofType": null - }, - { - "kind": "INTERFACE", - "name": "Entity", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "SCALAR", - "name": "IPI", - "description": "An [IPI](https://musicbrainz.org/doc/IPI) (interested party\ninformation) code is an identifying number assigned by the CISAC database for\nmusical rights management.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "ReleaseGroupConnection", - "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": "ReleaseGroupEdge", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "ReleaseGroupEdge", - "description": "An edge in a connection.", - "fields": [ - { - "name": "node", - "description": "The item at the end of the edge", - "args": [], - "type": { - "kind": "OBJECT", - "name": "ReleaseGroup", - "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 - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "ReleaseGroup", - "description": "A [release group](https://musicbrainz.org/doc/Release_Group) is\nused to group several different releases into a single logical entity. Every\nrelease belongs to one, and only one release group.\n\nBoth release groups and releases are “albums” in a general sense, but with an\nimportant difference: a release is something you can buy as media such as a CD\nor a vinyl record, while a release group embraces the overall concept of an\nalbum – it doesn’t matter how many CDs or editions/versions it had.", - "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": "title", - "description": "The official title of the entity.", - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "disambiguation", - "description": "A comment used to help distinguish identically named entitites.", - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "artistCredit", - "description": "The main credited artist(s).", - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "ArtistCredit", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "firstReleaseDate", - "description": "The date of the earliest release in the group.", - "args": [], - "type": { - "kind": "SCALAR", - "name": "Date", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "primaryType", - "description": "The [type](https://musicbrainz.org/doc/Release_Group/Type)\nof a release group describes what kind of releases the release group represents,\ne.g. album, single, soundtrack, compilation, etc. A release group can have a\n“main” type and an unspecified number of additional types.", - "args": [], - "type": { - "kind": "ENUM", - "name": "ReleaseGroupType", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "primaryTypeID", - "description": "The MBID associated with the value of the `primaryType`\nfield.", - "args": [], - "type": { - "kind": "SCALAR", - "name": "MBID", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "secondaryTypes", - "description": "Additional [types](https://musicbrainz.org/doc/Release_Group/Type)\nthat apply to this release group.", - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "ReleaseGroupType", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "secondaryTypeIDs", - "description": "The MBIDs associated with the values of the `secondaryTypes`\nfield.", - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "MBID", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "artists", - "description": "A list of artist entities 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": "releases", - "description": "A list of release entities linked to this entity.", + "description": "A list of releases linked to this entity.", "args": [ { "name": "after", @@ -3269,6 +3177,39 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -3287,6 +3228,16 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "SCALAR", + "name": "IPI", + "description": "An [IPI](https://musicbrainz.org/doc/IPI) (interested party\ninformation) code is an identifying number assigned by the CISAC database for\nmusical rights management.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "Relationships", @@ -4330,6 +4281,18 @@ }, "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, @@ -4535,6 +4498,550 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "TagConnection", + "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": "TagEdge", + "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": "TagEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "node", + "description": "The item at the end of the edge", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Tag", + "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 + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Tag", + "description": "[Tags](https://musicbrainz.org/tags) are a way mark entities\nwith extra information – for example, the genres that apply to an artist,\nrelease, or recording.", + "fields": [ + { + "name": "name", + "description": "The tag label.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "count", + "description": "How many times this tag has been applied to the entity.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReleaseGroupConnection", + "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": "ReleaseGroupEdge", + "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": "ReleaseGroupEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "node", + "description": "The item at the end of the edge", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ReleaseGroup", + "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 + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReleaseGroup", + "description": "A [release group](https://musicbrainz.org/doc/Release_Group) is\nused to group several different releases into a single logical entity. Every\nrelease belongs to one, and only one release group.\n\nBoth release groups and releases are “albums” in a general sense, but with an\nimportant difference: a release is something you can buy as media such as a CD\nor a vinyl record, while a release group embraces the overall concept of an\nalbum – it doesn’t matter how many CDs or editions/versions it had.", + "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": "title", + "description": "The official title of the entity.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "disambiguation", + "description": "A comment used to help distinguish identically named entitites.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "artistCredit", + "description": "The main credited artist(s).", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ArtistCredit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "firstReleaseDate", + "description": "The date of the earliest release in the group.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Date", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "primaryType", + "description": "The [type](https://musicbrainz.org/doc/Release_Group/Type)\nof a release group describes what kind of releases the release group represents,\ne.g. album, single, soundtrack, compilation, etc. A release group can have a\n“main” type and an unspecified number of additional types.", + "args": [], + "type": { + "kind": "ENUM", + "name": "ReleaseGroupType", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "primaryTypeID", + "description": "The MBID associated with the value of the `primaryType`\nfield.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "secondaryTypes", + "description": "Additional [types](https://musicbrainz.org/doc/Release_Group/Type)\nthat apply to this release group.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReleaseGroupType", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "secondaryTypeIDs", + "description": "The MBIDs associated with the values of the `secondaryTypes`\nfield.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "MBID", + "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": "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": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReleaseGroupType", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "status", + "description": null, + "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": "relationships", + "description": "Relationships between this entity and other entitites.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Relationships", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "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": "WorkConnection", @@ -4571,6 +5078,18 @@ }, "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, @@ -4678,6 +5197,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "iswcs", "description": "A list of [ISWCs](https://musicbrainz.org/doc/ISWC) assigned\nto the work by copyright collecting agencies.", @@ -4732,7 +5267,7 @@ }, { "name": "artists", - "description": "A list of artist entities linked to this entity.", + "description": "A list of artists linked to this entity.", "args": [ { "name": "after", @@ -4774,6 +5309,39 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -4828,6 +5396,18 @@ }, "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, @@ -4935,6 +5515,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "lifeSpan", "description": "The begin and end dates of the entity’s existence. Its exact\nmeaning depends on the type of entity.", @@ -5006,6 +5602,51 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "relationships", + "description": "Relationships between this entity and other entitites.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Relationships", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -5070,6 +5711,18 @@ }, "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, @@ -5177,6 +5830,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "address", "description": "The address describes the location of the place using the\nstandard addressing format for the country it is located in.", @@ -5251,7 +5920,7 @@ }, { "name": "events", - "description": "A list of event entities linked to this entity.", + "description": "A list of events linked to this entity.", "args": [ { "name": "after", @@ -5281,6 +5950,51 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "relationships", + "description": "Relationships between this entity and other entitites.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Relationships", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -5405,6 +6119,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "aliases", + "description": "[Aliases](https://musicbrainz.org/doc/Aliases) are used to store\nalternate names or misspellings.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Alias", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "description", "description": "A brief description of the main characteristics of the\ninstrument.", @@ -5440,6 +6170,51 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "relationships", + "description": "Relationships between this entity and other entitites.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Relationships", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -5542,6 +6317,51 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "relationships", + "description": "Relationships between this entity and other entitites.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Relationships", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tags", + "description": "A list of tags 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": "TagConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -5657,6 +6477,49 @@ "name": "BrowseQuery", "description": "A query for all MusicBrainz entities directly linked to another\nentity.", "fields": [ + { + "name": "areas", + "description": "Browse area 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": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AreaConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "artists", "description": "Browse artist entities linked to the given arguments.", @@ -5691,6 +6554,16 @@ }, "defaultValue": null }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null + }, { "name": "recording", "description": "The MBID of a recording to which the entity is linked.", @@ -5784,6 +6657,16 @@ }, "defaultValue": null }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null + }, { "name": "place", "description": "The MBID of a place to which the event is linked.", @@ -5837,6 +6720,16 @@ }, "defaultValue": null }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null + }, { "name": "release", "description": "The MBID of a release to which the entity is linked.", @@ -5889,6 +6782,16 @@ "ofType": null }, "defaultValue": null + }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null } ], "type": { @@ -5933,6 +6836,16 @@ }, "defaultValue": null }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null + }, { "name": "release", "description": "The MBID of a release to which the entity is linked.", @@ -5996,6 +6909,16 @@ }, "defaultValue": null }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null + }, { "name": "label", "description": "The MBID of a label to which the release is linked.", @@ -6089,6 +7012,16 @@ }, "defaultValue": null }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null + }, { "name": "release", "description": "The MBID of a release to which the entity is linked.", @@ -6141,6 +7074,16 @@ "ofType": null }, "defaultValue": null + }, + { + "name": "collection", + "description": "The MBID of a collection in which the entity is found.", + "type": { + "kind": "SCALAR", + "name": "MBID", + "ofType": null + }, + "defaultValue": null } ], "type": { @@ -6200,6 +7143,100 @@ "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 + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "URLConnection", @@ -6236,6 +7273,18 @@ }, "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, @@ -6293,7 +7342,7 @@ "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6340,7 +7389,7 @@ "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6381,13 +7430,107 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "events", + "description": "Search for event entities matching the given query.", + "args": [ + { + "name": "query", + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "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": "instruments", + "description": "Search for instrument entities matching the given query.", + "args": [ + { + "name": "query", + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "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": "InstrumentConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "labels", "description": "Search for label entities matching the given query.", "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6434,7 +7577,7 @@ "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6481,7 +7624,7 @@ "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6528,7 +7671,7 @@ "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6575,7 +7718,7 @@ "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6616,13 +7759,60 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "series", + "description": "Search for series entities matching the given query.", + "args": [ + { + "name": "query", + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "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": "SeriesConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "works", "description": "Search for work entities matching the given query.", "args": [ { "name": "query", - "description": null, + "description": "The query terms, in Lucene search syntax. See [examples\nand search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).", "type": { "kind": "NON_NULL", "name": null, @@ -6671,7 +7861,7 @@ }, { "kind": "OBJECT", - "name": "AreaConnection", + "name": "InstrumentConnection", "description": "A connection to a list of items.", "fields": [ { @@ -6699,7 +7889,58 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "AreaEdge", + "name": "InstrumentEdge", + "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": "InstrumentEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "node", + "description": "The item at the end of the edge", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Instrument", + "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 } }, @@ -6714,7 +7955,62 @@ }, { "kind": "OBJECT", - "name": "AreaEdge", + "name": "SeriesConnection", + "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": "SeriesEdge", + "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": "SeriesEdge", "description": "An edge in a connection.", "fields": [ { @@ -6723,7 +8019,7 @@ "args": [], "type": { "kind": "OBJECT", - "name": "Area", + "name": "Series", "ofType": null }, "isDeprecated": false, diff --git a/schema.md b/schema.md index b17c04d..c7e3f4f 100644 --- a/schema.md +++ b/schema.md @@ -51,24 +51,34 @@ type Area implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # [ISO 3166 codes](https://en.wikipedia.org/wiki/ISO_3166) are # the codes assigned by ISO to countries and subdivisions. isoCodes: [String] - # A list of artist entities linked to this entity. + # A list of artists linked to this entity. artists(after: String, first: Int): ArtistConnection - # A list of event entities linked to this entity. + # A list of events linked to this entity. events(after: String, first: Int): EventConnection - # A list of label entities linked to this entity. + # A list of labels linked to this entity. labels(after: String, first: Int): LabelConnection - # A list of place entities linked to this entity. + # A list of places linked to this entity. places(after: String, first: Int): PlaceConnection - # A list of release entities linked to this entity. + # A list of releases linked to this entity. releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection + + # Relationships between this entity and other entitites. + relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -78,6 +88,10 @@ type AreaConnection { # A list of edges. edges: [AreaEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -112,8 +126,8 @@ type Artist implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String - # [Aliases](https://musicbrainz.org/doc/Aliases) are used to - # store alternate names or misspellings. + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. aliases: [Alias] # The country with which an artist is primarily identified. It @@ -151,20 +165,23 @@ type Artist implements Node, Entity { # field. typeID: MBID - # A list of recording entities linked to this entity. + # A list of recordings linked to this entity. recordings(after: String, first: Int): RecordingConnection - # A list of release entities linked to this entity. + # A list of releases linked to this entity. releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection - # A list of release group entities linked to this entity. + # A list of release groups linked to this entity. releaseGroups(after: String, first: Int, type: [ReleaseGroupType]): ReleaseGroupConnection - # A list of work entities linked to this entity. + # A list of works linked to this entity. works(after: String, first: Int): WorkConnection # Relationships between this entity and other entitites. relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -174,6 +191,10 @@ type ArtistConnection { # A list of edges. edges: [ArtistEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # [Artist credits](https://musicbrainz.org/doc/Artist_Credits) @@ -207,6 +228,15 @@ type ArtistEdge { # A query for all MusicBrainz entities directly linked to another # entity. type BrowseQuery { + # Browse area entities linked to the given arguments. + areas( + after: String + first: Int + + # The MBID of a collection in which the entity is found. + collection: MBID + ): AreaConnection + # Browse artist entities linked to the given arguments. artists( after: String @@ -215,6 +245,9 @@ type BrowseQuery { # The MBID of an area to which the entity is linked. area: MBID + # The MBID of a collection in which the entity is found. + collection: MBID + # The MBID of a recording to which the entity is linked. recording: MBID @@ -239,6 +272,9 @@ type BrowseQuery { # The MBID of an artist to which the entity is linked. artist: MBID + # The MBID of a collection in which the entity is found. + collection: MBID + # The MBID of a place to which the event is linked. place: MBID ): EventConnection @@ -251,6 +287,9 @@ type BrowseQuery { # The MBID of an area to which the entity is linked. area: MBID + # The MBID of a collection in which the entity is found. + collection: MBID + # The MBID of a release to which the entity is linked. release: MBID ): LabelConnection @@ -262,6 +301,9 @@ type BrowseQuery { # The MBID of an area to which the entity is linked. area: MBID + + # The MBID of a collection in which the entity is found. + collection: MBID ): PlaceConnection # Browse recording entities linked to the given arguments. @@ -272,6 +314,9 @@ type BrowseQuery { # The MBID of an artist to which the entity is linked. artist: MBID + # The MBID of a collection in which the entity is found. + collection: MBID + # The MBID of a release to which the entity is linked. release: MBID ): RecordingConnection @@ -287,6 +332,9 @@ type BrowseQuery { # The MBID of an artist to which the entity is linked. artist: MBID + # The MBID of a collection in which the entity is found. + collection: MBID + # The MBID of a label to which the release is linked. label: MBID @@ -312,6 +360,9 @@ type BrowseQuery { # The MBID of an artist to which the entity is linked. artist: MBID + # The MBID of a collection in which the entity is found. + collection: MBID + # The MBID of a release to which the entity is linked. release: MBID ): ReleaseGroupConnection @@ -323,6 +374,9 @@ type BrowseQuery { # The MBID of an artist to which the entity is linked. artist: MBID + + # The MBID of a collection in which the entity is found. + collection: MBID ): WorkConnection # Browse URL entities linked to the given arguments. @@ -372,6 +426,10 @@ type Event implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # The begin and end dates of the entity’s existence. Its exact # meaning depends on the type of entity. lifeSpan: LifeSpan @@ -393,6 +451,12 @@ type Event implements Node, Entity { # The MBID associated with the value of the `type` # field. typeID: MBID + + # Relationships between this entity and other entitites. + relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -402,6 +466,10 @@ type EventConnection { # A list of edges. edges: [EventEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -429,6 +497,10 @@ type Instrument implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # A brief description of the main characteristics of the # instrument. description: String @@ -441,6 +513,34 @@ type Instrument implements Node, Entity { # The MBID associated with the value of the `type` # field. typeID: MBID + + # Relationships between this entity and other entitites. + relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection +} + +# A connection to a list of items. +type InstrumentConnection { + # Information to aid in pagination. + pageInfo: PageInfo! + + # A list of edges. + edges: [InstrumentEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int +} + +# An edge in a connection. +type InstrumentEdge { + # The item at the end of the edge + node: Instrument + + # A cursor for use in pagination + cursor: String! } # An [IPI](https://musicbrainz.org/doc/IPI) (interested party @@ -469,6 +569,10 @@ type Label implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # The country of origin for the label. country: String @@ -495,8 +599,14 @@ type Label implements Node, Entity { # field. typeID: MBID - # A list of release entities linked to this entity. + # A list of releases linked to this entity. releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection + + # Relationships between this entity and other entitites. + relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -506,6 +616,10 @@ type LabelConnection { # A list of edges. edges: [LabelEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -640,6 +754,10 @@ type Place implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # The address describes the location of the place using the # standard addressing format for the country it is located in. address: String @@ -663,8 +781,14 @@ type Place implements Node, Entity { # field. typeID: MBID - # A list of event entities linked to this entity. + # A list of events linked to this entity. events(after: String, first: Int): EventConnection + + # Relationships between this entity and other entitites. + relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -674,6 +798,10 @@ type PlaceConnection { # A list of edges. edges: [PlaceEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -697,12 +825,10 @@ type Query { # Perform a lookup of a MusicBrainz entity by its MBID. lookup: LookupQuery - # Browse all MusicBrainz entities directly linked to another - # entity. + # Browse all MusicBrainz entities directly linked to another entity. browse: BrowseQuery - # Search for MusicBrainz entities using Lucene query - # syntax. + # Search for MusicBrainz entities using Lucene query syntax. search: SearchQuery } @@ -731,6 +857,10 @@ type Recording implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # The main credited artist(s). artistCredit: [ArtistCredit] @@ -741,14 +871,17 @@ type Recording implements Node, Entity { # Whether this is a video recording. video: Boolean - # A list of artist entities linked to this entity. + # A list of artists linked to this entity. artists(after: String, first: Int): ArtistConnection - # A list of release entities linked to this entity. + # A list of releases linked to this entity. releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection # Relationships between this entity and other entitites. relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -758,6 +891,10 @@ type RecordingConnection { # A list of edges. edges: [RecordingEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -820,6 +957,10 @@ type RelationshipConnection { # A list of edges. edges: [RelationshipEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -1068,6 +1209,10 @@ type Release implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # The main credited artist(s). artistCredit: [ArtistCredit] @@ -1109,20 +1254,23 @@ type Release implements Node, Entity { # [ratings](https://musicbrainz.org/doc/Rating_System). quality: String - # A list of artist entities linked to this entity. + # A list of artists linked to this entity. artists(after: String, first: Int): ArtistConnection - # A list of label entities linked to this entity. + # A list of labels linked to this entity. labels(after: String, first: Int): LabelConnection - # A list of recording entities linked to this entity. + # A list of recordings linked to this entity. recordings(after: String, first: Int): RecordingConnection - # A list of release group entities linked to this entity. + # A list of release groups linked to this entity. releaseGroups(after: String, first: Int, type: [ReleaseGroupType]): ReleaseGroupConnection # Relationships between this entity and other entitites. relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -1132,6 +1280,10 @@ type ReleaseConnection { # A list of edges. edges: [ReleaseEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -1171,6 +1323,10 @@ type ReleaseGroup implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # The main credited artist(s). artistCredit: [ArtistCredit] @@ -1195,14 +1351,17 @@ type ReleaseGroup implements Node, Entity { # field. secondaryTypeIDs: [MBID] - # A list of artist entities linked to this entity. + # A list of artists linked to this entity. artists(after: String, first: Int): ArtistConnection - # A list of release entities linked to this entity. + # A list of releases linked to this entity. releases(after: String, first: Int, type: [ReleaseGroupType], status: [ReleaseStatus]): ReleaseConnection # Relationships between this entity and other entitites. relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -1212,6 +1371,10 @@ type ReleaseGroupConnection { # A list of edges. edges: [ReleaseGroupEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -1326,28 +1489,103 @@ enum ReleaseStatus { # A search for MusicBrainz entities using Lucene query syntax. type SearchQuery { # Search for area entities matching the given query. - areas(query: String!, after: String, first: Int): AreaConnection + areas( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): AreaConnection # Search for artist entities matching the given query. - artists(query: String!, after: String, first: Int): ArtistConnection + artists( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): ArtistConnection + + # Search for event entities matching the given query. + events( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): EventConnection + + # Search for instrument entities matching the given query. + instruments( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): InstrumentConnection # Search for label entities matching the given query. - labels(query: String!, after: String, first: Int): LabelConnection + labels( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): LabelConnection # Search for place entities matching the given query. - places(query: String!, after: String, first: Int): PlaceConnection + places( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): PlaceConnection # Search for recording entities matching the given query. - recordings(query: String!, after: String, first: Int): RecordingConnection + recordings( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): RecordingConnection # Search for release entities matching the given query. - releases(query: String!, after: String, first: Int): ReleaseConnection + releases( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): ReleaseConnection # Search for release group entities matching the given query. - releaseGroups(query: String!, after: String, first: Int): ReleaseGroupConnection + releaseGroups( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): ReleaseGroupConnection + + # Search for series entities matching the given query. + series( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): SeriesConnection # Search for work entities matching the given query. - works(query: String!, after: String, first: Int): WorkConnection + works( + # The query terms, in Lucene search syntax. See [examples + # and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search). + query: String! + after: String + first: Int + ): WorkConnection } # A [series](https://musicbrainz.org/doc/Series) is a sequence of @@ -1373,6 +1611,67 @@ type Series implements Node, Entity { # The MBID associated with the value of the `type` # field. typeID: MBID + + # Relationships between this entity and other entitites. + relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection +} + +# A connection to a list of items. +type SeriesConnection { + # Information to aid in pagination. + pageInfo: PageInfo! + + # A list of edges. + edges: [SeriesEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int +} + +# An edge in a connection. +type SeriesEdge { + # The item at the end of the edge + node: Series + + # A cursor for use in pagination + cursor: String! +} + +# [Tags](https://musicbrainz.org/tags) are a way mark entities +# with extra information – for example, the genres that apply to an artist, +# release, or recording. +type Tag { + # The tag label. + name: String! + + # How many times this tag has been applied to the entity. + count: Int +} + +# A connection to a list of items. +type TagConnection { + # Information to aid in pagination. + pageInfo: PageInfo! + + # A list of edges. + edges: [TagEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int +} + +# An edge in a connection. +type TagEdge { + # The item at the end of the edge + node: Tag + + # A cursor for use in pagination + cursor: String! } # A time of day, in 24-hour hh:mm notation. @@ -1402,6 +1701,10 @@ type URLConnection { # A list of edges. edges: [URLEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. @@ -1432,6 +1735,10 @@ type Work implements Node, Entity { # A comment used to help distinguish identically named entitites. disambiguation: String + # [Aliases](https://musicbrainz.org/doc/Aliases) are used to store + # alternate names or misspellings. + aliases: [Alias] + # A list of [ISWCs](https://musicbrainz.org/doc/ISWC) assigned # to the work by copyright collecting agencies. iswcs: [String] @@ -1446,11 +1753,14 @@ type Work implements Node, Entity { # field. typeID: MBID - # A list of artist entities linked to this entity. + # A list of artists linked to this entity. artists(after: String, first: Int): ArtistConnection # Relationships between this entity and other entitites. relationships: Relationships + + # A list of tags linked to this entity. + tags(after: String, first: Int): TagConnection } # A connection to a list of items. @@ -1460,6 +1770,10 @@ type WorkConnection { # A list of edges. edges: [WorkEdge] + + # A count of the total number of items in this connection, + # ignoring pagination. + totalCount: Int } # An edge in a connection. diff --git a/src/loaders.js b/src/loaders.js index 2f77740..01c04cc 100644 --- a/src/loaders.js +++ b/src/loaders.js @@ -3,13 +3,14 @@ import LRUCache from 'lru-cache' import { toPlural } from './types/helpers' const debug = require('debug')('graphbrainz:loaders') +const ONE_DAY = 24 * 60 * 60 * 1000 export default function createLoaders (client) { // All loaders share a single LRU cache that will remember 8192 responses, // each cached for 1 day. const cache = LRUCache({ - max: 8192, - maxAge: 24 * 60 * 60 * 1000, + max: parseInt(process.env.GRAPHBRAINZ_CACHE_SIZE || 8192, 10), + maxAge: parseInt(process.env.GRAPHBRAINZ_CACHE_TTL || ONE_DAY, 10), dispose (key) { debug(`Removed '${key}' from cache.`) } @@ -25,7 +26,8 @@ export default function createLoaders (client) { if (entity) { // Store the entity type so we can determine what type of object this // is elsewhere in the code. - entity.entityType = entityType + entity._type = entityType + entity._inc = params.inc } return entity }) @@ -42,7 +44,8 @@ export default function createLoaders (client) { list[toPlural(entityType)].forEach(entity => { // Store the entity type so we can determine what type of object this // is elsewhere in the code. - entity.entityType = entityType + entity._type = entityType + entity._inc = params.inc }) return list }) @@ -59,7 +62,8 @@ export default function createLoaders (client) { list[toPlural(entityType)].forEach(entity => { // Store the entity type so we can determine what type of object this // is elsewhere in the code. - entity.entityType = entityType + entity._type = entityType + entity._inc = params.inc }) return list }) diff --git a/src/queries/browse.js b/src/queries/browse.js index 49a53b0..451f5c9 100644 --- a/src/queries/browse.js +++ b/src/queries/browse.js @@ -4,6 +4,7 @@ import { browseResolver } from '../resolvers' import { MBID, URLString, + AreaConnection, ArtistConnection, EventConnection, LabelConnection, @@ -24,6 +25,10 @@ const artist = { type: MBID, description: 'The MBID of an artist to which the entity is linked.' } +const collection = { + type: MBID, + description: 'The MBID of a collection in which the entity is found.' +} const recording = { type: MBID, description: 'The MBID of a recording to which the entity is linked.' @@ -55,8 +60,12 @@ export const BrowseQuery = new GraphQLObjectType({ description: `A query for all MusicBrainz entities directly linked to another entity.`, fields: { + areas: browseQuery(AreaConnection, { + collection + }), artists: browseQuery(ArtistConnection, { area, + collection, recording, release, releaseGroup, @@ -68,6 +77,7 @@ entity.`, events: browseQuery(EventConnection, { area, artist, + collection, place: { type: MBID, description: 'The MBID of a place to which the event is linked.' @@ -75,18 +85,22 @@ entity.`, }), labels: browseQuery(LabelConnection, { area, + collection, release }), places: browseQuery(PlaceConnection, { - area + area, + collection }), recordings: browseQuery(RecordingConnection, { artist, + collection, release }), releases: browseQuery(ReleaseConnection, { area, artist, + collection, label: { type: MBID, description: 'The MBID of a label to which the release is linked.' @@ -105,10 +119,12 @@ release, but is not included in the credits for the release itself.` }), releaseGroups: browseQuery(ReleaseGroupConnection, { artist, + collection, release }), works: browseQuery(WorkConnection, { - artist + artist, + collection }), urls: browseQuery(URLConnection, { resource: { diff --git a/src/queries/search.js b/src/queries/search.js index af57602..98ae607 100644 --- a/src/queries/search.js +++ b/src/queries/search.js @@ -4,11 +4,14 @@ import { searchResolver } from '../resolvers' import { AreaConnection, ArtistConnection, + EventConnection, + InstrumentConnection, LabelConnection, PlaceConnection, RecordingConnection, ReleaseConnection, ReleaseGroupConnection, + SeriesConnection, WorkConnection } from '../types' import { toWords } from '../types/helpers' @@ -19,7 +22,11 @@ function searchQuery (connectionType) { type: connectionType, description: `Search for ${typeName} entities matching the given query.`, args: { - query: { type: new GraphQLNonNull(GraphQLString) }, + query: { + type: new GraphQLNonNull(GraphQLString), + description: `The query terms, in Lucene search syntax. See [examples +and search fields](https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2/Search).` + }, ...forwardConnectionArgs }, resolve: searchResolver() @@ -32,11 +39,14 @@ export const SearchQuery = new GraphQLObjectType({ fields: { areas: searchQuery(AreaConnection), artists: searchQuery(ArtistConnection), + events: searchQuery(EventConnection), + instruments: searchQuery(InstrumentConnection), labels: searchQuery(LabelConnection), places: searchQuery(PlaceConnection), recordings: searchQuery(RecordingConnection), releases: searchQuery(ReleaseConnection), releaseGroups: searchQuery(ReleaseGroupConnection), + series: searchQuery(SeriesConnection), works: searchQuery(WorkConnection) } }) diff --git a/src/resolvers.js b/src/resolvers.js index a125cc5..e7fb6a7 100644 --- a/src/resolvers.js +++ b/src/resolvers.js @@ -12,6 +12,12 @@ export function includeRelationships (params, info) { if (fields.relationships) { fields = getFields(fields.relationships) } else { + if (fields.edges) { + fields = getFields(fields.edges) + if (fields.node) { + return includeRelationships(params, fields.node) + } + } return params } } @@ -31,11 +37,27 @@ export function includeRelationships (params, info) { } export function includeSubqueries (params, info) { - const fields = getFields(info) - if (fields.artistCredit) { - params = { - ...params, - inc: extendIncludes(params.inc, ['artist-credits']) + const subqueryIncludes = { + aliases: 'aliases', + artistCredit: 'artist-credits', + tags: 'tags' + } + let fields = getFields(info) + const include = [] + for (const key in subqueryIncludes) { + if (fields[key]) { + const value = subqueryIncludes[key] + include.push(value) + } + } + params = { + ...params, + inc: extendIncludes(params.inc, include) + } + if (fields.edges) { + fields = getFields(fields.edges) + if (fields.node) { + params = includeSubqueries(params, fields.node) } } return params @@ -44,7 +66,8 @@ export function includeSubqueries (params, info) { export function lookupResolver () { return (root, { mbid }, { loaders }, info) => { const entityType = toDashed(info.fieldName) - const params = includeRelationships({}, info) + let params = includeSubqueries({}, info) + params = includeRelationships(params, info) return loaders.lookup.load([entityType, mbid, params]) } } @@ -58,7 +81,7 @@ export function browseResolver () { type, status, limit: first, - offset: getOffsetWithDefault(after, 0) + offset: getOffsetWithDefault(after, -1) + 1 } params = includeSubqueries(params, info) params = includeRelationships(params, info) @@ -74,18 +97,24 @@ export function browseResolver () { [`${singularName}-count`]: arrayLength } = list const meta = { sliceStart, arrayLength } - return connectionFromArraySlice(arraySlice, { first, after }, meta) + return { + totalCount: arrayLength, + ...connectionFromArraySlice(arraySlice, { first, after }, meta) + } }) } } export function searchResolver () { - return (source, { first = 25, after, ...args }, { loaders }, info) => { + return (source, { first = 25, after, query, ...args }, { loaders }, info) => { const pluralName = toDashed(info.fieldName) const singularName = toSingular(pluralName) - const { query, ...params } = args - params.limit = first - params.offset = getOffsetWithDefault(after, 0) + let params = { + ...args, + limit: first, + offset: getOffsetWithDefault(after, -1) + 1 + } + params = includeSubqueries(params, info) return loaders.search.load([singularName, query, params]).then(list => { const { [pluralName]: arraySlice, @@ -93,7 +122,10 @@ export function searchResolver () { count: arrayLength } = list const meta = { sliceStart, arrayLength } - return connectionFromArraySlice(arraySlice, { first, after }, meta) + return { + totalCount: arrayLength, + ...connectionFromArraySlice(arraySlice, { first, after }, meta) + } }) } } @@ -117,7 +149,10 @@ export function relationshipResolver () { } return true }) - return connectionFromArray(relationships, args) + return { + totalCount: relationships.length, + ...connectionFromArray(relationships, args) + } } } @@ -128,3 +163,25 @@ export function linkedResolver () { return browseResolver()(source, args, context, info) } } + +const noop = value => value + +/** + * If we weren't smart enough or weren't able to include the `inc` parameter + * for a particular field that's being requested, make another request to grab + * it (after making sure it isn't already available). + */ +export function subqueryResolver (includeValue, handler = noop) { + return (source, args, { loaders }, info) => { + const key = toDashed(info.fieldName) + if (key in source || (source._inc && source._inc.indexOf(key) !== -1)) { + return handler(source[key], args) + } else { + const { _type: entityType, id } = source + const params = { inc: [includeValue || key] } + return loaders.lookup.load([entityType, id, params]).then(entity => { + return handler(entity[key], args) + }) + } + } +} diff --git a/src/types/area.js b/src/types/area.js index a7e7ad3..b6d3e34 100644 --- a/src/types/area.js +++ b/src/types/area.js @@ -1,5 +1,4 @@ import { GraphQLObjectType, GraphQLString, GraphQLList } from 'graphql' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { @@ -8,11 +7,15 @@ import { name, sortName, disambiguation, + aliases, artists, events, labels, places, - releases + releases, + relationships, + tags, + connectionWithCount } from './helpers' const Area = new GraphQLObjectType({ @@ -26,6 +29,7 @@ or settlements (countries, cities, or the like).`, name, sortName, disambiguation, + aliases, isoCodes: { type: new GraphQLList(GraphQLString), description: `[ISO 3166 codes](https://en.wikipedia.org/wiki/ISO_3166) are @@ -36,10 +40,11 @@ the codes assigned by ISO to countries and subdivisions.`, events, labels, places, - releases + releases, + relationships, + tags }) }) -const { connectionType: AreaConnection } = connectionDefinitions({ nodeType: Area }) -export { AreaConnection } +export const AreaConnection = connectionWithCount(Area) export default Area diff --git a/src/types/artist-credit.js b/src/types/artist-credit.js index a539ede..9926ba3 100644 --- a/src/types/artist-credit.js +++ b/src/types/artist-credit.js @@ -16,7 +16,7 @@ credits.`, resolve: (source) => { const { artist } = source if (artist) { - artist.entityType = 'artist' + artist._type = 'artist' } return artist } diff --git a/src/types/artist.js b/src/types/artist.js index b7e4351..ea0afcc 100644 --- a/src/types/artist.js +++ b/src/types/artist.js @@ -1,8 +1,6 @@ -import { GraphQLObjectType, GraphQLString, GraphQLList } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' +import { GraphQLObjectType, GraphQLString } from 'graphql/type' import Node from './node' import Entity from './entity' -import Alias from './alias' import Area from './area' import { getFallback, @@ -12,12 +10,15 @@ import { name, sortName, disambiguation, + aliases, lifeSpan, recordings, releases, releaseGroups, works, - relationships + relationships, + tags, + connectionWithCount } from './helpers' const Artist = new GraphQLObjectType({ @@ -34,23 +35,7 @@ even a fictional character.`, name, sortName, disambiguation, - aliases: { - type: new GraphQLList(Alias), - description: `[Aliases](https://musicbrainz.org/doc/Aliases) are used to -store alternate names or misspellings.`, - resolve: (source, args, { loaders }, info) => { - const key = 'aliases' - if (key in source) { - return source[key] - } else { - const { entityType, id } = source - const params = { inc: ['aliases'] } - return loaders.lookup.load([entityType, id, params]).then(entity => { - return entity[key] - }) - } - } - }, + aliases, country: { type: GraphQLString, description: `The country with which an artist is primarily identified. It @@ -85,10 +70,10 @@ neither. Groups do not have genders.` releases, releaseGroups, works, - relationships + relationships, + tags }) }) -const { connectionType: ArtistConnection } = connectionDefinitions({ nodeType: Artist }) -export { ArtistConnection } +export const ArtistConnection = connectionWithCount(Artist) export default Artist diff --git a/src/types/entity.js b/src/types/entity.js index 2f0c0dc..7a1da6a 100644 --- a/src/types/entity.js +++ b/src/types/entity.js @@ -5,11 +5,9 @@ export default new GraphQLInterfaceType({ name: 'Entity', description: 'An entity in the MusicBrainz schema.', resolveType (value) { - if (value.entityType && require.resolve(`./${value.entityType}`)) { - return require(`./${value.entityType}`).default + if (value._type && require.resolve(`./${value._type}`)) { + return require(`./${value._type}`).default } }, - fields: () => ({ - mbid - }) + fields: () => ({ mbid }) }) diff --git a/src/types/event.js b/src/types/event.js index 981327e..a8392c9 100644 --- a/src/types/event.js +++ b/src/types/event.js @@ -1,5 +1,4 @@ import { GraphQLObjectType, GraphQLString, GraphQLBoolean } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { Time } from './scalars' @@ -9,7 +8,11 @@ import { mbid, name, disambiguation, - lifeSpan + aliases, + lifeSpan, + relationships, + tags, + connectionWithCount } from './helpers' const Event = new GraphQLObjectType({ @@ -23,6 +26,7 @@ Generally this means live performances, like concerts and festivals.`, mbid, name, disambiguation, + aliases, lifeSpan, time: { type: Time, @@ -40,10 +44,11 @@ for syntax and examples.` }, ...fieldWithID('type', { description: 'What kind of event the event is, e.g. concert, festival, etc.' - }) + }), + relationships, + tags }) }) -const { connectionType: EventConnection } = connectionDefinitions({ nodeType: Event }) -export { EventConnection } +export const EventConnection = connectionWithCount(Event) export default Event diff --git a/src/types/helpers.js b/src/types/helpers.js index 8fd70f3..d43ae99 100644 --- a/src/types/helpers.js +++ b/src/types/helpers.js @@ -3,16 +3,20 @@ import pascalCase from 'pascalcase' import { GraphQLObjectType, GraphQLString, + GraphQLInt, GraphQLList, GraphQLNonNull } from 'graphql' import { globalIdField, connectionArgs, + connectionDefinitions, + connectionFromArray, forwardConnectionArgs } from 'graphql-relay' import { MBID } from './scalars' import { ReleaseGroupType, ReleaseStatus } from './enums' +import Alias from './alias' import ArtistCredit from './artist-credit' import { ArtistConnection } from './artist' import { EventConnection } from './event' @@ -23,10 +27,12 @@ import { RecordingConnection } from './recording' import { RelationshipConnection } from './relationship' import { ReleaseConnection } from './release' import { ReleaseGroupConnection } from './release-group' +import { TagConnection } from './tag' import { WorkConnection } from './work' import { linkedResolver, relationshipResolver, + subqueryResolver, includeRelationships } from '../resolvers' @@ -119,16 +125,17 @@ meaning depends on the type of entity.`, resolve: getHyphenated } -function linkedQuery (connectionType, args) { - const typeName = toWords(connectionType.name.slice(0, -10)) +function linkedQuery (connectionType, { args, ...config } = {}) { + const typeName = toPlural(toWords(connectionType.name.slice(0, -10))) return { type: connectionType, - description: `A list of ${typeName} entities linked to this entity.`, + description: `A list of ${typeName} linked to this entity.`, args: { ...forwardConnectionArgs, ...args }, - resolve: linkedResolver() + resolve: linkedResolver(), + ...config } } @@ -181,21 +188,17 @@ export const relationships = { } } +export const aliases = { + type: new GraphQLList(Alias), + description: `[Aliases](https://musicbrainz.org/doc/Aliases) are used to store +alternate names or misspellings.`, + resolve: subqueryResolver() +} + export const artistCredit = { type: new GraphQLList(ArtistCredit), description: 'The main credited artist(s).', - resolve: (source, args, { loaders }, info) => { - const key = 'artist-credit' - if (key in source) { - return source[key] - } else { - const { entityType, id } = source - const params = { inc: ['artists'] } - return loaders.lookup.load([entityType, id, params]).then(entity => { - return entity[key] - }) - } - } + resolve: subqueryResolver() } export const artists = linkedQuery(ArtistConnection) @@ -204,10 +207,33 @@ export const labels = linkedQuery(LabelConnection) export const places = linkedQuery(PlaceConnection) export const recordings = linkedQuery(RecordingConnection) export const releases = linkedQuery(ReleaseConnection, { - type: { type: new GraphQLList(ReleaseGroupType) }, - status: { type: new GraphQLList(ReleaseStatus) } + args: { + type: { type: new GraphQLList(ReleaseGroupType) }, + status: { type: new GraphQLList(ReleaseStatus) } + } }) export const releaseGroups = linkedQuery(ReleaseGroupConnection, { - type: { type: new GraphQLList(ReleaseGroupType) } + args: { + type: { type: new GraphQLList(ReleaseGroupType) } + } +}) +export const tags = linkedQuery(TagConnection, { + resolve: subqueryResolver('tags', (value = [], args) => ({ + totalCount: value.length, + ...connectionFromArray(value, args) + })) }) export const works = linkedQuery(WorkConnection) + +export const totalCount = { + type: GraphQLInt, + description: `A count of the total number of items in this connection, +ignoring pagination.` +} + +export function connectionWithCount (nodeType) { + return connectionDefinitions({ + nodeType, + connectionFields: () => ({ totalCount }) + }).connectionType +} diff --git a/src/types/index.js b/src/types/index.js index b306b19..696694e 100644 --- a/src/types/index.js +++ b/src/types/index.js @@ -5,12 +5,13 @@ export { default as Entity } from './entity' export { default as Area, AreaConnection } from './area' export { default as Artist, ArtistConnection } from './artist' export { default as Event, EventConnection } from './event' -export { default as Instrument } from './instrument' +export { default as Instrument, InstrumentConnection } from './instrument' export { default as Label, LabelConnection } from './label' export { default as Place, PlaceConnection } from './place' export { default as Recording, RecordingConnection } from './recording' export { default as Release, ReleaseConnection } from './release' export { default as ReleaseGroup, ReleaseGroupConnection } from './release-group' export { default as Series, SeriesConnection } from './series' +export { default as Tag, TagConnection } from './tag' export { default as URL, URLConnection } from './url' export { default as Work, WorkConnection } from './work' diff --git a/src/types/instrument.js b/src/types/instrument.js index e2a12e0..711153c 100644 --- a/src/types/instrument.js +++ b/src/types/instrument.js @@ -6,7 +6,11 @@ import { id, mbid, name, - disambiguation + disambiguation, + aliases, + relationships, + tags, + connectionWithCount } from './helpers' const Instrument = new GraphQLObjectType({ @@ -20,6 +24,7 @@ used in relationships between two other entities.`, mbid, name, disambiguation, + aliases, description: { type: GraphQLString, description: `A brief description of the main characteristics of the @@ -29,8 +34,11 @@ instrument.` description: `The type categorises the instrument by the way the sound is created, similar to the [Hornbostel-Sachs](https://en.wikipedia.org/wiki/Hornbostel%E2%80%93Sachs) classification.` - }) + }), + relationships, + tags }) }) +export const InstrumentConnection = connectionWithCount(Instrument) export default Instrument diff --git a/src/types/label.js b/src/types/label.js index 50de1bc..b0a5a99 100644 --- a/src/types/label.js +++ b/src/types/label.js @@ -4,7 +4,6 @@ import { GraphQLString, GraphQLInt } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { IPI } from './scalars' @@ -15,9 +14,13 @@ import { name, sortName, disambiguation, + aliases, lifeSpan, releases, - fieldWithID + relationships, + tags, + fieldWithID, + connectionWithCount } from './helpers' const Label = new GraphQLObjectType({ @@ -32,6 +35,7 @@ represent a record company.`, name, sortName, disambiguation, + aliases, country: { type: GraphQLString, description: 'The country of origin for the label.' @@ -55,10 +59,11 @@ label.` description: `A type describing the main activity of the label, e.g. imprint, production, distributor, rights society, etc.` }), - releases + releases, + relationships, + tags }) }) -const { connectionType: LabelConnection } = connectionDefinitions({ nodeType: Label }) -export { LabelConnection } +export const LabelConnection = connectionWithCount(Label) export default Label diff --git a/src/types/node.js b/src/types/node.js index 14ebdcc..375bebc 100644 --- a/src/types/node.js +++ b/src/types/node.js @@ -8,9 +8,8 @@ const { nodeInterface, nodeField } = nodeDefinitions( return loaders.lookup.load([entityType, id]) }, (obj) => { - console.log(obj.entityType) try { - return require(`./${obj.entityType}`).default + return require(`./${obj._type}`).default } catch (err) { console.error(err) return null diff --git a/src/types/place.js b/src/types/place.js index 4abf618..1659f07 100644 --- a/src/types/place.js +++ b/src/types/place.js @@ -1,5 +1,4 @@ import { GraphQLObjectType, GraphQLString } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { Degrees } from './scalars' @@ -9,9 +8,13 @@ import { mbid, name, disambiguation, + aliases, lifeSpan, events, - fieldWithID + fieldWithID, + relationships, + tags, + connectionWithCount } from './helpers' export const Coordinates = new GraphQLObjectType({ @@ -39,6 +42,7 @@ or other place where music is performed, recorded, engineered, etc.`, mbid, name, disambiguation, + aliases, address: { type: GraphQLString, description: `The address describes the location of the place using the @@ -58,10 +62,11 @@ which the place is located.` description: `The type categorises the place based on its primary function.` }), - events + events, + relationships, + tags }) }) -const { connectionType: PlaceConnection } = connectionDefinitions({ nodeType: Place }) -export { PlaceConnection } +export const PlaceConnection = connectionWithCount(Place) export default Place diff --git a/src/types/recording.js b/src/types/recording.js index e8a8bf5..dc123ed 100644 --- a/src/types/recording.js +++ b/src/types/recording.js @@ -1,5 +1,4 @@ import { GraphQLObjectType, GraphQLInt, GraphQLBoolean } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { @@ -7,10 +6,13 @@ import { mbid, title, disambiguation, + aliases, artistCredit, artists, releases, - relationships + relationships, + tags, + connectionWithCount } from './helpers' const Recording = new GraphQLObjectType({ @@ -33,6 +35,7 @@ or mixing.`, mbid, title, disambiguation, + aliases, artistCredit, length: { type: GraphQLInt, @@ -45,10 +48,10 @@ from the lengths of the tracks using it.` }, artists, releases, - relationships + relationships, + tags }) }) -const { connectionType: RecordingConnection } = connectionDefinitions({ nodeType: Recording }) -export { RecordingConnection } +export const RecordingConnection = connectionWithCount(Recording) export default Recording diff --git a/src/types/relationship.js b/src/types/relationship.js index 462181c..8bb62b1 100644 --- a/src/types/relationship.js +++ b/src/types/relationship.js @@ -5,12 +5,12 @@ import { GraphQLList, GraphQLBoolean } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import { DateType } from './scalars' import Entity from './entity' import { getHyphenated, - fieldWithID + fieldWithID, + connectionWithCount } from './helpers' const Relationship = new GraphQLObjectType({ @@ -25,7 +25,7 @@ other and to URLs outside MusicBrainz.`, resolve: source => { const targetType = source['target-type'] const target = source[targetType] - target.entityType = targetType.replace('_', '-') + target._type = targetType.replace('_', '-') return target } }, @@ -78,6 +78,5 @@ relationship type.` }) }) -const { connectionType: RelationshipConnection } = connectionDefinitions({ nodeType: Relationship }) -export { RelationshipConnection } +export const RelationshipConnection = connectionWithCount(Relationship) export default Relationship diff --git a/src/types/release-group.js b/src/types/release-group.js index e1f59cf..0461eab 100644 --- a/src/types/release-group.js +++ b/src/types/release-group.js @@ -1,5 +1,4 @@ import { GraphQLObjectType, GraphQLList } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { DateType } from './scalars' @@ -9,12 +8,15 @@ import { mbid, title, disambiguation, + aliases, artistCredit, artists, releases, relationships, + tags, + fieldWithID, getHyphenated, - fieldWithID + connectionWithCount } from './helpers' const ReleaseGroup = new GraphQLObjectType({ @@ -33,6 +35,7 @@ album – it doesn’t matter how many CDs or editions/versions it had.`, mbid, title, disambiguation, + aliases, artistCredit, firstReleaseDate: { type: DateType, @@ -53,10 +56,10 @@ that apply to this release group.` }), artists, releases, - relationships + relationships, + tags }) }) -const { connectionType: ReleaseGroupConnection } = connectionDefinitions({ nodeType: ReleaseGroup }) -export { ReleaseGroupConnection } +export const ReleaseGroupConnection = connectionWithCount(ReleaseGroup) export default ReleaseGroup diff --git a/src/types/release.js b/src/types/release.js index 93ecd57..2b642a5 100644 --- a/src/types/release.js +++ b/src/types/release.js @@ -1,5 +1,4 @@ import { GraphQLObjectType, GraphQLString, GraphQLList } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { DateType } from './scalars' @@ -10,14 +9,17 @@ import { mbid, title, disambiguation, + aliases, artistCredit, artists, labels, recordings, releaseGroups, relationships, + tags, + fieldWithID, getHyphenated, - fieldWithID + connectionWithCount } from './helpers' const Release = new GraphQLObjectType({ @@ -33,6 +35,7 @@ MusicBrainz as one release.`, mbid, title, disambiguation, + aliases, artistCredit, releaseEvents: { type: new GraphQLList(ReleaseEvent), @@ -75,10 +78,10 @@ It is not a mark of how good or bad the music itself is – for that, use labels, recordings, releaseGroups, - relationships + relationships, + tags }) }) -const { connectionType: ReleaseConnection } = connectionDefinitions({ nodeType: Release }) -export { ReleaseConnection } +export const ReleaseConnection = connectionWithCount(Release) export default Release diff --git a/src/types/series.js b/src/types/series.js index 5c853fa..129a60f 100644 --- a/src/types/series.js +++ b/src/types/series.js @@ -1,8 +1,16 @@ import { GraphQLObjectType } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' -import { id, mbid, name, disambiguation, fieldWithID } from './helpers' +import { + id, + mbid, + name, + disambiguation, + relationships, + tags, + fieldWithID, + connectionWithCount +} from './helpers' const Series = new GraphQLObjectType({ name: 'Series', @@ -18,10 +26,11 @@ theme.`, ...fieldWithID('type', { description: `The type primarily describes what type of entity the series contains.` - }) + }), + relationships, + tags }) }) -const { connectionType: SeriesConnection } = connectionDefinitions({ nodeType: Series }) -export { SeriesConnection } +export const SeriesConnection = connectionWithCount(Series) export default Series diff --git a/src/types/tag.js b/src/types/tag.js new file mode 100644 index 0000000..f0853d2 --- /dev/null +++ b/src/types/tag.js @@ -0,0 +1,27 @@ +import { + GraphQLObjectType, + GraphQLNonNull, + GraphQLString, + GraphQLInt +} from 'graphql/type' +import { connectionWithCount } from './helpers' + +const Tag = new GraphQLObjectType({ + name: 'Tag', + description: `[Tags](https://musicbrainz.org/tags) are a way mark entities +with extra information – for example, the genres that apply to an artist, +release, or recording.`, + fields: () => ({ + name: { + type: new GraphQLNonNull(GraphQLString), + description: 'The tag label.' + }, + count: { + type: GraphQLInt, + description: 'How many times this tag has been applied to the entity.' + } + }) +}) + +export const TagConnection = connectionWithCount(Tag) +export default Tag diff --git a/src/types/url.js b/src/types/url.js index 198583c..ce17152 100644 --- a/src/types/url.js +++ b/src/types/url.js @@ -1,9 +1,8 @@ import { GraphQLObjectType, GraphQLNonNull } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { URLString } from './scalars' -import { id, mbid, relationships } from './helpers' +import { id, mbid, relationships, connectionWithCount } from './helpers' const URL = new GraphQLObjectType({ name: 'URL', @@ -22,6 +21,5 @@ acquired, an entry in another database, etc.`, }) }) -const { connectionType: URLConnection } = connectionDefinitions({ nodeType: URL }) -export { URLConnection } +export const URLConnection = connectionWithCount(URL) export default URL diff --git a/src/types/work.js b/src/types/work.js index 6dfbcd3..9cf5ba6 100644 --- a/src/types/work.js +++ b/src/types/work.js @@ -1,5 +1,4 @@ import { GraphQLObjectType, GraphQLString, GraphQLList } from 'graphql/type' -import { connectionDefinitions } from 'graphql-relay' import Node from './node' import Entity from './entity' import { @@ -7,9 +6,12 @@ import { mbid, title, disambiguation, + aliases, artists, relationships, - fieldWithID + tags, + fieldWithID, + connectionWithCount } from './helpers' const Work = new GraphQLObjectType({ @@ -23,6 +25,7 @@ more audio recordings.`, mbid, title, disambiguation, + aliases, iswcs: { type: new GraphQLList(GraphQLString), description: `A list of [ISWCs](https://musicbrainz.org/doc/ISWC) assigned @@ -36,10 +39,10 @@ to the work by copyright collecting agencies.` description: 'The type of work.' }), artists, - relationships + relationships, + tags }) }) -const { connectionType: WorkConnection } = connectionDefinitions({ nodeType: Work }) -export { WorkConnection } +export const WorkConnection = connectionWithCount(Work) export default Work