Files
speckle-server/modules/core/graph/resolvers/branches.js
T
izzy lyseggen c406abe5ec feat(subs): subs for branch & commit mutations 🥳
also applied @hasRole and @hasScope directives to mutations in this schema
2020-08-19 15:46:40 +01:00

125 lines
4.1 KiB
JavaScript

'use strict'
const appRoot = require( 'app-root-path' )
const { ForbiddenError, ApolloError, withFilter } = require( 'apollo-server-express' )
const { validateServerRole, validateScopes, authorizeResolver, pubsub } = require( `${appRoot}/modules/shared` )
const {
createBranch,
updateBranch,
getBranchById,
getBranchesByStreamId,
getBranchByNameAndStreamId,
deleteBranchById
} = require( '../../services/branches' )
const { getUserById } = require( '../../services/users' )
// subscription events
const BRANCH_CREATED = 'BRANCH_CREATED'
const BRANCH_UPDATED = 'BRANCH_UPDATED'
const BRANCH_DELETED = 'BRANCH_DELETED'
module.exports = {
Query: {},
Stream: {
async branches( parent, args, context, info ) {
if ( args.limit && args.limit > 100 )
throw new UserInputError( 'Cannot return more than 100 items, please use pagination.' )
let { items, cursor, totalCount } = await getBranchesByStreamId( { streamId: parent.id, limit: args.limit, cursor: args.cursor } )
return { totalCount, cursor, items }
},
async branch( parent, args, context, info ) {
return await getBranchByNameAndStreamId( { streamId: parent.id, name: args.name } )
},
},
Branch: {
async author( parent, args, context, info ) {
return await getUserById( { userId: parent.authorId } )
}
},
Mutation: {
async branchCreate( parent, args, context, info ) {
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
await authorizeResolver( context.userId, args.branch.streamId, 'stream:contributor' )
let id = await createBranch( { ...args.branch, authorId: context.userId } )
if ( id ) {
await pubsub.publish( BRANCH_CREATED, {
branchCreated: { ...args.branch, id: id, authorId: context.userId },
streamId: args.branch.streamId } )
}
return id
},
async branchUpdate( parent, args, context, info ) {
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
await authorizeResolver( context.userId, args.branch.streamId, 'stream:contributor' )
let updated = await updateBranch( { ...args.branch } )
if ( updated ) {
await pubsub.publish( BRANCH_UPDATED, {
branchUpdated: { ...args.branch },
streamId: args.branch.streamId,
branchId: args.branch.id
} )
}
return updated
},
async branchDelete( parent, args, context, info ) {
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
let role = await authorizeResolver( context.userId, args.branch.streamId, 'stream:contributor' )
let branch = await getBranchById( { id: args.branch.id } )
if ( !branch ) {
throw new ApolloError( 'Branch not found.' )
}
if ( branch.authorId !== context.userId && role !== 'stream:owner' )
throw new ForbiddenError( 'Only the branch creator or stream owners are allowed to delete branches.' )
let deleted = await deleteBranchById( { id: args.branch.id } )
if ( deleted ) {
await pubsub.publish( BRANCH_DELETED, { branchDeleted: { ...args.branch }, streamId: args.branch.streamId } )
}
return deleted
}
},
Subscription: {
branchCreated: {
subscribe: withFilter( () => pubsub.asyncIterator( [ BRANCH_CREATED ] ),
( payload, variables ) => {
return payload.streamId === variables.streamId
} )
},
branchUpdated: {
subscribe: withFilter( () => pubsub.asyncIterator( [ BRANCH_UPDATED ] ),
( payload, variables ) => {
let streamMatch = payload.streamId === variables.streamId
if ( streamMatch && variables.branchId ) {
return payload.branchId === variables.branchId
}
return streamMatch
} )
},
branchDeleted: {
subscribe: withFilter( () => pubsub.asyncIterator( [ BRANCH_DELETED ] ),
( payload, variables ) => {
return payload.streamId === variables.streamId
} )
}
}
}