204 lines
5.6 KiB
JavaScript
204 lines
5.6 KiB
JavaScript
import { DollarApollo } from './dollar-apollo'
|
|
import { ApolloProvider as apolloProvider } from './apollo-provider'
|
|
import CApolloQuery from './components/ApolloQuery'
|
|
import CApolloSubscribeToMore from './components/ApolloSubscribeToMore'
|
|
import CApolloMutation from './components/ApolloMutation'
|
|
import { Globals, omit } from './utils'
|
|
|
|
const keywords = [
|
|
'$subscribe',
|
|
]
|
|
|
|
function hasProperty (holder, key) {
|
|
return typeof holder !== 'undefined' && holder.hasOwnProperty(key)
|
|
}
|
|
|
|
const launch = function launch () {
|
|
const apolloProvider = this.$apolloProvider
|
|
|
|
if (this._apolloLaunched || !apolloProvider) return
|
|
this._apolloLaunched = true
|
|
|
|
// Prepare properties
|
|
let apollo = this.$options.apollo
|
|
|
|
if (apollo) {
|
|
if (!apollo.$init) {
|
|
apollo.$init = true
|
|
|
|
// Default options applied to `apollo` options
|
|
if (apolloProvider.defaultOptions) {
|
|
apollo = this.$options.apollo = Object.assign({}, apolloProvider.defaultOptions, apollo)
|
|
}
|
|
}
|
|
|
|
defineReactiveSetter(this.$apollo, 'skipAll', apollo.$skipAll, apollo.$deep)
|
|
defineReactiveSetter(this.$apollo, 'skipAllQueries', apollo.$skipAllQueries, apollo.$deep)
|
|
defineReactiveSetter(this.$apollo, 'skipAllSubscriptions', apollo.$skipAllSubscriptions, apollo.$deep)
|
|
defineReactiveSetter(this.$apollo, 'client', apollo.$client, apollo.$deep)
|
|
defineReactiveSetter(this.$apollo, 'loadingKey', apollo.$loadingKey, apollo.$deep)
|
|
defineReactiveSetter(this.$apollo, 'error', apollo.$error, apollo.$deep)
|
|
defineReactiveSetter(this.$apollo, 'watchLoading', apollo.$watchLoading, apollo.$deep)
|
|
|
|
// Apollo Data
|
|
Object.defineProperty(this, '$apolloData', {
|
|
get: () => this.$data.$apolloData,
|
|
enumerable: true,
|
|
configurable: true,
|
|
})
|
|
|
|
// watchQuery
|
|
for (let key in apollo) {
|
|
if (key.charAt(0) !== '$') {
|
|
let options = apollo[key]
|
|
// Default options from component
|
|
if (apollo.$query) {
|
|
options = Object.assign({}, apollo.$query, options)
|
|
}
|
|
// Property proxy
|
|
if (!hasProperty(this, key) && !hasProperty(this.$props, key) && !hasProperty(this.$data, key)) {
|
|
Object.defineProperty(this, key, {
|
|
get: () => this.$data.$apolloData.data[key],
|
|
enumerable: true,
|
|
configurable: true,
|
|
})
|
|
}
|
|
this.$apollo.addSmartQuery(key, options)
|
|
}
|
|
}
|
|
|
|
if (apollo.subscribe) {
|
|
Globals.Vue.util.warn('vue-apollo -> `subscribe` option is deprecated. Use the `$subscribe` option instead.')
|
|
}
|
|
|
|
if (apollo.$subscribe) {
|
|
for (let key in apollo.$subscribe) {
|
|
this.$apollo.addSmartSubscription(key, apollo.$subscribe[key])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function defineReactiveSetter ($apollo, key, value) {
|
|
if (typeof value !== 'undefined') {
|
|
if (typeof value === 'function') {
|
|
$apollo.defineReactiveSetter(key, value)
|
|
} else {
|
|
$apollo[key] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
export function install (Vue, options) {
|
|
if (install.installed) return
|
|
install.installed = true
|
|
|
|
Globals.Vue = Vue
|
|
|
|
// Options merging
|
|
const merge = Vue.config.optionMergeStrategies.methods
|
|
Vue.config.optionMergeStrategies.apollo = function (toVal, fromVal, vm) {
|
|
if (!toVal) return fromVal
|
|
if (!fromVal) return toVal
|
|
|
|
const toData = Object.assign({}, omit(toVal, keywords), toVal.data)
|
|
const fromData = Object.assign({}, omit(fromVal, keywords), fromVal.data)
|
|
|
|
const map = {}
|
|
for (let i = 0; i < keywords.length; i++) {
|
|
const key = keywords[i]
|
|
map[key] = merge(toVal[key], fromVal[key])
|
|
}
|
|
|
|
return Object.assign(map, merge(toData, fromData))
|
|
}
|
|
|
|
// Lazy creation
|
|
Object.defineProperty(Vue.prototype, '$apollo', {
|
|
get () {
|
|
if (!this._apollo) {
|
|
this._apollo = new DollarApollo(this)
|
|
}
|
|
return this._apollo
|
|
},
|
|
})
|
|
|
|
const vueVersion = Vue.version.substr(0, Vue.version.indexOf('.'))
|
|
|
|
Vue.mixin({
|
|
...vueVersion === '1' ? {
|
|
init () {
|
|
let apolloProvider
|
|
if (this.$options.apolloProvider) {
|
|
apolloProvider = this._apolloProvider = this.$options.apolloProvider
|
|
} else {
|
|
apolloProvider = this.$root._apolloProvider
|
|
}
|
|
this.$apolloProvider = apolloProvider
|
|
},
|
|
} : {},
|
|
|
|
...vueVersion === '2' ? {
|
|
inject: {
|
|
$apolloProvider: { default: null },
|
|
},
|
|
|
|
data () {
|
|
return {
|
|
'$apolloData': {
|
|
queries: {},
|
|
loading: 0,
|
|
data: {},
|
|
},
|
|
}
|
|
},
|
|
} : {},
|
|
|
|
created: launch,
|
|
|
|
destroyed: function () {
|
|
if (this._apollo) {
|
|
this._apollo.destroy()
|
|
this._apollo = null
|
|
}
|
|
},
|
|
|
|
})
|
|
|
|
if (vueVersion === '2') {
|
|
Vue.component('apollo-query', CApolloQuery)
|
|
Vue.component('ApolloQuery', CApolloQuery)
|
|
Vue.component('apollo-subscribe-to-more', CApolloSubscribeToMore)
|
|
Vue.component('ApolloSubscribeToMore', CApolloSubscribeToMore)
|
|
Vue.component('apollo-mutation', CApolloMutation)
|
|
Vue.component('ApolloMutation', CApolloMutation)
|
|
}
|
|
}
|
|
|
|
apolloProvider.install = install
|
|
|
|
// eslint-disable-next-line no-undef
|
|
apolloProvider.version = VERSION
|
|
|
|
// Apollo provider
|
|
export const ApolloProvider = apolloProvider
|
|
export { willPrefetch } from './apollo-provider'
|
|
|
|
// Components
|
|
export const ApolloQuery = CApolloQuery
|
|
export const ApolloSubscribeToMore = CApolloSubscribeToMore
|
|
export const ApolloMutation = CApolloMutation
|
|
|
|
// Auto-install
|
|
let GlobalVue = null
|
|
if (typeof window !== 'undefined') {
|
|
GlobalVue = window.Vue
|
|
} else if (typeof global !== 'undefined') {
|
|
GlobalVue = global.Vue
|
|
}
|
|
if (GlobalVue) {
|
|
GlobalVue.use(apolloProvider)
|
|
}
|
|
|
|
export default apolloProvider
|