diff --git a/packages/leaders-program/apollo/create-client.js b/packages/leaders-program/apollo/create-client.js
deleted file mode 100644
index 63f7ccef0..000000000
--- a/packages/leaders-program/apollo/create-client.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import { ApolloClient } from 'apollo-client';
-import { createHttpLink } from 'apollo-link-http';
-import { InMemoryCache } from 'apollo-cache-inmemory';
-import fragmentMatcher from './fragment-matcher';
-
-export default ({ uri, headers }) => new ApolloClient({
- link: createHttpLink({ uri, headers }),
- cache: new InMemoryCache({ fragmentMatcher }),
-});
diff --git a/packages/leaders-program/apollo/create-provider.js b/packages/leaders-program/apollo/create-provider.js
deleted file mode 100644
index ac7249359..000000000
--- a/packages/leaders-program/apollo/create-provider.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import VueApollo from 'vue-apollo';
-import createApolloClient from './create-client';
-
-export default ({
- graphqlUri,
- tenantKey,
- siteId,
- baseApiUri,
-} = {}) => {
- const apiUri = baseApiUri || window.location.origin;
- if (!graphqlUri || !tenantKey || !apiUri) {
- throw new Error('The graphqlUri, tenantKey, and baseApiUri options are required to create the BaseCMS Apollo Provider.');
- }
- const headers = {
- 'x-tenant-key': tenantKey,
- 'x-base4-api-uri': apiUri,
- };
- if (siteId) headers['x-site-id'] = siteId;
- return new VueApollo({
- defaultClient: createApolloClient({ uri: graphqlUri, headers }),
- });
-};
diff --git a/packages/leaders-program/apollo/fragment-matcher.js b/packages/leaders-program/apollo/fragment-matcher.js
deleted file mode 100644
index 98bb02f18..000000000
--- a/packages/leaders-program/apollo/fragment-matcher.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
-import introspectionQueryResultData from '@parameter1/base-cms-graphql-fragment-types';
-
-export default new IntrospectionFragmentMatcher({ introspectionQueryResultData });
diff --git a/packages/leaders-program/package.json b/packages/leaders-program/package.json
index a32aecb55..04269e989 100644
--- a/packages/leaders-program/package.json
+++ b/packages/leaders-program/package.json
@@ -14,12 +14,9 @@
},
"dependencies": {
"core-js": "^3.18.2",
- "graphql": "^14.7.0",
- "graphql-tag": "^2.12.5",
"object-path": "^0.11.8",
"portal-vue": "^2.1.7",
- "vue": "^2.6.14",
- "vue-apollo": "^3.0.8"
+ "vue": "^2.6.14"
},
"devDependencies": {
"@parameter1/base-cms-graphql-fragment-types": "^2.45.0",
@@ -27,10 +24,6 @@
"@vue/cli-plugin-eslint": "^4.5.13",
"@vue/cli-service": "^4.5.13",
"@vue/eslint-config-airbnb": "^4.0.1",
- "apollo-cache-inmemory": "^1.6.6",
- "apollo-client": "^2.6.10",
- "apollo-link": "^1.2.14",
- "apollo-link-http": "^1.5.17",
"babel-eslint": "^10.1.0",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
diff --git a/packages/leaders-program/public/index.html b/packages/leaders-program/public/index.html
index e2ebac24b..6f20dbb84 100644
--- a/packages/leaders-program/public/index.html
+++ b/packages/leaders-program/public/index.html
@@ -10,7 +10,7 @@
diff --git a/packages/leaders-program/src/components/containers/section.vue b/packages/leaders-program/src/components/containers/section.vue
index 8c9a85bba..f9e5de30c 100644
--- a/packages/leaders-program/src/components/containers/section.vue
+++ b/packages/leaders-program/src/components/containers/section.vue
@@ -58,6 +58,7 @@ import query from '../../graphql/queries/content-for-section';
import getEdgeNodes from '../../utils/get-edge-nodes';
export default {
+ inject: ['$graphql'],
components: {
PlusIcon,
MinusIcon,
@@ -197,7 +198,7 @@ export default {
promotionLimit: this.promotionLimit,
videoLimit: this.videoLimit,
};
- const { data } = await this.$apollo.query({ query, variables });
+ const { data } = await this.$graphql.query({ query, variables });
this.items = getEdgeNodes(data, 'websiteScheduledContent');
this.hasLoaded = true;
} catch (e) {
diff --git a/packages/leaders-program/src/components/leaders.vue b/packages/leaders-program/src/components/leaders.vue
index 90ed1b811..f4a3c8bf3 100644
--- a/packages/leaders-program/src/components/leaders.vue
+++ b/packages/leaders-program/src/components/leaders.vue
@@ -50,6 +50,7 @@ import getEdgeNodes from '../utils/get-edge-nodes';
import getAsObject from '../utils/get-as-object';
export default {
+ inject: ['$graphql'],
components: {
Loading,
LeadersHeader,
@@ -253,7 +254,7 @@ export default {
const { sectionIds } = this;
if (sectionIds && sectionIds.length) {
const variables = { sectionIds };
- const r = await this.$apollo.query({ query: fromIdsQuery, variables });
+ const r = await this.$graphql.query({ query: fromIdsQuery, variables });
const sections = getEdgeNodes(r, 'data.websiteSections')
.filter(s => s.hierarchy.some(({ alias }) => alias === this.sectionAlias));
if (sections.length) return sections;
@@ -269,7 +270,7 @@ export default {
async loadContentSections() {
if (!this.contentId) return [];
const variables = { contentId: this.contentId };
- const r1 = await this.$apollo.query({ query: contentQuery, variables });
+ const r1 = await this.$graphql.query({ query: contentQuery, variables });
const taxonomyIds = getEdgeNodes(r1, 'data.content.taxonomy').map(t => t.id);
const sectionIds = [];
this.taxonomyIds = taxonomyIds;
@@ -279,7 +280,7 @@ export default {
}
if (!taxonomyIds.length && !sectionIds.length) return [];
const v2 = { taxonomyIds, relatedSectionIds: sectionIds };
- const r2 = await this.$apollo.query({ query: fromContentQuery, variables: v2 });
+ const r2 = await this.$graphql.query({ query: fromContentQuery, variables: v2 });
const sections = getEdgeNodes(r2, 'data.websiteSections');
return sections
.filter(s => s.hierarchy.some(({ alias }) => alias === this.sectionAlias));
@@ -287,7 +288,7 @@ export default {
async loadAllSections() {
const variables = { sectionAlias: this.sectionAlias };
- const { data } = await this.$apollo.query({ query: allQuery, variables });
+ const { data } = await this.$graphql.query({ query: allQuery, variables });
this.loadType = 'all';
return getEdgeNodes(data, 'websiteSectionAlias.children');
},
diff --git a/packages/leaders-program/src/dev.js b/packages/leaders-program/src/dev.js
index 457bb713c..df101efa7 100644
--- a/packages/leaders-program/src/dev.js
+++ b/packages/leaders-program/src/dev.js
@@ -1,12 +1,10 @@
/* eslint-disable no-new */
import Vue from 'vue';
-import VueApollo from 'vue-apollo';
import Leaders from './components/leaders.vue';
-import createProvider from '../apollo/create-provider';
+import createGraphQLClient from './graphql/create-client';
Vue.config.productionTip = false;
-Vue.use(VueApollo);
const components = {
Leaders,
@@ -15,21 +13,22 @@ const components = {
const loadComponent = ({
el,
name,
- apollo = {},
+ graphql = {},
props = {},
on,
} = {}) => {
- const { uri, tenant, siteId } = apollo;
+ const { uri, tenant, siteId } = graphql;
if (!uri || !tenant || !siteId) throw new Error('The provided apollo config is invalid.');
if (!components[name]) throw new Error(`No BaseCMS Management Component found for '${name}'`);
const Component = components[name];
new Vue({
el,
- apolloProvider: createProvider({
- graphqlUri: uri,
- tenantKey: tenant,
- siteId,
- }),
+ provide: {
+ $graphql: createGraphQLClient({
+ uri,
+ headers: { 'x-tenant-key': tenant, 'x-site-id': siteId },
+ }),
+ },
render: h => h(Component, { props, on }),
});
};
diff --git a/packages/leaders-program/src/graphql/create-client.js b/packages/leaders-program/src/graphql/create-client.js
new file mode 100644
index 000000000..dc35bca06
--- /dev/null
+++ b/packages/leaders-program/src/graphql/create-client.js
@@ -0,0 +1,48 @@
+import sha1 from './sha1';
+
+const getOperationName = (string) => {
+ const matches = /query\s+([a-z0-9]+)[(]?.+{/gi.exec(string);
+ if (matches && matches[1]) return matches[1];
+ return undefined;
+};
+
+export default ({ uri, headers: globalHeaders }) => {
+ const cache = new Map();
+ return Object.create({
+ query: async ({ query, variables, headers }) => {
+ const body = JSON.stringify({
+ operationName: getOperationName(query),
+ variables,
+ query,
+ });
+ const hash = await sha1(body);
+ if (hash && cache.has(hash)) return cache.get(hash);
+
+ const res = await fetch(uri, {
+ method: 'POST',
+ headers: {
+ ...globalHeaders,
+ ...headers,
+ 'content-type': 'application/json',
+ },
+ body,
+ });
+ const json = await res.json();
+ if (!res.ok || (json && json.errors)) {
+ if (!json || !json.errors) {
+ const err = new Error(`An unknown, fatal GraphQL error was encountered (${res.status})`);
+ err.statusCode = res.status;
+ throw err;
+ }
+ const [networkError] = json.errors;
+ const err = new Error(networkError.message);
+ const { extensions } = networkError;
+ if (extensions) err.code = extensions.code;
+ if (extensions && extensions.exception) err.statusCode = extensions.exception.statusCode;
+ throw err;
+ }
+ if (hash) cache.set(hash, json);
+ return json;
+ },
+ });
+};
diff --git a/packages/leaders-program/src/graphql/parse.js b/packages/leaders-program/src/graphql/parse.js
new file mode 100644
index 000000000..33a997c13
--- /dev/null
+++ b/packages/leaders-program/src/graphql/parse.js
@@ -0,0 +1 @@
+export default (strings, ...rest) => [...strings, ...rest].join('\n');
diff --git a/packages/leaders-program/src/graphql/queries/all-sections.js b/packages/leaders-program/src/graphql/queries/all-sections.js
index 178e357a1..c58d82cad 100644
--- a/packages/leaders-program/src/graphql/queries/all-sections.js
+++ b/packages/leaders-program/src/graphql/queries/all-sections.js
@@ -1,4 +1,4 @@
-import gql from 'graphql-tag';
+import gql from '../parse';
export default gql`
diff --git a/packages/leaders-program/src/graphql/queries/content-for-section.js b/packages/leaders-program/src/graphql/queries/content-for-section.js
index c3ec0cff5..ba180c9fd 100644
--- a/packages/leaders-program/src/graphql/queries/content-for-section.js
+++ b/packages/leaders-program/src/graphql/queries/content-for-section.js
@@ -1,4 +1,4 @@
-import gql from 'graphql-tag';
+import gql from '../parse';
export default gql`
diff --git a/packages/leaders-program/src/graphql/queries/content.js b/packages/leaders-program/src/graphql/queries/content.js
index 0c0a3b19b..fdf4cfe6c 100644
--- a/packages/leaders-program/src/graphql/queries/content.js
+++ b/packages/leaders-program/src/graphql/queries/content.js
@@ -1,4 +1,4 @@
-import gql from 'graphql-tag';
+import gql from '../parse';
export default gql`
diff --git a/packages/leaders-program/src/graphql/queries/sections-from-content.js b/packages/leaders-program/src/graphql/queries/sections-from-content.js
index 1ed5a3121..f6798d120 100644
--- a/packages/leaders-program/src/graphql/queries/sections-from-content.js
+++ b/packages/leaders-program/src/graphql/queries/sections-from-content.js
@@ -1,4 +1,4 @@
-import gql from 'graphql-tag';
+import gql from '../parse';
export default gql`
diff --git a/packages/leaders-program/src/graphql/queries/sections-from-ids.js b/packages/leaders-program/src/graphql/queries/sections-from-ids.js
index bca40ca07..ed2ca5773 100644
--- a/packages/leaders-program/src/graphql/queries/sections-from-ids.js
+++ b/packages/leaders-program/src/graphql/queries/sections-from-ids.js
@@ -1,4 +1,4 @@
-import gql from 'graphql-tag';
+import gql from '../parse';
export default gql`
diff --git a/packages/leaders-program/src/graphql/sha1.js b/packages/leaders-program/src/graphql/sha1.js
new file mode 100644
index 000000000..f8bff715b
--- /dev/null
+++ b/packages/leaders-program/src/graphql/sha1.js
@@ -0,0 +1,18 @@
+const { error } = console;
+
+export default async (string) => {
+ try {
+ const buffer = new TextEncoder('utf-8').encode(string);
+ const digest = await crypto.subtle.digest('SHA-1', buffer);
+ const hexCodes = [];
+ const view = new DataView(digest);
+ for (let i = 0; i < view.byteLength; i += 1) {
+ const byte = view.getUint8(i).toString(16).padStart(2, '0');
+ hexCodes.push(byte);
+ }
+ return hexCodes.join('');
+ } catch (e) {
+ error('Unable to create SHA1 - GraphQL cache will be disabled.', e);
+ return null;
+ }
+};
diff --git a/packages/leaders-program/src/index.js b/packages/leaders-program/src/index.js
index f6c194687..c0dc4b603 100644
--- a/packages/leaders-program/src/index.js
+++ b/packages/leaders-program/src/index.js
@@ -1,3 +1,5 @@
import Leaders from './components/leaders.vue';
+export { default as createGraphQLClient } from './graphql/create-client';
+
export default Leaders;
diff --git a/packages/marko-web-identity-x/browser/comments/post.vue b/packages/marko-web-identity-x/browser/comments/post.vue
index 2c534cb4d..7b028b429 100644
--- a/packages/marko-web-identity-x/browser/comments/post.vue
+++ b/packages/marko-web-identity-x/browser/comments/post.vue
@@ -33,7 +33,7 @@