import Observable from 'zen-observable-ts' ; import { GraphQLRequest , Operation } from './types' ; import { ApolloLink } from './link' ; import { getOperationName } from 'apollo-utilities' ; import { invariant , InvariantError } from 'ts-invariant' ; export { getOperationName } ; export function validateOperation ( operation ) { const OPERATION_FIELDS = [ 'query' , 'operationName' , 'variables' , 'extensions' , 'context' , ] ; for ( let key of Object . keys ( operation ) ) { if ( OPERATION_FIELDS . indexOf ( key ) < 0 ) { throw new InvariantError ( `illegal argument: ${ key }` ) ; } } return operation ; } export class LinkError extends Error { public link : ApolloLink ; constructor ( message ? , link ? ) { super ( message ) ; this . link = link ; } } export function isTerminating ( link ) { return link . request . length <= 1 ; } export function toPromise < R > ( observable ) { let completed = false ; return new Promise < R > ( ( resolve , reject ) => { observable . subscribe ( { next : data => { if ( completed ) { invariant . warn ( `Promise Wrapper does not support multiple results from Observable` ) ; } else { completed = true ; resolve ( data ) ; } } , error : reject , } ) ; } ) ; } export const makePromise = toPromise ; export function fromPromise < T > ( promise ) { return new Observable < T > ( observer => { promise . then ( ( value ) => { observer . next ( value ) ; observer . complete ( ) ; } ) . catch ( observer . error . bind ( observer ) ) ; } ) ; } export function fromError < T > ( errorValue ) { return new Observable < T > ( observer => { observer . error ( errorValue ) ; } ) ; } export function transformOperation ( operation ) { const transformedOperation = { variables : operation . variables || { } , extensions : operation . extensions || { } , operationName : operation . operationName , query : operation . query , } ; if ( ! transformedOperation . operationName ) { transformedOperation . operationName = typeof transformedOperation . query !== 'string' ? getOperationName ( transformedOperation . query ) : '' ; } return transformedOperation as Operation ; } export function createOperation ( starting , operation ) { let context = { ... starting } ; const setContext = next => { if ( typeof next === 'function' ) { context = { ... context , ... next ( context ) } ; } else { context = { ... context , ... next } ; } } ; const getContext = ( ) => ( { ... context } ) ; Object . defineProperty ( operation , 'setContext' , { enumerable : false , value : setContext , } ) ; Object . defineProperty ( operation , 'getContext' , { enumerable : false , value : getContext , } ) ; Object . defineProperty ( operation , 'toKey' , { enumerable : false , value : ( ) => getKey ( operation ) , } ) ; return operation as Operation ; } export function getKey ( operation ) { const { query , variables , operationName } = operation ; return JSON . stringify ( [ operationName , query , variables ] ) ; }