mirror of
https://github.com/BradNut/graphbrainz
synced 2025-09-08 17:40:32 +00:00
Add tags, aliases, more optimized API calls, fix offset
This commit is contained in:
parent
8270397137
commit
092c37bad7
26 changed files with 2425 additions and 638 deletions
|
|
@ -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.
|
||||
|
|
|
|||
2244
schema.json
2244
schema.json
File diff suppressed because it is too large
Load diff
382
schema.md
382
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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ credits.`,
|
|||
resolve: (source) => {
|
||||
const { artist } = source
|
||||
if (artist) {
|
||||
artist.entityType = 'artist'
|
||||
artist._type = 'artist'
|
||||
}
|
||||
return artist
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
27
src/types/tag.js
Normal file
27
src/types/tag.js
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue