This commit is contained in:
Brian Beck 2016-08-31 21:31:48 -07:00
parent 8759943638
commit ed5339f2e1
9 changed files with 794 additions and 618 deletions

View file

@ -37,7 +37,7 @@ type Area implements Entity {
statuses: [ReleaseStatus]): [Release]
}
type AreaPage {
type AreaConnection {
count: Int!
offset: Int!
created: Date
@ -80,7 +80,7 @@ type ArtistCredit {
joinPhrase: String
}
type ArtistPage {
type ArtistConnection {
count: Int!
offset: Int!
created: Date
@ -94,23 +94,23 @@ type BrowseQuery {
recording: MBID,
release: MBID,
releaseGroup: MBID,
work: MBID): ArtistPage
work: MBID): ArtistConnection
events(limit: Int,
offset: Int,
area: MBID,
artist: MBID,
place: MBID): EventPage
place: MBID): EventConnection
labels(limit: Int,
offset: Int,
area: MBID,
release: MBID): LabelPage
release: MBID): LabelConnection
places(limit: Int,
offset: Int,
area: MBID): PlacePage
area: MBID): PlaceConnection
recordings(limit: Int,
offset: Int,
artist: MBID,
release: MBID): RecordingPage
release: MBID): RecordingConnection
releases(limit: Int,
offset: Int,
area: MBID,
@ -119,17 +119,17 @@ type BrowseQuery {
track: MBID,
trackArtist: MBID,
recording: MBID,
releaseGroup: MBID): ReleasePage
releaseGroup: MBID): ReleaseConnection
releaseGroups(limit: Int,
offset: Int,
artist: MBID,
release: MBID): ReleaseGroupPage
release: MBID): ReleaseGroupConnection
works(limit: Int,
offset: Int,
artist: MBID): WorkPage
artist: MBID): WorkConnection
urls(limit: Int,
offset: Int,
resource: URLString): URLPage
resource: URLString): URLConnection
}
type Coordinates {
@ -157,7 +157,7 @@ type Event implements Entity {
typeID: MBID
}
type EventPage {
type EventConnection {
count: Int!
offset: Int!
created: Date
@ -195,7 +195,7 @@ type Label implements Entity {
statuses: [ReleaseStatus]): [Release]
}
type LabelPage {
type LabelConnection {
count: Int!
offset: Int!
created: Date
@ -237,7 +237,7 @@ type Place implements Entity {
events(limit: Int, offset: Int): [Event]
}
type PlacePage {
type PlaceConnection {
count: Int!
offset: Int!
created: Date
@ -261,7 +261,7 @@ type Recording implements Entity {
relations: Relations
}
type RecordingPage {
type RecordingConnection {
count: Int!
offset: Int!
created: Date
@ -394,7 +394,7 @@ type ReleaseGroup implements Entity {
relations: Relations
}
type ReleaseGroupPage {
type ReleaseGroupConnection {
count: Int!
offset: Int!
created: Date
@ -420,7 +420,7 @@ enum ReleaseGroupType {
NAT
}
type ReleasePage {
type ReleaseConnection {
count: Int!
offset: Int!
created: Date
@ -441,14 +441,14 @@ type RootQuery {
}
type SearchQuery {
areas(query: String!, limit: Int, offset: Int): AreaPage
artists(query: String!, limit: Int, offset: Int): ArtistPage
labels(query: String!, limit: Int, offset: Int): LabelPage
places(query: String!, limit: Int, offset: Int): PlacePage
recordings(query: String!, limit: Int, offset: Int): RecordingPage
releases(query: String!, limit: Int, offset: Int): ReleasePage
releaseGroups(query: String!, limit: Int, offset: Int): ReleaseGroupPage
works(query: String!, limit: Int, offset: Int): WorkPage
areas(query: String!, limit: Int, offset: Int): AreaConnection
artists(query: String!, limit: Int, offset: Int): ArtistConnection
labels(query: String!, limit: Int, offset: Int): LabelConnection
places(query: String!, limit: Int, offset: Int): PlaceConnection
recordings(query: String!, limit: Int, offset: Int): RecordingConnection
releases(query: String!, limit: Int, offset: Int): ReleaseConnection
releaseGroups(query: String!, limit: Int, offset: Int): ReleaseGroupConnection
works(query: String!, limit: Int, offset: Int): WorkConnection
}
scalar Time
@ -459,7 +459,7 @@ type URL implements Entity {
relations: Relations
}
type URLPage {
type URLConnection {
count: Int!
offset: Int!
created: Date
@ -480,7 +480,7 @@ type Work implements Entity {
relations: Relations
}
type WorkPage {
type WorkConnection {
count: Int!
offset: Int!
created: Date

View file

@ -47,7 +47,7 @@
"pascalcase": "^0.1.1",
"qs": "^6.2.1",
"request": "^2.74.0",
"retry": "^0.9.0"
"retry": "^0.10.0"
},
"devDependencies": {
"babel-cli": "^6.11.4",
@ -59,7 +59,7 @@
"mocha": "^3.0.1",
"nodemon": "^1.10.2",
"snazzy": "^4.0.1",
"standard": "^7.1.2"
"standard": "^8.0.0"
},
"standard": {
"parser": "babel-eslint"

File diff suppressed because it is too large Load diff

View file

@ -2,15 +2,15 @@ import { GraphQLObjectType, GraphQLInt } from 'graphql'
import {
MBID,
URLString,
ArtistPage,
EventPage,
LabelPage,
PlacePage,
RecordingPage,
ReleasePage,
ReleaseGroupPage,
URLPage,
WorkPage
ArtistConnection,
EventConnection,
LabelConnection,
PlaceConnection,
RecordingConnection,
ReleaseConnection,
ReleaseGroupConnection,
URLConnection,
WorkConnection
} from '../types'
import { browseResolver } from '../resolvers'
@ -21,7 +21,7 @@ export default new GraphQLObjectType({
'to another entity.',
fields: {
artists: {
type: ArtistPage,
type: ArtistConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -34,7 +34,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
events: {
type: EventPage,
type: EventConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -45,7 +45,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
labels: {
type: LabelPage,
type: LabelConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -55,7 +55,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
places: {
type: PlacePage,
type: PlaceConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -64,7 +64,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
recordings: {
type: RecordingPage,
type: RecordingConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -74,7 +74,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
releases: {
type: ReleasePage,
type: ReleaseConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -89,7 +89,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
releaseGroups: {
type: ReleaseGroupPage,
type: ReleaseGroupConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -99,7 +99,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
works: {
type: WorkPage,
type: WorkConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },
@ -108,7 +108,7 @@ export default new GraphQLObjectType({
resolve: browseResolver()
},
urls: {
type: URLPage,
type: URLConnection,
args: {
limit: { type: GraphQLInt },
offset: { type: GraphQLInt },

View file

@ -1,13 +1,13 @@
import { GraphQLObjectType } from 'graphql'
import {
AreaPage,
ArtistPage,
LabelPage,
PlacePage,
RecordingPage,
ReleasePage,
ReleaseGroupPage,
WorkPage
AreaConnection,
ArtistConnection,
LabelConnection,
PlaceConnection,
RecordingConnection,
ReleaseConnection,
ReleaseGroupConnection,
WorkConnection
} from '../types'
import { searchQuery } from '../types/helpers'
@ -17,13 +17,13 @@ export default new GraphQLObjectType({
'Search queries provide a way to search for MusicBrainz entities using ' +
'Lucene query syntax.',
fields: {
areas: searchQuery(AreaPage),
artists: searchQuery(ArtistPage),
labels: searchQuery(LabelPage),
places: searchQuery(PlacePage),
recordings: searchQuery(RecordingPage),
releases: searchQuery(ReleasePage),
releaseGroups: searchQuery(ReleaseGroupPage),
works: searchQuery(WorkPage)
areas: searchQuery(AreaConnection),
artists: searchQuery(ArtistConnection),
labels: searchQuery(LabelConnection),
places: searchQuery(PlaceConnection),
recordings: searchQuery(RecordingConnection),
releases: searchQuery(ReleaseConnection),
releaseGroups: searchQuery(ReleaseGroupConnection),
works: searchQuery(WorkConnection)
}
})

View file

@ -1,4 +1,5 @@
import dashify from 'dashify'
import { toEntityType } from './types/helpers'
import { getOffsetWithDefault, connectionFromArraySlice } from 'graphql-relay'
import { getFields, extendIncludes } from './util'
export function includeRelations (params, info) {
@ -12,7 +13,7 @@ export function includeRelations (params, info) {
}
if (fields) {
const relations = Object.keys(fields)
const includeRels = relations.map(key => `${dashify(key)}-rels`)
const includeRels = relations.map(key => `${toEntityType(key)}-rels`)
if (includeRels.length) {
params = {
...params,
@ -37,14 +38,14 @@ export function includeSubqueries (params, info) {
export function lookupResolver (entityType, extraParams = {}) {
return (root, { id }, { lookupLoader }, info) => {
const params = includeRelations(extraParams, info)
entityType = entityType || dashify(info.fieldName)
entityType = entityType || toEntityType(info.fieldName)
return lookupLoader.load([entityType, id, params])
}
}
export function browseResolver () {
return (source, args, { browseLoader }, info) => {
const pluralName = dashify(info.fieldName)
const pluralName = toEntityType(info.fieldName)
let singularName = pluralName
if (pluralName.endsWith('s')) {
singularName = pluralName.slice(0, -1)
@ -56,13 +57,23 @@ export function browseResolver () {
export function searchResolver () {
return (source, args, { searchLoader }, info) => {
const pluralName = dashify(info.fieldName)
const pluralName = toEntityType(info.fieldName)
let singularName = pluralName
if (pluralName.endsWith('s')) {
singularName = pluralName.slice(0, -1)
}
const { query, ...params } = args
return searchLoader.load([singularName, query, params])
const { query, first, after, ...params } = args
params.limit = first
params.offset = getOffsetWithDefault(after, 0)
return searchLoader.load([singularName, query, params]).then(list => {
const {
[pluralName]: arraySlice,
offset: sliceStart,
count: arrayLength
} = list
const meta = { sliceStart, arrayLength }
return connectionFromArraySlice(arraySlice, { first, after }, meta)
})
}
}
@ -72,7 +83,7 @@ export function relationResolver () {
direction,
type,
typeID }, { lookupLoader }, info) => {
const targetType = dashify(info.fieldName).replace('-', '_')
const targetType = toEntityType(info.fieldName).replace('-', '_')
return source.filter(relation => {
if (relation['target-type'] !== targetType) {
return false
@ -93,12 +104,12 @@ export function relationResolver () {
export function linkedResolver () {
return (source, args, { browseLoader }, info) => {
const pluralName = dashify(info.fieldName)
const pluralName = toEntityType(info.fieldName)
let singularName = pluralName
if (pluralName.endsWith('s')) {
singularName = pluralName.slice(0, -1)
}
const parentEntity = dashify(info.parentType.name)
const parentEntity = toEntityType(info.parentType.name)
let params = {
[parentEntity]: source.id,
type: [],

View file

@ -7,7 +7,7 @@ import {
GraphQLList,
GraphQLNonNull
} from 'graphql'
import { globalIdField } from 'graphql-relay'
import { globalIdField, forwardConnectionArgs } from 'graphql-relay'
import { MBID } from './scalars'
import { ReleaseGroupType, ReleaseStatus } from './enums'
import ArtistCredit from './artist-credit'
@ -85,22 +85,22 @@ export function lookupQuery (entity, params) {
}
}
export function searchQuery (entityPage) {
const entity = entityPage.getFields().results.type.ofType.ofType
export function searchQuery (connectionType) {
return {
type: entityPage,
description: `Search for ${entity.name} entities.`,
type: connectionType,
args: {
query: { type: new GraphQLNonNull(GraphQLString) },
limit: { type: GraphQLInt },
offset: { type: GraphQLInt }
...forwardConnectionArgs
},
resolve: searchResolver()
}
}
export const id = globalIdField()
export const mbid = { type: new GraphQLNonNull(MBID) }
export const mbid = {
type: new GraphQLNonNull(MBID),
resolve: source => source.id
}
export const name = { type: GraphQLString }
export const sortName = { type: GraphQLString, resolve: getHyphenated }
export const title = { type: GraphQLString }

View file

@ -2,15 +2,15 @@ export { MBID, DateType, IPI, URLString } from './scalars'
export { ReleaseGroupType, ReleaseStatus } from './enums'
export { default as Node } from './node'
export { default as Entity } from './entity'
export { default as Area, AreaPage } from './area'
export { default as Artist, ArtistPage } from './artist'
export { default as Event, EventPage } from './event'
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 Label, LabelPage } from './label'
export { default as Place, PlacePage } from './place'
export { default as Recording, RecordingPage } from './recording'
export { default as Release, ReleasePage } from './release'
export { default as ReleaseGroup, ReleaseGroupPage } from './release-group'
export { default as Series, SeriesPage } from './series'
export { default as URL, URLPage } from './url'
export { default as Work, WorkPage } from './work'
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 URL, URLConnection } from './url'
export { default as Work, WorkConnection } from './work'

View file

@ -10,8 +10,9 @@ const { nodeInterface, nodeField } = nodeDefinitions(
},
(obj) => {
try {
return require(`./${obj.entityType}`)
return require(`./${obj.entityType}`).default
} catch (err) {
console.error(err)
return null
}
}